Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 8d3a1783fd | |||
| af1f660486 | |||
| b1c8a7446e | |||
| 7e991396e9 | |||
| 25cbf9bfdd | |||
| 4d8ba1fefc |
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"json.schemas": [
|
||||
{
|
||||
"fileMatch": ["/npmextra.json"],
|
||||
"fileMatch": ["/.smartconfig.json"],
|
||||
"schema": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
16
changelog.md
16
changelog.md
@@ -1,5 +1,21 @@
|
||||
# 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)
|
||||
add last updated footer to status object and refresh demo data
|
||||
|
||||
- Render a bottom bar that shows the status object's lastUpdated timestamp when available.
|
||||
- Adjust detail row padding to keep spacing consistent with the new footer layout.
|
||||
- Update demo status objects to include lastUpdated examples for current, hourly, and daily timestamps.
|
||||
- Bump @tsclass/tsclass from ^9.3.0 to ^9.5.0.
|
||||
|
||||
## 2026-03-14 - 3.48.5 - fix(repo)
|
||||
no changes to commit
|
||||
|
||||
|
||||
9
license
9
license
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2020 Lossless GmbH (hello@lossless.com)
|
||||
Copyright (c) 2020 Task Venture Capital GmbH (hello@task.vc)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
@@ -8,10 +8,7 @@ copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software. You agree to being mentioned
|
||||
as reference by Lossless GmbH. This includes the use of your entity logos
|
||||
or profile picture by Lossless GmbH on websites and readme's, also on third party
|
||||
pages like gitlab.com or github.com.
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
@@ -19,4 +16,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
SOFTWARE.
|
||||
|
||||
24
package.json
24
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@design.estate/dees-catalog",
|
||||
"version": "3.48.5",
|
||||
"version": "3.49.1",
|
||||
"private": false,
|
||||
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
|
||||
"main": "dist_ts_web/index.js",
|
||||
@@ -16,8 +16,8 @@
|
||||
"author": "Lossless GmbH",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"@design.estate/dees-domtools": "^2.5.1",
|
||||
"@design.estate/dees-element": "^2.2.2",
|
||||
"@design.estate/dees-domtools": "^2.5.4",
|
||||
"@design.estate/dees-element": "^2.2.4",
|
||||
"@design.estate/dees-wcctools": "^3.8.0",
|
||||
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||
"@fortawesome/free-brands-svg-icons": "^7.2.0",
|
||||
@@ -33,8 +33,8 @@
|
||||
"@tiptap/extension-typography": "^2.23.0",
|
||||
"@tiptap/extension-underline": "^2.23.0",
|
||||
"@tiptap/starter-kit": "^2.23.0",
|
||||
"@tsclass/tsclass": "^9.3.0",
|
||||
"apexcharts": "^5.10.3",
|
||||
"@tsclass/tsclass": "^9.5.0",
|
||||
"apexcharts": "^5.10.4",
|
||||
"highlight.js": "11.11.1",
|
||||
"ibantools": "^4.5.1",
|
||||
"lucide": "^0.577.0",
|
||||
@@ -44,12 +44,12 @@
|
||||
"xterm-addon-fit": "^0.8.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@git.zone/tsbuild": "^4.3.0",
|
||||
"@git.zone/tsbundle": "^2.9.1",
|
||||
"@git.zone/tstest": "^3.3.2",
|
||||
"@git.zone/tswatch": "^3.3.0",
|
||||
"@push.rocks/projectinfo": "^5.0.2",
|
||||
"@types/node": "^25.4.0"
|
||||
"@git.zone/tsbuild": "^4.4.0",
|
||||
"@git.zone/tsbundle": "^2.10.0",
|
||||
"@git.zone/tstest": "^3.6.3",
|
||||
"@git.zone/tswatch": "^3.3.2",
|
||||
"@push.rocks/projectinfo": "^5.1.0",
|
||||
"@types/node": "^25.5.0"
|
||||
},
|
||||
"files": [
|
||||
"ts/**/*",
|
||||
@@ -60,7 +60,7 @@
|
||||
"dist_ts_web/**/*",
|
||||
"assets/**/*",
|
||||
"cli.js",
|
||||
"npmextra.json",
|
||||
".smartconfig.json",
|
||||
"readme.md"
|
||||
],
|
||||
"browserslist": [
|
||||
|
||||
1324
pnpm-lock.yaml
generated
1324
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
10
readme.md
10
readme.md
@@ -58,13 +58,13 @@ For developers working on this library, please refer to the [UI Components Playb
|
||||
| **Core UI** | [`DeesButton`](#deesbutton), [`DeesButtonExit`](#deesbuttonexit), [`DeesButtonGroup`](#deesbuttongroup), [`DeesBadge`](#deesbadge), [`DeesChips`](#deeschips), [`DeesHeading`](#deesheading), [`DeesHint`](#deeshint), [`DeesIcon`](#deesicon), [`DeesLabel`](#deeslabel), [`DeesPanel`](#deespanel), [`DeesSearchbar`](#deessearchbar), [`DeesSpinner`](#deesspinner), [`DeesToast`](#deestoast), [`DeesWindowcontrols`](#deeswindowcontrols), [`DeesActionbar`](#deesactionbar) |
|
||||
| **Forms** | [`DeesForm`](#deesform), [`DeesInputText`](#deesinputtext), [`DeesInputCheckbox`](#deesinputcheckbox), [`DeesInputDropdown`](#deesinputdropdown), [`DeesInputRadiogroup`](#deesinputradiogroup), [`DeesInputFileupload`](#deesinputfileupload), [`DeesInputIban`](#deesinputiban), [`DeesInputPhone`](#deesinputphone), [`DeesInputQuantitySelector`](#deesinputquantityselector), [`DeesInputMultitoggle`](#deesinputmultitoggle), [`DeesInputToggle`](#deesinputtoggle), [`DeesInputTags`](#deesinputtags), [`DeesInputTypelist`](#deesinputtypelist), [`DeesInputList`](#deesinputlist), [`DeesInputProfilepicture`](#deesinputprofilepicture), [`DeesInputRichtext`](#deesinputrichtext), [`DeesInputWysiwyg`](#deesinputwysiwyg), [`DeesInputDatepicker`](#deesinputdatepicker), [`DeesInputSearchselect`](#deesinputsearchselect), [`DeesInputCode`](#deesinputcode), [`DeesFormSubmit`](#deesformsubmit) |
|
||||
| **App Shell (Layout)** | [`DeesAppui`](#deesappui-️), [`DeesAppuiMainmenu`](#deesappuimainmenu), [`DeesAppuiSecondarymenu`](#deesappuisecondarymenu), [`DeesAppuiMaincontent`](#deesappuimaincontent), [`DeesAppuiAppbar`](#deesappuiappbar), [`DeesAppuiActivitylog`](#deesappuiactivitylog), [`DeesAppuiBottombar`](#deesappuibottombar), [`DeesAppuiProfiledropdown`](#deesappuiprofiledropdown), [`DeesAppuiTabs`](#deesappuitabs), [`DeesMobileNavigation`](#deesmobilenavigation), [`DeesDashboardGrid`](#deesdashboardgrid) |
|
||||
| **Data Display** | [`DeesTable`](#deestable), [`DeesDataviewCodebox`](#deesdataviewcodebox), [`DeesDataviewStatusobject`](#deesdataviewstatusobject), [`DeesPdf`](#deespdf), [`DeesStatsGrid`](#deesstatsgrid), [`DeesPagination`](#deespagination) |
|
||||
| **Data Display** | [`DeesTable`](#deestable), [`DeesDataviewCodebox`](#deesdataviewcodebox), [`DeesDataviewStatusobject`](#deesdataviewstatusobject), [`DeesPdf`](#deespdf), [`DeesStatsGrid`](#deesstatsgrid), [`DeesPagination`](#deespagination), [`DeesStorageBrowser`](#deesstorgebrowser) |
|
||||
| **Media & Tiles** | [`DeesTilePdf`](#deestilepdf), [`DeesTileImage`](#deestileimage), [`DeesTileAudio`](#deestileaudio), [`DeesTileVideo`](#deestilevideo), [`DeesTileNote`](#deestilenote), [`DeesTileFolder`](#deestilefolder), [`DeesPreview`](#deespreview), [`DeesPdfViewer`](#deespdfviewer), [`DeesPdfPreview`](#deespdfpreview), [`DeesImageViewer`](#deesimageviewer), [`DeesAudioViewer`](#deesaudioviewer), [`DeesVideoViewer`](#deesvideoviewer) |
|
||||
| **Visualization** | [`DeesChartArea`](#deeschartarea), [`DeesChartLog`](#deeschartlog) |
|
||||
| **Dialogs & Overlays** | [`DeesModal`](#deesmodal), [`DeesContextmenu`](#deescontextmenu), [`DeesSpeechbubble`](#deesspeechbubble), [`DeesWindowlayer`](#deeswindowlayer) |
|
||||
| **Navigation** | [`DeesStepper`](#deesstepper), [`DeesProgressbar`](#deesprogressbar) |
|
||||
| **Workspace / IDE** | [`DeesWorkspace`](#deesworkspace), [`DeesWorkspaceMonaco`](#deesworkspacemonaco), [`DeesWorkspaceDiffEditor`](#deesworkspacediffeditor), [`DeesWorkspaceFiletree`](#deesworkspacefiletree), [`DeesWorkspaceTerminal`](#deesworkspaceterminal), [`DeesWorkspaceTerminalPreview`](#deesworkspaceterminalpreview), [`DeesWorkspaceMarkdown`](#deesworkspacemarkdown), [`DeesWorkspaceMarkdownoutlet`](#deesworkspacemarkdownoutlet), [`DeesWorkspaceBottombar`](#deesworkspacebottombar) |
|
||||
| **Theming** | [`DeesTheme`](#deestheme) |
|
||||
| **Theming** | [`DeesTheme`](#deestheme), [`DeesUpdater`](#deesupdater) |
|
||||
| **Pre-built Templates** | [`DeesSimpleAppdash`](#deessimpleappdash), [`DeesSimpleLogin`](#deessimplelogin) |
|
||||
| **Shopping** | [`DeesShoppingProductcard`](#deesshoppingproductcard) |
|
||||
|
||||
@@ -1780,7 +1780,7 @@ interface ITileFolderItem {
|
||||
|
||||
## License and Legal Information
|
||||
|
||||
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./LICENSE) file.
|
||||
This repository contains open-source code licensed under the MIT License. A copy of the license can be found in the [LICENSE](./license) file.
|
||||
|
||||
**Please note:** The MIT License does not grant permission to use the trade names, trademarks, service marks, or product names of the project, except as required for reasonable and customary use in describing the origin of the work and reproducing the content of the NOTICE file.
|
||||
|
||||
@@ -1792,9 +1792,11 @@ Use of these trademarks must comply with Task Venture Capital GmbH's Trademark G
|
||||
|
||||
### Company Information
|
||||
|
||||
Task Venture Capital GmbH
|
||||
Task Venture Capital GmbH
|
||||
Registered at District Court Bremen HRB 35230 HB, Germany
|
||||
|
||||
For any legal inquiries or further information, please contact us via email at hello@task.vc.
|
||||
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||
|
||||
By using this repository, you acknowledge that you have read this section, agree to comply with its terms, and understand that the licensing of the code does not imply endorsement by Task Venture Capital GmbH of any derivative works.
|
||||
|
||||
@@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@design.estate/dees-catalog',
|
||||
version: '3.48.5',
|
||||
version: '3.49.1',
|
||||
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
||||
}
|
||||
|
||||
@@ -122,7 +122,7 @@ export class DeesAppuiBar extends DeesElement {
|
||||
>
|
||||
${menuItem.iconName ? html`<dees-icon .icon="${`lucide:${menuItem.iconName}`}"></dees-icon>` : ''}
|
||||
${menuItem.name}
|
||||
${hasSubmenu ? this.renderDropdown(menuItem.submenu, itemId, isActive) : ''}
|
||||
${hasSubmenu ? this.renderDropdown(menuItem.submenu!, itemId, isActive) : ''}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
@@ -75,21 +75,21 @@ export const demoFunc = () => {
|
||||
// Set up status toggle
|
||||
const statusButtons = elementArg.querySelectorAll('.status-toggle dees-button');
|
||||
statusButtons[0].addEventListener('click', () => {
|
||||
appbar.user = { ...appbar.user, status: 'online' };
|
||||
appbar.user = { ...appbar.user!, status: 'online' };
|
||||
});
|
||||
statusButtons[1].addEventListener('click', () => {
|
||||
appbar.user = { ...appbar.user, status: 'busy' };
|
||||
appbar.user = { ...appbar.user!, status: 'busy' };
|
||||
});
|
||||
statusButtons[2].addEventListener('click', () => {
|
||||
appbar.user = { ...appbar.user, status: 'away' };
|
||||
appbar.user = { ...appbar.user!, status: 'away' };
|
||||
});
|
||||
statusButtons[3].addEventListener('click', () => {
|
||||
appbar.user = { ...appbar.user, status: 'offline' };
|
||||
appbar.user = { ...appbar.user!, status: 'offline' };
|
||||
});
|
||||
|
||||
// Set up window controls toggle
|
||||
const windowControlsButton = elementArg.querySelector('.window-controls-toggle dees-button');
|
||||
windowControlsButton.addEventListener('click', () => {
|
||||
windowControlsButton!.addEventListener('click', () => {
|
||||
appbar.showWindowControls = !appbar.showWindowControls;
|
||||
});
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ export class DeesAppuiMaincontent extends DeesElement {
|
||||
}
|
||||
// Tab selection is now handled by the dees-appui-tabs component
|
||||
// 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) {
|
||||
await tabsComponent.updateComplete;
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export class DeesAppuiMainmenu extends DeesElement {
|
||||
accessor tabs: interfaces.IMenuItem[] = [];
|
||||
|
||||
@property()
|
||||
accessor selectedTab: interfaces.IMenuItem;
|
||||
accessor selectedTab!: interfaces.IMenuItem;
|
||||
|
||||
@property({ type: Boolean, reflect: true })
|
||||
accessor collapsed: boolean = false;
|
||||
|
||||
@@ -663,21 +663,21 @@ export class DeesAppuiTabs extends DeesElement {
|
||||
}
|
||||
|
||||
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 {
|
||||
const selectedIndex = this.tabs.indexOf(this.selectedTab);
|
||||
const selectedIndex = this.tabs.indexOf(this.selectedTab!);
|
||||
const isHorizontal = this.tabStyle === 'horizontal';
|
||||
const selector = isHorizontal
|
||||
const selector = isHorizontal
|
||||
? `.tabs-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 {
|
||||
return this.shadowRoot.querySelector('.tabIndicator');
|
||||
return this.shadowRoot!.querySelector('.tabIndicator');
|
||||
}
|
||||
|
||||
private handleInitialTransition(indicator: HTMLElement): void {
|
||||
@@ -695,7 +695,7 @@ export class DeesAppuiTabs extends DeesElement {
|
||||
const tabContent = tabElement.querySelector('.tab-content') as HTMLElement;
|
||||
if (!tabContent) return;
|
||||
|
||||
const wrapperRect = indicator.parentElement.getBoundingClientRect();
|
||||
const wrapperRect = indicator.parentElement!.getBoundingClientRect();
|
||||
const contentRect = tabContent.getBoundingClientRect();
|
||||
|
||||
const contentLeft = contentRect.left - wrapperRect.left;
|
||||
@@ -707,7 +707,7 @@ export class DeesAppuiTabs extends DeesElement {
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
indicator.style.top = `${tabElement.offsetTop + tabsContainer.offsetTop}px`;
|
||||
|
||||
@@ -12,7 +12,7 @@ class DemoDashboardView extends DeesElement {
|
||||
@state()
|
||||
accessor activated: boolean = false;
|
||||
|
||||
private ctx: IViewActivationContext;
|
||||
private ctx!: IViewActivationContext;
|
||||
|
||||
private statsTiles: IStatsTile[] = [
|
||||
{
|
||||
@@ -267,7 +267,7 @@ class DemoSettingsView extends DeesElement {
|
||||
@state()
|
||||
accessor hasChanges: boolean = false;
|
||||
|
||||
private appui: DeesAppui;
|
||||
private appui!: DeesAppui;
|
||||
|
||||
onActivate(context: IViewActivationContext) {
|
||||
this.appui = context.appui as any;
|
||||
|
||||
@@ -1037,7 +1037,7 @@ export class DeesAppui extends DeesElement {
|
||||
if (!config.mainMenu?.sections) return [];
|
||||
|
||||
return config.mainMenu.sections.map((section) => ({
|
||||
name: section.name,
|
||||
name: section.name || '',
|
||||
items: section.views
|
||||
.map((viewId) => {
|
||||
const view = this.viewRegistry.get(viewId);
|
||||
|
||||
@@ -173,7 +173,7 @@ export class ViewRegistry {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
// Reuse cached instance - just show it
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
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 '@design.estate/dees-wcctools/demotools';
|
||||
|
||||
|
||||
@@ -301,15 +301,15 @@ export class DeesMobilenavigation extends DeesElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private windowLayer: DeesWindowLayer;
|
||||
private windowLayer!: DeesWindowLayer;
|
||||
|
||||
/**
|
||||
* inits the show
|
||||
*/
|
||||
public async show() {
|
||||
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)
|
||||
if (!this.windowLayer) {
|
||||
this.windowLayer = await DeesWindowLayer.createAndShow({
|
||||
@@ -328,7 +328,7 @@ export class DeesMobilenavigation extends DeesElement {
|
||||
zIndexRegistry.register(this, this.mobileNavZIndex);
|
||||
|
||||
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() {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
const main = this.shadowRoot.querySelector('.main');
|
||||
main.classList.remove('show');
|
||||
const main = this.shadowRoot!.querySelector('.main');
|
||||
main!.classList.remove('show');
|
||||
|
||||
// Unregister from z-index registry
|
||||
zIndexRegistry.unregister(this);
|
||||
|
||||
@@ -288,8 +288,8 @@ export const demoFunc = () => html`
|
||||
}
|
||||
|
||||
if (dataBtn && output) {
|
||||
dataBtn.addEventListener('clicked', (e: CustomEvent) => {
|
||||
output.textContent = `Clicked: Secondary button with data: ${e.detail.data}`;
|
||||
dataBtn.addEventListener('clicked', (e: Event) => {
|
||||
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');
|
||||
|
||||
if (form && output) {
|
||||
form.addEventListener('formData', (e: CustomEvent) => {
|
||||
output.innerHTML = '<strong>Form submitted with data:</strong><br>' +
|
||||
JSON.stringify(e.detail.data, null, 2);
|
||||
form.addEventListener('formData', (e: Event) => {
|
||||
output.innerHTML = '<strong>Form submitted with data:</strong><br>' +
|
||||
JSON.stringify((e as CustomEvent).detail.data, null, 2);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -31,10 +31,10 @@ export class DeesButton extends DeesElement {
|
||||
return true;
|
||||
}
|
||||
})
|
||||
accessor text: string;
|
||||
accessor text!: string;
|
||||
|
||||
@property()
|
||||
accessor eventDetailData: string;
|
||||
accessor eventDetailData!: string;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
@@ -69,7 +69,7 @@ export class DeesButton extends DeesElement {
|
||||
accessor insideForm: boolean = false;
|
||||
|
||||
@property({ type: String, reflect: true })
|
||||
accessor icon: string;
|
||||
accessor icon!: string;
|
||||
|
||||
@property({ type: String, reflect: true })
|
||||
accessor iconPosition: 'left' | 'right' = 'left';
|
||||
|
||||
@@ -37,7 +37,7 @@ export class DeesChartArea extends DeesElement {
|
||||
|
||||
// instance
|
||||
@state()
|
||||
accessor chart: ApexCharts;
|
||||
accessor chart!: ApexCharts;
|
||||
|
||||
@property()
|
||||
accessor label: string = 'Untitled Chart';
|
||||
@@ -68,8 +68,8 @@ export class DeesChartArea extends DeesElement {
|
||||
@property({ type: Number })
|
||||
accessor autoScrollInterval: number = 1000; // Auto-scroll interval in milliseconds (0 to disable)
|
||||
|
||||
private resizeObserver: ResizeObserver;
|
||||
private resizeTimeout: number;
|
||||
private resizeObserver!: ResizeObserver;
|
||||
private resizeTimeout!: number;
|
||||
private internalChartData: ApexAxisChartSeries = [];
|
||||
private autoScrollTimer: number | null = null;
|
||||
private readonly DEBUG_RESIZE = false; // Set to true to enable resize debugging
|
||||
@@ -132,7 +132,7 @@ export class DeesChartArea extends DeesElement {
|
||||
if (this.chart) {
|
||||
try {
|
||||
this.chart.destroy();
|
||||
this.chart = null;
|
||||
this.chart = null as any;
|
||||
} catch (error) {
|
||||
console.error('Error destroying chart:', error);
|
||||
}
|
||||
@@ -170,14 +170,14 @@ export class DeesChartArea extends DeesElement {
|
||||
await new Promise(resolve => requestAnimationFrame(resolve));
|
||||
|
||||
// Get actual dimensions of the container
|
||||
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
||||
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
||||
|
||||
const mainbox: HTMLDivElement | null = this.shadowRoot!.querySelector('.mainbox');
|
||||
const chartContainer: HTMLDivElement | null = this.shadowRoot!.querySelector('.chartContainer');
|
||||
|
||||
if (!mainbox || !chartContainer) {
|
||||
console.error('Chart containers not found');
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// Calculate initial dimensions
|
||||
const styleChartContainer = window.getComputedStyle(chartContainer);
|
||||
const paddingTop = parseInt(styleChartContainer.paddingTop, 10);
|
||||
@@ -368,7 +368,7 @@ export class DeesChartArea extends DeesElement {
|
||||
};
|
||||
|
||||
try {
|
||||
this.chart = new ApexChartsLib(this.shadowRoot.querySelector('.chartContainer'), options);
|
||||
this.chart = new ApexChartsLib(this.shadowRoot!.querySelector('.chartContainer')!, options);
|
||||
await this.chart.render();
|
||||
|
||||
// Give the chart a moment to fully initialize before resizing
|
||||
@@ -376,7 +376,7 @@ export class DeesChartArea extends DeesElement {
|
||||
await this.resizeChart();
|
||||
|
||||
// Ensure resize observer is watching the mainbox
|
||||
const mainbox = this.shadowRoot.querySelector('.mainbox');
|
||||
const mainbox = this.shadowRoot!.querySelector('.mainbox');
|
||||
if (mainbox && this.resizeObserver) {
|
||||
// Disconnect any previous observations
|
||||
this.resizeObserver.disconnect();
|
||||
@@ -572,9 +572,9 @@ export class DeesChartArea extends DeesElement {
|
||||
}
|
||||
|
||||
try {
|
||||
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
||||
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
||||
|
||||
const mainbox: HTMLDivElement | null = this.shadowRoot!.querySelector('.mainbox');
|
||||
const chartContainer: HTMLDivElement | null = this.shadowRoot!.querySelector('.chartContainer');
|
||||
|
||||
if (!mainbox || !chartContainer) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,8 +44,8 @@ export const demoFunc = () => {
|
||||
// Get the chart elements
|
||||
const chartElement = elementArg.querySelector('#main-chart') as DeesChartArea;
|
||||
const connectionsChartElement = elementArg.querySelector('#connections-chart') as DeesChartArea;
|
||||
let intervalId: number;
|
||||
let connectionsIntervalId: number;
|
||||
let intervalId: number | null;
|
||||
let connectionsIntervalId: number | null;
|
||||
let currentDataset = 'system';
|
||||
|
||||
// Y-axis formatters for different datasets
|
||||
@@ -71,7 +71,7 @@ export const demoFunc = () => {
|
||||
|
||||
// Generate initial data points for time window
|
||||
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 pointCount = Math.floor(TIME_WINDOW / interval);
|
||||
|
||||
@@ -240,10 +240,10 @@ export const demoFunc = () => {
|
||||
// Switch dataset
|
||||
const switchDataset = (name: string) => {
|
||||
currentDataset = name;
|
||||
const dataset = datasets[name];
|
||||
const dataset = (datasets as Record<string, any>)[name];
|
||||
chartElement.label = dataset.label;
|
||||
chartElement.series = dataset.series;
|
||||
chartElement.yAxisFormatter = formatters[name];
|
||||
chartElement.yAxisFormatter = (formatters as Record<string, any>)[name];
|
||||
|
||||
// Set appropriate y-axis scaling
|
||||
if (name === 'system') {
|
||||
|
||||
@@ -8,8 +8,8 @@ export const demoFunc = () => {
|
||||
// Get the log elements
|
||||
const structuredLog = elementArg.querySelector('#structured-log') as DeesChartLog;
|
||||
const rawLog = elementArg.querySelector('#raw-log') as DeesChartLog;
|
||||
let structuredIntervalId: number;
|
||||
let rawIntervalId: number;
|
||||
let structuredIntervalId: number | null;
|
||||
let rawIntervalId: number | null;
|
||||
|
||||
const serverSources = ['Server', 'Database', 'API', 'Auth', 'Cache', 'Queue', 'WebSocket', 'Scheduler'];
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ export class DeesDataviewCodebox extends DeesElement {
|
||||
</style>
|
||||
<div
|
||||
class="mainbox"
|
||||
@contextmenu="${(eventArg) => {
|
||||
@contextmenu="${(eventArg: MouseEvent) => {
|
||||
DeesContextmenu.openContextMenuWithOptions(eventArg, [
|
||||
{
|
||||
name: 'About',
|
||||
@@ -241,7 +241,7 @@ export class DeesDataviewCodebox extends DeesElement {
|
||||
private codeToDisplayStore = '';
|
||||
private highlightJs: HLJSApi | null = null;
|
||||
|
||||
public async updated(_changedProperties) {
|
||||
public async updated(_changedProperties: Map<string, any>) {
|
||||
super.updated(_changedProperties);
|
||||
console.log('highlighting now');
|
||||
console.log(this.childNodes);
|
||||
@@ -267,11 +267,11 @@ export class DeesDataviewCodebox extends DeesElement {
|
||||
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, {
|
||||
language: this.progLang,
|
||||
ignoreIllegals: true,
|
||||
});
|
||||
localCodeNode.innerHTML = highlightedHtml.value;
|
||||
localCodeNode!.innerHTML = highlightedHtml.value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -50,6 +50,7 @@ export const demoFunc = () => html` <style>
|
||||
.statusObject=${{
|
||||
id: '1',
|
||||
name: 'API Gateway Service',
|
||||
lastUpdated: Date.now(),
|
||||
combinedStatus: 'ok',
|
||||
combinedStatusText: 'All systems operational',
|
||||
details: [
|
||||
@@ -89,6 +90,7 @@ export const demoFunc = () => html` <style>
|
||||
.statusObject=${{
|
||||
id: '2',
|
||||
name: 'PostgreSQL Cluster',
|
||||
lastUpdated: Date.now() - 3600000,
|
||||
combinedStatus: 'partly_ok',
|
||||
combinedStatusText: 'Minor issues detected',
|
||||
details: [
|
||||
@@ -128,6 +130,7 @@ export const demoFunc = () => html` <style>
|
||||
.statusObject=${{
|
||||
id: '3',
|
||||
name: 'CI/CD Pipeline',
|
||||
lastUpdated: Date.now() - 86400000,
|
||||
combinedStatus: 'not_ok',
|
||||
combinedStatusText: 'Build failure',
|
||||
details: [
|
||||
|
||||
@@ -29,7 +29,7 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
public static demo = demoFunc;
|
||||
public static demoGroups = ['Data View'];
|
||||
|
||||
@property({ type: Object }) accessor statusObject: tsclass.code.IStatusObject;
|
||||
@property({ type: Object }) accessor statusObject!: tsclass.code.IStatusObject;
|
||||
|
||||
public static styles = [
|
||||
themeDefaultStyles,
|
||||
@@ -128,7 +128,7 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
grid-template-columns: 48px auto;
|
||||
border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 94%)', 'hsl(0 0% 14.9%)')};
|
||||
transition: background-color 0.15s ease;
|
||||
padding-right: 16px;
|
||||
padding: 0 16px;
|
||||
cursor: context-menu;
|
||||
}
|
||||
|
||||
@@ -148,7 +148,7 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
.detail .detailsText .label {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')}
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
|
||||
margin-bottom: 2px;
|
||||
letter-spacing: -0.01em;
|
||||
}
|
||||
@@ -159,6 +159,28 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 15%)', 'hsl(0 0% 90%)')};
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.bottomBar {
|
||||
position: relative;
|
||||
color: ${cssManager.bdTheme('hsl(0 0% 45.1%)', 'hsl(0 0% 63.9%)')};
|
||||
background: ${cssManager.bdTheme('hsl(0 0% 97%)', 'hsl(0 0% 7%)')};
|
||||
border-top: 1px solid ${cssManager.bdTheme('hsl(0 0% 89.8%)', 'hsl(0 0% 14.9%)')};
|
||||
height: 28px;
|
||||
font-size: 12px;
|
||||
line-height: 28px;
|
||||
display: flex;
|
||||
justify-content: flex-end;
|
||||
align-items: stretch;
|
||||
overflow: hidden;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.bottomBar .statusLabel {
|
||||
padding: 0 16px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: 500;
|
||||
}
|
||||
`,
|
||||
];
|
||||
|
||||
@@ -209,6 +231,11 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
</div>
|
||||
`;
|
||||
})}
|
||||
<div class="bottomBar">
|
||||
<div class="statusLabel">${this.statusObject?.lastUpdated
|
||||
? `Last updated: ${new Date(this.statusObject.lastUpdated).toLocaleString()}`
|
||||
: ''}</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -232,7 +259,7 @@ export class DeesDataviewStatusobject extends DeesElement {
|
||||
await navigator.clipboard.writeText(JSON.stringify(this.statusObject, null, 2));
|
||||
|
||||
// Show feedback
|
||||
const button = this.shadowRoot.querySelector('.copyMain') as HTMLElement;
|
||||
const button = this.shadowRoot!.querySelector('.copyMain') as HTMLElement;
|
||||
const originalText = button.textContent;
|
||||
button.textContent = 'Copied!';
|
||||
|
||||
|
||||
@@ -878,7 +878,7 @@ export class DeesStatsGrid extends DeesElement {
|
||||
|
||||
private renderTile(tile: IStatsTile): TemplateResult {
|
||||
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;
|
||||
|
||||
return html`
|
||||
|
||||
@@ -52,12 +52,12 @@ export class DeesTable<T> extends DeesElement {
|
||||
@property({
|
||||
type: String,
|
||||
})
|
||||
accessor key: string;
|
||||
accessor key!: string;
|
||||
|
||||
@property({
|
||||
type: String,
|
||||
})
|
||||
accessor label: string;
|
||||
accessor label!: string;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
@@ -83,7 +83,7 @@ export class DeesTable<T> extends DeesElement {
|
||||
type: String,
|
||||
reflect: true,
|
||||
})
|
||||
accessor dataName: string;
|
||||
accessor dataName!: string;
|
||||
|
||||
|
||||
@property({
|
||||
@@ -127,7 +127,7 @@ export class DeesTable<T> extends DeesElement {
|
||||
@property({
|
||||
type: Object,
|
||||
})
|
||||
accessor selectedDataRow: T;
|
||||
accessor selectedDataRow!: T;
|
||||
|
||||
@property({
|
||||
type: Array,
|
||||
@@ -359,7 +359,7 @@ export class DeesTable<T> extends DeesElement {
|
||||
if (elementArg.tagName === 'TR') {
|
||||
return elementArg;
|
||||
} else {
|
||||
return getTr(elementArg.parentElement);
|
||||
return getTr(elementArg.parentElement!);
|
||||
}
|
||||
};
|
||||
return html`
|
||||
@@ -393,8 +393,8 @@ export class DeesTable<T> extends DeesElement {
|
||||
}}
|
||||
@drop=${async (eventArg: DragEvent) => {
|
||||
eventArg.preventDefault();
|
||||
const newFiles = [];
|
||||
for (const file of Array.from(eventArg.dataTransfer.files)) {
|
||||
const newFiles: File[] = [];
|
||||
for (const file of Array.from(eventArg.dataTransfer!.files)) {
|
||||
this.files.push(file);
|
||||
newFiles.push(file);
|
||||
this.requestUpdate();
|
||||
@@ -548,8 +548,8 @@ export class DeesTable<T> extends DeesElement {
|
||||
type: ['header'],
|
||||
actionFunc: async () => {
|
||||
console.log('open search');
|
||||
const searchGrid = this.shadowRoot.querySelector('.searchGrid');
|
||||
searchGrid.classList.toggle('hidden');
|
||||
const searchGrid = this.shadowRoot!.querySelector('.searchGrid');
|
||||
searchGrid!.classList.toggle('hidden');
|
||||
}
|
||||
});
|
||||
console.log(this.dataActions);
|
||||
@@ -609,7 +609,7 @@ export class DeesTable<T> extends DeesElement {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
await domtools.convenience.smartdelay.delayFor(0);
|
||||
// Get the table element
|
||||
const table = this.shadowRoot.querySelector('table');
|
||||
const table = this.shadowRoot!.querySelector('table');
|
||||
if (!table) return;
|
||||
|
||||
// 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)) {
|
||||
this._rowIdMap.set(key, String(++this._rowIdCounter));
|
||||
}
|
||||
return this._rowIdMap.get(key);
|
||||
return this._rowIdMap.get(key)!;
|
||||
}
|
||||
|
||||
private isRowSelected(row: T): boolean {
|
||||
@@ -818,7 +818,7 @@ export class DeesTable<T> extends DeesElement {
|
||||
input.blur();
|
||||
}
|
||||
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);
|
||||
}
|
||||
input.remove();
|
||||
|
||||
@@ -89,7 +89,7 @@ export class DeesProgressbar extends DeesElement {
|
||||
}
|
||||
|
||||
public async updatePercentage() {
|
||||
const progressBarFill = this.shadowRoot.querySelector('.progressBarFill') as HTMLElement;
|
||||
const progressBarFill = this.shadowRoot!.querySelector('.progressBarFill') as HTMLElement;
|
||||
progressBarFill.style.width = `${this.percentage}%`;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ export class DeesFormSubmit extends DeesElement {
|
||||
accessor disabled = false;
|
||||
|
||||
@property({ type: String })
|
||||
accessor text: string;
|
||||
accessor text!: string;
|
||||
|
||||
@property({ type: String })
|
||||
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';
|
||||
|
||||
@property({ type: String })
|
||||
accessor icon: string;
|
||||
accessor icon!: string;
|
||||
|
||||
@property({ type: String })
|
||||
accessor iconPosition: 'left' | 'right' = 'left';
|
||||
|
||||
@@ -57,10 +57,10 @@ export const demoFunc = () => html`
|
||||
const outputDiv = elementArg.querySelector('.form-output');
|
||||
|
||||
if (form && outputDiv) {
|
||||
form.addEventListener('formData', async (eventArg: CustomEvent) => {
|
||||
form.addEventListener('formData', (async (eventArg: CustomEvent) => {
|
||||
const data = eventArg.detail.data;
|
||||
console.log('Form submitted with data:', data);
|
||||
|
||||
|
||||
// Show processing state
|
||||
form.setStatus('pending', 'Processing your registration...');
|
||||
outputDiv.innerHTML = `<strong>Submitted Data:</strong>\n${JSON.stringify(data, null, 2)}`;
|
||||
@@ -75,7 +75,7 @@ export const demoFunc = () => html`
|
||||
await domtools.plugins.smartdelay.delayFor(2000);
|
||||
form.reset();
|
||||
outputDiv.innerHTML = '<em>Form has been reset</em>';
|
||||
});
|
||||
}) as unknown as EventListener);
|
||||
|
||||
// Track individual field changes
|
||||
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');
|
||||
|
||||
// Monitor filter changes
|
||||
form.addEventListener('formData', (event: CustomEvent) => {
|
||||
form.addEventListener('formData', ((event: CustomEvent) => {
|
||||
const filters = event.detail.data;
|
||||
console.log('Filter applied:', filters);
|
||||
|
||||
|
||||
// Simulate search
|
||||
const resultsCount = Math.floor(Math.random() * 100) + 1;
|
||||
console.log(`Found ${resultsCount} results with filters:`, filters);
|
||||
});
|
||||
}) as unknown as EventListener);
|
||||
|
||||
// Setup real-time filter updates
|
||||
const inputs = form.querySelectorAll('[key]');
|
||||
@@ -224,7 +224,7 @@ export const demoFunc = () => html`
|
||||
const statusDiv = elementArg.querySelector('#status-display');
|
||||
|
||||
if (form) {
|
||||
form.addEventListener('formData', async (eventArg: CustomEvent) => {
|
||||
form.addEventListener('formData', (async (eventArg: CustomEvent) => {
|
||||
const data = eventArg.detail.data;
|
||||
console.log('Advanced form data:', data);
|
||||
|
||||
@@ -252,7 +252,7 @@ export const demoFunc = () => html`
|
||||
}
|
||||
|
||||
console.log('Form data logged:', data);
|
||||
});
|
||||
}) as unknown as EventListener);
|
||||
|
||||
// Monitor file uploads
|
||||
const fileUpload = form.querySelector('dees-input-fileupload');
|
||||
|
||||
@@ -135,13 +135,14 @@ export class DeesForm extends DeesElement {
|
||||
}
|
||||
|
||||
public getFormElements(): Array<TFormInputElement> {
|
||||
return Array.from(this.children).filter((child) =>
|
||||
// Use querySelectorAll('*') to find form inputs nested inside wrapper elements (e.g. <div>)
|
||||
return Array.from(this.querySelectorAll('*')).filter((child) =>
|
||||
FORM_INPUT_TYPES.includes(child.constructor as any)
|
||||
) as unknown as TFormInputElement[];
|
||||
}
|
||||
|
||||
public getSubmitButton(): DeesFormSubmit | undefined {
|
||||
return Array.from(this.children).find(
|
||||
return Array.from(this.querySelectorAll('*')).find(
|
||||
(child) => child instanceof DeesFormSubmit
|
||||
) as DeesFormSubmit;
|
||||
}
|
||||
@@ -155,8 +156,9 @@ export class DeesForm extends DeesElement {
|
||||
requiredOK = false;
|
||||
}
|
||||
}
|
||||
if (this.getSubmitButton()) {
|
||||
this.getSubmitButton().disabled = !requiredOK;
|
||||
const submitButton = this.getSubmitButton();
|
||||
if (submitButton) {
|
||||
submitButton.disabled = !requiredOK;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -199,6 +201,7 @@ export class DeesForm extends DeesElement {
|
||||
) {
|
||||
const inputChildren = this.getFormElements();
|
||||
const submitButton = this.getSubmitButton();
|
||||
if (!submitButton) return;
|
||||
|
||||
switch (visualStateArg) {
|
||||
case 'normal':
|
||||
@@ -239,7 +242,6 @@ export class DeesForm extends DeesElement {
|
||||
*/
|
||||
reset() {
|
||||
const inputChildren = this.getFormElements();
|
||||
const submitButton = this.getSubmitButton();
|
||||
|
||||
for (const inputChild of inputChildren) {
|
||||
inputChild.value = null;
|
||||
|
||||
@@ -31,10 +31,10 @@ export abstract class DeesInputBase<T = any> extends DeesElement {
|
||||
* Common properties for all inputs
|
||||
*/
|
||||
@property({ type: String })
|
||||
accessor key: string;
|
||||
accessor key!: string;
|
||||
|
||||
@property({ type: String })
|
||||
accessor label: string;
|
||||
accessor label!: string;
|
||||
|
||||
@property({ type: Boolean })
|
||||
accessor required: boolean = false;
|
||||
@@ -43,7 +43,7 @@ export abstract class DeesInputBase<T = any> extends DeesElement {
|
||||
accessor disabled: boolean = false;
|
||||
|
||||
@property({ type: String })
|
||||
accessor description: string;
|
||||
accessor description!: string;
|
||||
|
||||
/**
|
||||
* Common styles for all input components
|
||||
|
||||
@@ -215,7 +215,7 @@ export class DeesInputCheckbox extends DeesInputBase<DeesInputCheckbox> {
|
||||
}
|
||||
|
||||
public focus(): void {
|
||||
const checkboxDiv = this.shadowRoot.querySelector('.checkbox');
|
||||
const checkboxDiv = this.shadowRoot!.querySelector('.checkbox');
|
||||
if (checkboxDiv) {
|
||||
(checkboxDiv as any).focus();
|
||||
}
|
||||
|
||||
@@ -610,20 +610,20 @@ export class DeesInputCode extends DeesInputBase<string> {
|
||||
{
|
||||
name: 'Cancel',
|
||||
action: async (modalRef) => {
|
||||
await modalRef.destroy();
|
||||
await modalRef!.destroy();
|
||||
},
|
||||
},
|
||||
{
|
||||
name: 'Save & Close',
|
||||
action: async (modalRef) => {
|
||||
// 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) {
|
||||
const editor = await modalEditorElement.editorDeferred.promise;
|
||||
const newValue = editor.getValue();
|
||||
this.setValue(newValue);
|
||||
}
|
||||
await modalRef.destroy();
|
||||
await modalRef!.destroy();
|
||||
},
|
||||
},
|
||||
],
|
||||
|
||||
@@ -47,9 +47,9 @@ export const demoFunc = () => html`
|
||||
const datePicker = elementArg.querySelector('dees-input-datepicker');
|
||||
|
||||
if (datePicker) {
|
||||
datePicker.addEventListener('change', (event: CustomEvent) => {
|
||||
datePicker.addEventListener('change', ((event: CustomEvent) => {
|
||||
console.log('Basic date selected:', (event.target as DeesInputDatepicker).value);
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
}}>
|
||||
<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"]');
|
||||
|
||||
if (dateTimePicker) {
|
||||
dateTimePicker.addEventListener('change', (event: CustomEvent) => {
|
||||
dateTimePicker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const value = (event.target as DeesInputDatepicker).value;
|
||||
console.log('24h format datetime:', value);
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
|
||||
if (appointmentPicker) {
|
||||
appointmentPicker.addEventListener('change', (event: CustomEvent) => {
|
||||
appointmentPicker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const value = (event.target as DeesInputDatepicker).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'}>
|
||||
@@ -102,14 +102,14 @@ export const demoFunc = () => html`
|
||||
const timezonePickers = elementArg.querySelectorAll('dees-input-datepicker');
|
||||
|
||||
timezonePickers.forEach((picker) => {
|
||||
picker.addEventListener('change', (event: CustomEvent) => {
|
||||
picker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputDatepicker;
|
||||
console.log(`${target.label} value:`, target.value);
|
||||
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
|
||||
if (input) {
|
||||
console.log(`${target.label} formatted:`, input.value);
|
||||
}
|
||||
});
|
||||
}) as EventListener);
|
||||
});
|
||||
}}>
|
||||
<dees-panel .title=${'Timezone Support'} .subtitle=${'Date and time selection with timezone awareness'}>
|
||||
@@ -140,7 +140,7 @@ export const demoFunc = () => html`
|
||||
|
||||
if (futureDatePicker) {
|
||||
// Show the min/max constraints in action
|
||||
futureDatePicker.addEventListener('change', (event: CustomEvent) => {
|
||||
futureDatePicker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const value = (event.target as DeesInputDatepicker).value;
|
||||
if (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));
|
||||
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'}>
|
||||
@@ -171,14 +171,14 @@ export const demoFunc = () => html`
|
||||
|
||||
const datePickers = elementArg.querySelectorAll('dees-input-datepicker');
|
||||
datePickers.forEach((picker) => {
|
||||
picker.addEventListener('change', (event: CustomEvent) => {
|
||||
picker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputDatepicker;
|
||||
// Log the formatted value that's displayed in the input
|
||||
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
|
||||
if (input) {
|
||||
console.log(`${target.label} format:`, input.value);
|
||||
}
|
||||
});
|
||||
}) as EventListener);
|
||||
});
|
||||
}}>
|
||||
<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) => {
|
||||
// Generate weekend dates for the current month
|
||||
const generateWeekends = () => {
|
||||
const weekends = [];
|
||||
const weekends: string[] = [];
|
||||
const now = new Date();
|
||||
const year = now.getFullYear();
|
||||
const month = now.getMonth();
|
||||
@@ -286,7 +286,7 @@ export const demoFunc = () => html`
|
||||
|
||||
const picker = elementArg.querySelector('dees-input-datepicker');
|
||||
if (picker) {
|
||||
picker.disabledDates = generateWeekends();
|
||||
(picker as DeesInputDatepicker).disabledDates = generateWeekends();
|
||||
console.log('Disabled weekend dates for current month');
|
||||
}
|
||||
}}>
|
||||
@@ -344,7 +344,7 @@ export const demoFunc = () => html`
|
||||
|
||||
const picker = elementArg.querySelector('dees-input-datepicker');
|
||||
if (picker) {
|
||||
picker.events = sampleEvents;
|
||||
(picker as DeesInputDatepicker).events = sampleEvents;
|
||||
console.log('Calendar events loaded:', sampleEvents);
|
||||
}
|
||||
}}>
|
||||
@@ -371,7 +371,7 @@ export const demoFunc = () => html`
|
||||
const output = elementArg.querySelector('#event-output');
|
||||
|
||||
if (picker && output) {
|
||||
picker.addEventListener('change', (event: CustomEvent) => {
|
||||
picker.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputDatepicker;
|
||||
const value = target.value;
|
||||
if (value) {
|
||||
@@ -379,16 +379,16 @@ export const demoFunc = () => html`
|
||||
// Get the formatted value from the input element
|
||||
const input = target.shadowRoot?.querySelector('.date-input') as HTMLInputElement;
|
||||
const formattedValue = input?.value || 'N/A';
|
||||
output.innerHTML = `
|
||||
(output as HTMLElement).innerHTML = `
|
||||
<strong>Event triggered!</strong><br>
|
||||
ISO Value: ${value}<br>
|
||||
Formatted: ${formattedValue}<br>
|
||||
Date object: ${date.toLocaleString()}
|
||||
`;
|
||||
} else {
|
||||
output.innerHTML = '<em>Date cleared</em>';
|
||||
(output as HTMLElement).innerHTML = '<em>Date cleared</em>';
|
||||
}
|
||||
});
|
||||
}) as EventListener);
|
||||
|
||||
picker.addEventListener('blur', () => {
|
||||
console.log('Datepicker lost focus');
|
||||
|
||||
@@ -56,16 +56,16 @@ export const demoFunc = () => html`
|
||||
|
||||
// Log when country changes
|
||||
if (countryDropdown) {
|
||||
countryDropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
countryDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
console.log('Country selected:', event.detail);
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
|
||||
// Log when role changes
|
||||
if (roleDropdown) {
|
||||
roleDropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
roleDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
console.log('Role selected:', event.detail);
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
}}>
|
||||
<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');
|
||||
|
||||
if (priorityDropdown) {
|
||||
priorityDropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
priorityDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
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'}>
|
||||
@@ -128,10 +128,10 @@ export const demoFunc = () => html`
|
||||
|
||||
// Log all changes from horizontal dropdowns
|
||||
dropdowns.forEach((dropdown) => {
|
||||
dropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
dropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
const label = dropdown.getAttribute('label');
|
||||
console.log(`${label}: ${event.detail.option}`);
|
||||
});
|
||||
}) as EventListener);
|
||||
});
|
||||
}}>
|
||||
<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');
|
||||
|
||||
if (dropdown) {
|
||||
dropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
dropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
console.log('Bottom dropdown selected:', event.detail);
|
||||
});
|
||||
}) as EventListener);
|
||||
|
||||
// Note: The dropdown automatically detects available space
|
||||
// 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>';
|
||||
|
||||
// Handle dropdown changes
|
||||
dropdown.addEventListener('change', (event: CustomEvent) => {
|
||||
dropdown.addEventListener('change', ((event: CustomEvent) => {
|
||||
if (event.detail.value) {
|
||||
output.innerHTML = `
|
||||
(output as HTMLElement).innerHTML = `
|
||||
<strong>Selected:</strong> ${event.detail.value.option}<br>
|
||||
<strong>Key:</strong> ${event.detail.value.key}<br>
|
||||
<strong>Price:</strong> $${event.detail.value.payload?.price || 'N/A'}<br>
|
||||
<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'}>
|
||||
@@ -281,20 +281,20 @@ export const demoFunc = () => html`
|
||||
const frameworkDropdown = elementArg.querySelector('dees-input-dropdown[key="framework"]');
|
||||
|
||||
if (form) {
|
||||
form.addEventListener('formData', (event: CustomEvent) => {
|
||||
form.addEventListener('formData', ((event: CustomEvent) => {
|
||||
console.log('Form submitted with data:', event.detail.data);
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
|
||||
if (projectTypeDropdown && frameworkDropdown) {
|
||||
// Filter frameworks based on project type
|
||||
projectTypeDropdown.addEventListener('selectedOption', (event: CustomEvent) => {
|
||||
projectTypeDropdown.addEventListener('selectedOption', ((event: CustomEvent) => {
|
||||
const selectedType = event.detail.key;
|
||||
console.log(`Project type changed to: ${selectedType}`);
|
||||
|
||||
|
||||
// In a real app, you could filter the framework options based on project type
|
||||
// For demo purposes, we just log the change
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
}}>
|
||||
<dees-panel .title=${'7. Form Integration'} .subtitle=${'Dropdown working within a form with validation'}>
|
||||
|
||||
@@ -30,14 +30,14 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
|
||||
accessor options: { option: string; key: string; payload?: any }[] = [];
|
||||
|
||||
@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
|
||||
public get value() {
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -372,7 +372,7 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
|
||||
|
||||
if (this.isOpened) {
|
||||
// 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 spaceBelow = window.innerHeight - rect.bottom;
|
||||
const spaceAbove = rect.top;
|
||||
@@ -382,7 +382,7 @@ export class DeesInputDropdown extends DeesInputBase<DeesInputDropdown> {
|
||||
|
||||
// Focus search input if present
|
||||
await this.updateComplete;
|
||||
const searchInput = this.shadowRoot.querySelector('.search input') as HTMLInputElement;
|
||||
const searchInput = this.shadowRoot!.querySelector('.search input') as HTMLInputElement;
|
||||
if (searchInput) {
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
||||
accessor maxFiles: number = 0; // 0 means no limit
|
||||
|
||||
@property({ type: String, reflect: true })
|
||||
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' = null;
|
||||
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' | null = null;
|
||||
|
||||
accessor validationMessage: string = '';
|
||||
|
||||
@@ -266,7 +266,7 @@ export class DeesInputFileupload extends DeesInputBase<DeesInputFileupload> {
|
||||
return;
|
||||
}
|
||||
['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;
|
||||
}
|
||||
['dragenter', 'dragover', 'dragleave', 'drop'].forEach((eventName) => {
|
||||
this.dropArea!.removeEventListener(eventName, this.handleDragEvent);
|
||||
this.dropArea!.removeEventListener(eventName, this.handleDragEvent as unknown as EventListener);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ export class DeesInputIban extends DeesInputBase<DeesInputIban> {
|
||||
|
||||
public firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
|
||||
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) {
|
||||
deesInputText.changeSubject.subscribe(() => {
|
||||
this.changeSubject.next(this);
|
||||
@@ -81,8 +81,10 @@ export class DeesInputIban extends DeesInputBase<DeesInputIban> {
|
||||
}
|
||||
}
|
||||
this.enteredIbanIsValid = ibantools.isValidIBAN(this.enteredString.replace(/ /g, ''));
|
||||
const deesInputText = this.shadowRoot.querySelector('dees-input-text');
|
||||
deesInputText.validationText = `IBAN is valid: ${this.enteredIbanIsValid}`;
|
||||
const deesInputText = this.shadowRoot!.querySelector('dees-input-text') as any;
|
||||
if (deesInputText) {
|
||||
deesInputText.validationText = `IBAN is valid: ${this.enteredIbanIsValid}`;
|
||||
}
|
||||
}
|
||||
|
||||
public getValue(): string {
|
||||
|
||||
@@ -211,9 +211,9 @@ export class DeesInputMultitoggle extends DeesInputBase<DeesInputMultitoggle> {
|
||||
private indicatorInitialized = false;
|
||||
|
||||
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);
|
||||
|
||||
|
||||
// If no valid selection, hide indicator
|
||||
if (selectedIndex === -1 || !indicator) {
|
||||
if (indicator) {
|
||||
@@ -221,8 +221,8 @@ export class DeesInputMultitoggle extends DeesInputBase<DeesInputMultitoggle> {
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
const option: HTMLDivElement = this.shadowRoot.querySelector(
|
||||
|
||||
const option: HTMLDivElement | null = this.shadowRoot!.querySelector(
|
||||
`.option:nth-child(${selectedIndex + 2})`
|
||||
);
|
||||
|
||||
|
||||
@@ -67,7 +67,7 @@ export class DeesInputPhone extends DeesInputBase<DeesInputPhone> {
|
||||
}
|
||||
|
||||
// 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) {
|
||||
innerInput.changeSubject.subscribe(() => {
|
||||
this.changeSubject.next(this);
|
||||
|
||||
@@ -35,7 +35,7 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
accessor direction: 'vertical' | 'horizontal' = 'vertical';
|
||||
|
||||
@property({ type: String, reflect: true })
|
||||
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' = null;
|
||||
accessor validationState: 'valid' | 'invalid' | 'warn' | 'pending' | null = null;
|
||||
|
||||
// Form compatibility
|
||||
public get value() {
|
||||
@@ -346,15 +346,15 @@ export class DeesInputRadiogroup extends DeesInputBase<string | object> {
|
||||
}
|
||||
|
||||
private focusNextOption() {
|
||||
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement);
|
||||
const radioCircles = Array.from(this.shadowRoot!.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot!.activeElement);
|
||||
const nextIndex = (currentIndex + 1) % radioCircles.length;
|
||||
(radioCircles[nextIndex] as HTMLElement).focus();
|
||||
}
|
||||
|
||||
private focusPreviousOption() {
|
||||
const radioCircles = Array.from(this.shadowRoot.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot.activeElement);
|
||||
const radioCircles = Array.from(this.shadowRoot!.querySelectorAll('.radio-circle'));
|
||||
const currentIndex = radioCircles.findIndex(el => el === this.shadowRoot!.activeElement);
|
||||
const prevIndex = currentIndex <= 0 ? radioCircles.length - 1 : currentIndex - 1;
|
||||
(radioCircles[prevIndex] as HTMLElement).focus();
|
||||
}
|
||||
|
||||
@@ -58,11 +58,11 @@ export class DeesInputRichtext extends DeesInputBase<string> {
|
||||
@state()
|
||||
accessor wordCount: number = 0;
|
||||
|
||||
private editorElement: HTMLElement;
|
||||
private linkInputElement: HTMLInputElement;
|
||||
private editorElement!: HTMLElement;
|
||||
private linkInputElement!: HTMLInputElement;
|
||||
private tiptapBundle: ITiptapBundle | null = null;
|
||||
|
||||
public editor: Editor;
|
||||
public editor!: Editor;
|
||||
|
||||
public static styles = richtextStyles;
|
||||
|
||||
@@ -235,8 +235,8 @@ export class DeesInputRichtext extends DeesInputBase<string> {
|
||||
// Load Tiptap from CDN
|
||||
this.tiptapBundle = await DeesServiceLibLoader.getInstance().loadTiptap();
|
||||
|
||||
this.editorElement = this.shadowRoot.querySelector('.editor-content');
|
||||
this.linkInputElement = this.shadowRoot.querySelector('.link-input input');
|
||||
this.editorElement = this.shadowRoot!.querySelector('.editor-content')!;
|
||||
this.linkInputElement = this.shadowRoot!.querySelector('.link-input input')!;
|
||||
this.initializeEditor();
|
||||
}
|
||||
|
||||
|
||||
@@ -73,9 +73,9 @@ export const demoFunc = () => html`
|
||||
const inputs = elementArg.querySelectorAll('dees-input-text');
|
||||
|
||||
inputs.forEach((input: DeesInputText) => {
|
||||
input.addEventListener('changeSubject', (event: CustomEvent) => {
|
||||
input.addEventListener('changeSubject', ((event: CustomEvent) => {
|
||||
console.log(`Input "${input.label}" changed to:`, input.getValue());
|
||||
});
|
||||
}) as EventListener);
|
||||
|
||||
input.addEventListener('blur', () => {
|
||||
console.log(`Input "${input.label}" lost focus`);
|
||||
@@ -271,7 +271,8 @@ export const demoFunc = () => html`
|
||||
// Track password visibility toggles
|
||||
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
|
||||
const checkToggle = () => {
|
||||
const inputEl = input.shadowRoot?.querySelector('input');
|
||||
@@ -316,10 +317,10 @@ export const demoFunc = () => html`
|
||||
|
||||
if (dynamicInput && output) {
|
||||
// Update output on every change
|
||||
dynamicInput.addEventListener('changeSubject', (event: CustomEvent) => {
|
||||
dynamicInput.addEventListener('changeSubject', ((event: CustomEvent) => {
|
||||
const value = (event.detail as DeesInputText).getValue();
|
||||
output.textContent = `Current value: "${value}"`;
|
||||
});
|
||||
}) as EventListener);
|
||||
|
||||
// Also track focus/blur events
|
||||
dynamicInput.addEventListener('focus', () => {
|
||||
|
||||
@@ -47,7 +47,7 @@ export class DeesInputText extends DeesInputBase {
|
||||
type: Boolean,
|
||||
reflect: true,
|
||||
})
|
||||
accessor validationState: 'valid' | 'warn' | 'invalid';
|
||||
accessor validationState!: 'valid' | 'warn' | 'invalid';
|
||||
|
||||
@property({
|
||||
reflect: true,
|
||||
@@ -55,7 +55,7 @@ export class DeesInputText extends DeesInputBase {
|
||||
accessor validationText: string = '';
|
||||
|
||||
@property({})
|
||||
accessor validationFunction: (value: string) => boolean;
|
||||
accessor validationFunction!: (value: string) => boolean;
|
||||
|
||||
public static styles = [
|
||||
themeDefaultStyles,
|
||||
@@ -274,12 +274,12 @@ export class DeesInputText extends DeesInputBase {
|
||||
}
|
||||
|
||||
public async focus() {
|
||||
const textInput = this.shadowRoot.querySelector('input');
|
||||
textInput.focus();
|
||||
const textInput = this.shadowRoot!.querySelector('input');
|
||||
textInput!.focus();
|
||||
}
|
||||
|
||||
public async blur() {
|
||||
const textInput = this.shadowRoot.querySelector('input');
|
||||
textInput.blur();
|
||||
const textInput = this.shadowRoot!.querySelector('input');
|
||||
textInput!.blur();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,17 +12,19 @@ export const demoFunc = () => html`
|
||||
|
||||
if (toggleAllOnBtn && toggleAllOffBtn) {
|
||||
toggleAllOnBtn.addEventListener('click', () => {
|
||||
featureToggles.forEach((toggle: DeesInputToggle) => {
|
||||
if (!toggle.disabled && !toggle.required) {
|
||||
toggle.value = true;
|
||||
featureToggles.forEach((toggle) => {
|
||||
const t = toggle as unknown as DeesInputToggle;
|
||||
if (!t.disabled && !t.required) {
|
||||
t.value = true;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
toggleAllOffBtn.addEventListener('click', () => {
|
||||
featureToggles.forEach((toggle: DeesInputToggle) => {
|
||||
if (!toggle.disabled && !toggle.required) {
|
||||
toggle.value = false;
|
||||
featureToggles.forEach((toggle) => {
|
||||
const t = toggle as unknown as DeesInputToggle;
|
||||
if (!t.disabled && !t.required) {
|
||||
t.value = false;
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -280,10 +282,10 @@ export const demoFunc = () => html`
|
||||
<dees-input-toggle
|
||||
.label=${'Airplane mode'}
|
||||
.value=${false}
|
||||
@newValue=${(event: CustomEvent) => {
|
||||
@newValue=${(event: Event) => {
|
||||
const output = document.querySelector('#airplane-output');
|
||||
if (output) {
|
||||
output.textContent = `Airplane mode: ${event.detail ? 'ON' : 'OFF'}`;
|
||||
output.textContent = `Airplane mode: ${(event as CustomEvent).detail ? 'ON' : 'OFF'}`;
|
||||
}
|
||||
}}
|
||||
></dees-input-toggle>
|
||||
@@ -291,10 +293,10 @@ export const demoFunc = () => html`
|
||||
<dees-input-toggle
|
||||
.label=${'Do not disturb'}
|
||||
.value=${false}
|
||||
@newValue=${(event: CustomEvent) => {
|
||||
@newValue=${(event: Event) => {
|
||||
const output = document.querySelector('#dnd-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>
|
||||
|
||||
@@ -156,7 +156,7 @@ export class DeesInputTypelist extends DeesInputBase<DeesInputTypelist> {
|
||||
<dees-label .label=${this.label} .description=${this.description}></dees-label>
|
||||
<div class="mainbox">
|
||||
<div class="tags" @click=${() => {
|
||||
this.shadowRoot.querySelector('input').focus();
|
||||
this.shadowRoot!.querySelector('input')!.focus();
|
||||
}}>
|
||||
${this.value.length === 0
|
||||
? html`<div class="notags">No tags yet</div>`
|
||||
|
||||
@@ -200,15 +200,16 @@ export class HeadingBlockHandler extends BaseBlockHandler {
|
||||
const wysiwygBlock = (headingBlock.getRootNode() as ShadowRoot).host as any;
|
||||
if (wysiwygBlock) {
|
||||
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
|
||||
const self = this;
|
||||
(wysiwygBlock as any).disconnectedCallback = async function() {
|
||||
if (this.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', this.selectionHandler);
|
||||
this.selectionHandler = null;
|
||||
if (self.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', self.selectionHandler);
|
||||
self.selectionHandler = null;
|
||||
}
|
||||
if (originalDisconnectedCallback) {
|
||||
await originalDisconnectedCallback.call(wysiwygBlock);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -213,15 +213,16 @@ export class ListBlockHandler extends BaseBlockHandler {
|
||||
const wysiwygBlock = (listBlock.getRootNode() as ShadowRoot).host as any;
|
||||
if (wysiwygBlock) {
|
||||
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
|
||||
const self = this;
|
||||
(wysiwygBlock as any).disconnectedCallback = async function() {
|
||||
if (this.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', this.selectionHandler);
|
||||
this.selectionHandler = null;
|
||||
if (self.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', self.selectionHandler);
|
||||
self.selectionHandler = null;
|
||||
}
|
||||
if (originalDisconnectedCallback) {
|
||||
await originalDisconnectedCallback.call(wysiwygBlock);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -193,15 +193,16 @@ export class ParagraphBlockHandler extends BaseBlockHandler {
|
||||
const wysiwygBlock = element.closest('dees-wysiwyg-block');
|
||||
if (wysiwygBlock) {
|
||||
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
|
||||
const self = this;
|
||||
(wysiwygBlock as any).disconnectedCallback = async function() {
|
||||
if (this.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', this.selectionHandler);
|
||||
this.selectionHandler = null;
|
||||
if (self.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', self.selectionHandler);
|
||||
self.selectionHandler = null;
|
||||
}
|
||||
if (originalDisconnectedCallback) {
|
||||
await originalDisconnectedCallback.call(wysiwygBlock);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -192,15 +192,16 @@ export class QuoteBlockHandler extends BaseBlockHandler {
|
||||
const wysiwygBlock = (quoteBlock.getRootNode() as ShadowRoot).host as any;
|
||||
if (wysiwygBlock) {
|
||||
const originalDisconnectedCallback = (wysiwygBlock as any).disconnectedCallback;
|
||||
const self = this;
|
||||
(wysiwygBlock as any).disconnectedCallback = async function() {
|
||||
if (this.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', this.selectionHandler);
|
||||
this.selectionHandler = null;
|
||||
if (self.selectionHandler) {
|
||||
document.removeEventListener('selectionchange', self.selectionHandler);
|
||||
self.selectionHandler = null;
|
||||
}
|
||||
if (originalDisconnectedCallback) {
|
||||
await originalDisconnectedCallback.call(wysiwygBlock);
|
||||
}
|
||||
}.bind(this);
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -188,36 +188,39 @@ export class DeesFormattingMenu extends DeesElement {
|
||||
|
||||
public firstUpdated(): void {
|
||||
// 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');
|
||||
if (menu && menu.contains(e.target as Node)) {
|
||||
if (menu && menu.contains(mouseEvent.target as Node)) {
|
||||
// Prevent focus loss
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
mouseEvent.preventDefault();
|
||||
mouseEvent.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.shadowRoot?.addEventListener('click', (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
|
||||
this.shadowRoot!.addEventListener('click', (e: Event) => {
|
||||
const mouseEvent = e as MouseEvent;
|
||||
const target = mouseEvent.target as HTMLElement;
|
||||
const button = target.closest('.format-button') as HTMLElement;
|
||||
|
||||
|
||||
if (button) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
mouseEvent.preventDefault();
|
||||
mouseEvent.stopPropagation();
|
||||
|
||||
const command = button.getAttribute('data-command');
|
||||
if (command) {
|
||||
this.applyFormat(command);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.shadowRoot?.addEventListener('focus', (e: FocusEvent) => {
|
||||
|
||||
this.shadowRoot!.addEventListener('focus', (e: Event) => {
|
||||
const focusEvent = e as FocusEvent;
|
||||
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
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
focusEvent.preventDefault();
|
||||
focusEvent.stopPropagation();
|
||||
}
|
||||
}, true); // Use capture phase
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
|
||||
@state()
|
||||
accessor selectedText: string = '';
|
||||
|
||||
public editorContentRef: HTMLDivElement;
|
||||
public editorContentRef!: HTMLDivElement;
|
||||
public isComposing: boolean = false;
|
||||
|
||||
// Handler instances
|
||||
@@ -144,7 +144,7 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
|
||||
// No global selection listener needed
|
||||
|
||||
// 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) {
|
||||
this.selectedText = e.detail.text;
|
||||
@@ -164,8 +164,8 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}) as EventListener);
|
||||
|
||||
// Hide formatting menu when clicking outside
|
||||
document.addEventListener('mousedown', (e) => {
|
||||
// Check if click is on the formatting menu itself
|
||||
@@ -896,14 +896,14 @@ export class DeesInputWysiwyg extends DeesInputBase<string> {
|
||||
{
|
||||
name: 'Cancel',
|
||||
action: async (modal) => {
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
resolve(null);
|
||||
}
|
||||
},
|
||||
{
|
||||
name: 'Add Link',
|
||||
action: async (modal) => {
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
resolve(linkUrl);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -216,46 +216,50 @@ export class DeesSlashMenu extends DeesElement {
|
||||
|
||||
public firstUpdated(): void {
|
||||
// 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');
|
||||
if (menu && menu.contains(e.target as Node)) {
|
||||
if (menu && menu.contains(mouseEvent.target as Node)) {
|
||||
// Prevent focus loss
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
mouseEvent.preventDefault();
|
||||
mouseEvent.stopPropagation();
|
||||
}
|
||||
});
|
||||
|
||||
this.shadowRoot?.addEventListener('click', (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
|
||||
this.shadowRoot!.addEventListener('click', (e: Event) => {
|
||||
const mouseEvent = e as MouseEvent;
|
||||
const target = mouseEvent.target as HTMLElement;
|
||||
const menuItem = target.closest('.slash-menu-item') as HTMLElement;
|
||||
|
||||
|
||||
if (menuItem) {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
mouseEvent.preventDefault();
|
||||
mouseEvent.stopPropagation();
|
||||
|
||||
const itemType = menuItem.getAttribute('data-item-type');
|
||||
if (itemType) {
|
||||
this.selectItem(itemType);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.shadowRoot?.addEventListener('mouseenter', (e: MouseEvent) => {
|
||||
const target = e.target as HTMLElement;
|
||||
|
||||
this.shadowRoot!.addEventListener('mouseenter', (e: Event) => {
|
||||
const mouseEvent = e as MouseEvent;
|
||||
const target = mouseEvent.target as HTMLElement;
|
||||
const menuItem = target.closest('.slash-menu-item') as HTMLElement;
|
||||
|
||||
|
||||
if (menuItem) {
|
||||
const index = parseInt(menuItem.getAttribute('data-item-index') || '0', 10);
|
||||
this.selectedIndex = index;
|
||||
}
|
||||
}, 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');
|
||||
if (menu && menu.contains(e.target as Node)) {
|
||||
if (menu && menu.contains(focusEvent.target as Node)) {
|
||||
// Prevent menu from taking focus
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
focusEvent.preventDefault();
|
||||
focusEvent.stopPropagation();
|
||||
}
|
||||
}, true); // Use capture phase
|
||||
}
|
||||
|
||||
@@ -33,13 +33,13 @@ export class DeesWysiwygBlock extends DeesElement {
|
||||
}
|
||||
}
|
||||
@property({ type: Object })
|
||||
accessor block: IBlock;
|
||||
accessor block!: IBlock;
|
||||
|
||||
@property({ type: Boolean })
|
||||
accessor isSelected: boolean = false;
|
||||
|
||||
@property({ type: Object })
|
||||
accessor handlers: IBlockEventHandlers;
|
||||
accessor handlers!: IBlockEventHandlers;
|
||||
|
||||
@property({ type: Object })
|
||||
accessor wysiwygComponent: any; // Reference to parent dees-input-wysiwyg
|
||||
|
||||
@@ -105,10 +105,10 @@ export class WysiwygDragDropHandler {
|
||||
handleDragEnd(): void {
|
||||
// Clean up visual state
|
||||
const allBlocks = this.component.editorContentRef.querySelectorAll('.block-wrapper');
|
||||
allBlocks.forEach((block: HTMLElement) => {
|
||||
block.classList.remove('dragging', 'move-up', 'move-down');
|
||||
block.style.removeProperty('--drag-offset');
|
||||
block.style.removeProperty('transform');
|
||||
allBlocks.forEach((block) => {
|
||||
(block as HTMLElement).classList.remove('dragging', 'move-up', 'move-down');
|
||||
(block as HTMLElement).style.removeProperty('--drag-offset');
|
||||
(block as HTMLElement).style.removeProperty('transform');
|
||||
});
|
||||
|
||||
// Remove dragging class from editor
|
||||
|
||||
@@ -704,17 +704,17 @@ export class WysiwygKeyboardHandler {
|
||||
const rect = range.getBoundingClientRect();
|
||||
|
||||
// Get the container element
|
||||
let container = range.commonAncestorContainer;
|
||||
let container: Node = range.commonAncestorContainer;
|
||||
if (container.nodeType === Node.TEXT_NODE) {
|
||||
container = container.parentElement;
|
||||
container = container.parentElement!;
|
||||
}
|
||||
|
||||
|
||||
// Get the top position of the container
|
||||
const containerRect = (container as Element).getBoundingClientRect();
|
||||
|
||||
|
||||
// Check if we're near the top (within 5px tolerance for line height variations)
|
||||
const isNearTop = rect.top - containerRect.top < 5;
|
||||
|
||||
|
||||
// For single-line content, also check if we're at the beginning
|
||||
if (container.textContent && !container.textContent.includes('\n')) {
|
||||
const cursorPos = WysiwygSelection.getCursorPositionInElement(container as Element, ...shadowRoots);
|
||||
@@ -740,11 +740,11 @@ export class WysiwygKeyboardHandler {
|
||||
const rect = range.getBoundingClientRect();
|
||||
|
||||
// Get the container element
|
||||
let container = range.commonAncestorContainer;
|
||||
let container: Node = range.commonAncestorContainer;
|
||||
if (container.nodeType === Node.TEXT_NODE) {
|
||||
container = container.parentElement;
|
||||
container = container.parentElement!;
|
||||
}
|
||||
|
||||
|
||||
// Get the bottom position of the container
|
||||
const containerRect = (container as Element).getBoundingClientRect();
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export class WysiwygModalManager {
|
||||
{
|
||||
name: 'Cancel',
|
||||
action: async (modal) => {
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
resolve(null);
|
||||
}
|
||||
}
|
||||
@@ -158,7 +158,7 @@ export class WysiwygModalManager {
|
||||
{
|
||||
name: 'Done',
|
||||
action: async (modal) => {
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
@@ -56,10 +56,10 @@ export const demoFunc = () => html`
|
||||
const roundProfile = elementArg.querySelector('dees-input-profilepicture[shape="round"]');
|
||||
|
||||
if (roundProfile) {
|
||||
roundProfile.addEventListener('change', (event: CustomEvent) => {
|
||||
roundProfile.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputProfilePicture;
|
||||
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'}>
|
||||
@@ -85,10 +85,10 @@ export const demoFunc = () => html`
|
||||
// Different sizes demo
|
||||
const profiles = elementArg.querySelectorAll('dees-input-profilepicture');
|
||||
profiles.forEach((profile) => {
|
||||
profile.addEventListener('change', (event: CustomEvent) => {
|
||||
profile.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputProfilePicture;
|
||||
console.log(`Profile (size ${target.size}) changed`);
|
||||
});
|
||||
}) as EventListener);
|
||||
});
|
||||
}}>
|
||||
<dees-panel .title=${'Size Variations'} .subtitle=${'Profile pictures in different sizes'}>
|
||||
@@ -122,15 +122,15 @@ export const demoFunc = () => html`
|
||||
if (prefilledProfile) {
|
||||
prefilledProfile.value = sampleImageUrl;
|
||||
|
||||
prefilledProfile.addEventListener('change', (event: CustomEvent) => {
|
||||
prefilledProfile.addEventListener('change', ((event: CustomEvent) => {
|
||||
const target = event.target as DeesInputProfilePicture;
|
||||
const output = elementArg.querySelector('#prefilled-output');
|
||||
if (output) {
|
||||
output.textContent = target.value ?
|
||||
`Image data: ${target.value.substring(0, 80)}...` :
|
||||
output.textContent = target.value ?
|
||||
`Image data: ${target.value.substring(0, 80)}...` :
|
||||
'No image selected';
|
||||
}
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
}}>
|
||||
<dees-panel .title=${'Pre-filled and Value Binding'} .subtitle=${'Profile picture with initial value and change tracking'}>
|
||||
|
||||
@@ -436,10 +436,10 @@ export class DeesInputProfilePicture extends DeesInputBase<DeesInputProfilePictu
|
||||
this.modalInstance.outputSize = this.outputSize;
|
||||
this.modalInstance.outputQuality = this.outputQuality;
|
||||
|
||||
this.modalInstance.addEventListener('save', (event: CustomEvent) => {
|
||||
this.modalInstance.addEventListener('save', ((event: CustomEvent) => {
|
||||
this.value = event.detail.croppedImage;
|
||||
this.changeSubject.next(this);
|
||||
});
|
||||
}) as EventListener);
|
||||
|
||||
document.body.appendChild(this.modalInstance);
|
||||
}
|
||||
|
||||
@@ -41,7 +41,7 @@ export class DeesChips extends DeesElement {
|
||||
accessor selectableChips: Tag[] = [];
|
||||
|
||||
@property()
|
||||
accessor selectedChip: Tag = null;
|
||||
accessor selectedChip: Tag | null = null;
|
||||
|
||||
@property({
|
||||
type: Array,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import { html, css, cssManager } from '@design.estate/dees-element';
|
||||
import type { DeesDashboardgrid } from './dees-dashboardgrid.js';
|
||||
import type { LayoutDirection } from './types.js';
|
||||
import '@design.estate/dees-wcctools/demotools';
|
||||
|
||||
export const demoFunc = () => {
|
||||
@@ -160,7 +161,7 @@ export const demoFunc = () => {
|
||||
});
|
||||
|
||||
// Enhanced logging for reflow events
|
||||
let lastPlaceholderPosition = null;
|
||||
let lastPlaceholderPosition: Record<string, string> | null = null;
|
||||
let moveEventCounter = 0;
|
||||
|
||||
// Helper function to log grid state
|
||||
@@ -231,25 +232,28 @@ export const demoFunc = () => {
|
||||
// Log initial 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', {
|
||||
widget: e.detail.widget,
|
||||
displaced: e.detail.displaced,
|
||||
swappedWith: e.detail.swappedWith
|
||||
widget: detail.widget,
|
||||
displaced: detail.displaced,
|
||||
swappedWith: detail.swappedWith
|
||||
});
|
||||
});
|
||||
|
||||
grid.addEventListener('widget-resize', (e: CustomEvent) => {
|
||||
grid.addEventListener('widget-resize', (e: Event) => {
|
||||
const detail = (e as CustomEvent).detail;
|
||||
logGridState('Widget Resize', {
|
||||
widget: e.detail.widget,
|
||||
displaced: e.detail.displaced,
|
||||
swappedWith: e.detail.swappedWith
|
||||
widget: detail.widget,
|
||||
displaced: detail.displaced,
|
||||
swappedWith: detail.swappedWith
|
||||
});
|
||||
});
|
||||
|
||||
grid.addEventListener('widget-remove', (e: CustomEvent) => {
|
||||
grid.addEventListener('widget-remove', (e: Event) => {
|
||||
const detail = (e as CustomEvent).detail;
|
||||
logGridState('Widget Remove', {
|
||||
removedWidget: e.detail.widget
|
||||
removedWidget: detail.widget
|
||||
});
|
||||
updateStatus();
|
||||
});
|
||||
@@ -312,7 +316,7 @@ export const demoFunc = () => {
|
||||
|
||||
// Log compact operations
|
||||
const originalCompact = grid.compact.bind(grid);
|
||||
grid.compact = (direction?: string) => {
|
||||
grid.compact = (direction?: LayoutDirection) => {
|
||||
console.group('🗜️ Compacting Grid');
|
||||
console.log('Direction:', direction || 'vertical');
|
||||
logGridState('Before Compact');
|
||||
|
||||
@@ -32,7 +32,7 @@ export class DeesLabel extends DeesElement {
|
||||
type: String,
|
||||
reflect: true,
|
||||
})
|
||||
accessor description: string;
|
||||
accessor description!: string;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
|
||||
@@ -45,7 +45,7 @@ export class DeesStepper extends DeesElement {
|
||||
@property({
|
||||
type: Object,
|
||||
})
|
||||
accessor selectedStep: IStep;
|
||||
accessor selectedStep!: IStep;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -214,19 +214,19 @@ export class DeesStepper extends DeesElement {
|
||||
this.setScrollStatus();
|
||||
// Remove entrance class after initial animation completes
|
||||
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() {
|
||||
this.setScrollStatus();
|
||||
}
|
||||
|
||||
public scroller: typeof domtools.plugins.SweetScroll.prototype;
|
||||
public scroller!: typeof domtools.plugins.SweetScroll.prototype;
|
||||
|
||||
public async setScrollStatus() {
|
||||
const stepperContainer: HTMLElement = this.shadowRoot.querySelector('.stepperContainer');
|
||||
const firstStepElement: HTMLElement = this.shadowRoot.querySelector('.step');
|
||||
const selectedStepElement: HTMLElement = this.shadowRoot.querySelector('.selected');
|
||||
const stepperContainer = this.shadowRoot!.querySelector('.stepperContainer') as HTMLElement;
|
||||
const firstStepElement = this.shadowRoot!.querySelector('.step') as HTMLElement;
|
||||
const selectedStepElement = this.shadowRoot!.querySelector('.selected') as HTMLElement;
|
||||
if (!selectedStepElement) {
|
||||
return;
|
||||
}
|
||||
@@ -278,7 +278,7 @@ export class DeesStepper extends DeesElement {
|
||||
this.selectedStep = previousStep;
|
||||
await this.domtoolsPromise;
|
||||
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() {
|
||||
|
||||
@@ -21,9 +21,9 @@ export function throttle<T extends (...args: any[]) => any>(
|
||||
): (...args: Parameters<T>) => void {
|
||||
let inThrottle: boolean;
|
||||
|
||||
return function executedFunction(...args: Parameters<T>) {
|
||||
return (...args: Parameters<T>) => {
|
||||
if (!inThrottle) {
|
||||
func.apply(this, args);
|
||||
func(...args);
|
||||
inThrottle = true;
|
||||
setTimeout(() => inThrottle = false, limit);
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@ export const demo = () => {
|
||||
];
|
||||
|
||||
const generateGridItems = (count: number) => {
|
||||
const items = [];
|
||||
const items: ReturnType<typeof html>[] = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
const pdfUrl = samplePdfs[i % samplePdfs.length];
|
||||
items.push(html`
|
||||
|
||||
@@ -130,7 +130,7 @@ export class DeesContextmenu extends DeesElement {
|
||||
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 })[] = [];
|
||||
windowLayer: DeesWindowLayer;
|
||||
windowLayer!: DeesWindowLayer;
|
||||
|
||||
private submenu: DeesContextmenu | null = null;
|
||||
private submenuTimeout: any = null;
|
||||
@@ -278,7 +278,7 @@ export class DeesContextmenu extends DeesElement {
|
||||
}
|
||||
|
||||
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'));
|
||||
|
||||
switch (event.key) {
|
||||
@@ -352,7 +352,7 @@ export class DeesContextmenu extends DeesElement {
|
||||
if (!menuItem.submenu || menuItem.submenu.length === 0) return;
|
||||
|
||||
// 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;
|
||||
if (!menuItemElement) return;
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ export const demoFunc = () => html`
|
||||
heading: 'With Help Button',
|
||||
showHelpButton: true,
|
||||
onHelp: async () => {
|
||||
const helpModal = await DeesModal.createAndShow({
|
||||
await DeesModal.createAndShow({
|
||||
heading: 'Help',
|
||||
width: 'small',
|
||||
showCloseButton: true,
|
||||
@@ -60,7 +60,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Got it',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
},
|
||||
@@ -70,7 +70,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'OK',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>With Help Button</dees-button>
|
||||
@@ -85,7 +85,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Close',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>No Close Button</dees-button>
|
||||
@@ -101,7 +101,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Done',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Both Buttons</dees-button>
|
||||
@@ -116,7 +116,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Close',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Clean Header</dees-button>
|
||||
@@ -136,10 +136,10 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Cancel',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'OK',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Small Modal</dees-button>
|
||||
@@ -157,10 +157,10 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Cancel',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Sign Up',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Medium Modal</dees-button>
|
||||
@@ -181,10 +181,10 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Cancel',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Save',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Large Modal</dees-button>
|
||||
@@ -207,10 +207,10 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Save',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Cancel',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Fullscreen Modal</dees-button>
|
||||
@@ -230,7 +230,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Close',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Custom 700px</dees-button>
|
||||
@@ -245,7 +245,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Got it',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Max Width 600px</dees-button>
|
||||
@@ -260,7 +260,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'OK',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Min Width 400px</dees-button>
|
||||
@@ -279,13 +279,13 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Delete',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Cancel',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Save Changes',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Three Buttons</dees-button>
|
||||
@@ -298,7 +298,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Acknowledge',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Single Button</dees-button>
|
||||
@@ -322,10 +322,10 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Discard All Changes',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}, {
|
||||
name: 'Save and Continue Editing',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Long Labels</dees-button>
|
||||
@@ -347,7 +347,7 @@ export const demoFunc = () => html`
|
||||
`,
|
||||
menuOptions: [{
|
||||
name: 'Close',
|
||||
action: async (modal) => modal.destroy()
|
||||
action: async (modal) => modal!.destroy()
|
||||
}],
|
||||
});
|
||||
}}>Test Responsive</dees-button>
|
||||
|
||||
@@ -85,7 +85,7 @@ export class DeesModal extends DeesElement {
|
||||
accessor heading = '';
|
||||
|
||||
@state({})
|
||||
accessor content: TemplateResult;
|
||||
accessor content!: TemplateResult;
|
||||
|
||||
@state({})
|
||||
accessor menuOptions: plugins.tsclass.website.IMenuItem<DeesModal>[] = [];
|
||||
@@ -94,10 +94,10 @@ export class DeesModal extends DeesElement {
|
||||
accessor width: 'small' | 'medium' | 'large' | 'fullscreen' | number = 'medium';
|
||||
|
||||
@property({ type: Number })
|
||||
accessor maxWidth: number;
|
||||
accessor maxWidth!: number;
|
||||
|
||||
@property({ type: Number })
|
||||
accessor minWidth: number;
|
||||
accessor minWidth!: number;
|
||||
|
||||
@property({ type: Boolean })
|
||||
accessor showCloseButton: boolean = true;
|
||||
@@ -106,7 +106,7 @@ export class DeesModal extends DeesElement {
|
||||
accessor showHelpButton: boolean = false;
|
||||
|
||||
@property({ attribute: false })
|
||||
accessor onHelp: () => void | Promise<void>;
|
||||
accessor onHelp!: () => void | Promise<void>;
|
||||
|
||||
@property({ type: Boolean })
|
||||
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>) {
|
||||
super.firstUpdated(_changedProperties);
|
||||
const domtools = await this.domtoolsPromise;
|
||||
await domtools.convenience.smartdelay.delayFor(30);
|
||||
const modal = this.shadowRoot.querySelector('.modal');
|
||||
modal.classList.add('show');
|
||||
const modal = this.shadowRoot!.querySelector('.modal');
|
||||
modal!.classList.add('show');
|
||||
}
|
||||
|
||||
public async handleOutsideClick(eventArg: MouseEvent) {
|
||||
eventArg.stopPropagation();
|
||||
const modalContainer = this.shadowRoot.querySelector('.modalContainer');
|
||||
const modalContainer = this.shadowRoot!.querySelector('.modalContainer');
|
||||
if (eventArg.target === modalContainer) {
|
||||
await this.destroy();
|
||||
}
|
||||
@@ -402,8 +402,8 @@ export class DeesModal extends DeesElement {
|
||||
|
||||
public async destroy() {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
const modal = this.shadowRoot.querySelector('.modal');
|
||||
modal.classList.add('predestroy');
|
||||
const modal = this.shadowRoot!.querySelector('.modal');
|
||||
modal!.classList.add('predestroy');
|
||||
await domtools.convenience.smartdelay.delayFor(200);
|
||||
document.body.removeChild(this);
|
||||
await this.windowLayer.destroy();
|
||||
|
||||
@@ -42,7 +42,7 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
speechbubble.manifested = true;
|
||||
windowLayer.appendChild(speechbubble);
|
||||
windowLayer.style.pointerEvents = 'none';
|
||||
(windowLayer.shadowRoot.querySelector('.windowOverlay') as HTMLElement).style.pointerEvents = 'none';
|
||||
(windowLayer.shadowRoot!.querySelector('.windowOverlay') as HTMLElement).style.pointerEvents = 'none';
|
||||
return speechbubble;
|
||||
}
|
||||
|
||||
@@ -50,13 +50,13 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
@property({
|
||||
type: Object,
|
||||
})
|
||||
accessor reffedElement: HTMLElement;
|
||||
accessor reffedElement!: HTMLElement;
|
||||
|
||||
@property({
|
||||
type: String,
|
||||
reflect: true,
|
||||
})
|
||||
accessor text: string;
|
||||
accessor text!: string;
|
||||
|
||||
@property({
|
||||
type: Boolean,
|
||||
@@ -73,7 +73,7 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
})
|
||||
accessor status: 'normal' | 'pending' | 'success' | 'error' = 'normal';
|
||||
|
||||
public windowLayer: DeesWindowLayer;
|
||||
public windowLayer!: DeesWindowLayer;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -189,7 +189,7 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
}
|
||||
if (this.manifested) {
|
||||
await this.updatePosition();
|
||||
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '1';
|
||||
(this.shadowRoot!.querySelector('.maincontainer') as HTMLElement).style.opacity = '1';
|
||||
} else {
|
||||
// lets make sure we instrument it
|
||||
let speechbubble: DeesSpeechbubble;
|
||||
@@ -227,7 +227,7 @@ export class DeesSpeechbubble extends DeesElement {
|
||||
public async show() {}
|
||||
|
||||
public async destroy() {
|
||||
(this.shadowRoot.querySelector('.maincontainer') as HTMLElement).style.opacity = '0';
|
||||
(this.shadowRoot!.querySelector('.maincontainer') as HTMLElement).style.opacity = '0';
|
||||
this.windowLayer.destroy();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,7 +132,7 @@ export class WebContainerEnvironment implements IExecutionEnvironment {
|
||||
const watcher = this.container!.fs.watch(
|
||||
path,
|
||||
{ recursive: options?.recursive ?? false },
|
||||
callback
|
||||
callback as (event: 'rename' | 'change', filename: string | Uint8Array) => void
|
||||
);
|
||||
return {
|
||||
stop: () => watcher.close(),
|
||||
|
||||
@@ -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) => {
|
||||
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: 'ipad', element: 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: '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 as DeesShoppingProductcard | null, data: { name: 'iPad Air', category: 'Tablets', description: '10.9" Liquid Retina display', price: 599, iconName: 'lucide:tablet' }},
|
||||
{ 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 = () => {
|
||||
let total = 0;
|
||||
const items = [];
|
||||
const items: string[] = [];
|
||||
|
||||
products.forEach(product => {
|
||||
const element = elementArg.querySelector(`#${product.id}`) as DeesShoppingProductcard;
|
||||
@@ -216,8 +216,8 @@ export const demoFunc = () => html`
|
||||
const output = document.querySelector('#selection-output');
|
||||
if (output) {
|
||||
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
|
||||
const selectedProducts = [];
|
||||
selectedCards.forEach((card: DeesShoppingProductcard) => {
|
||||
const selectedProducts: string[] = [];
|
||||
(selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
|
||||
if (card.selected) {
|
||||
selectedProducts.push(card.productData.name);
|
||||
}
|
||||
@@ -243,8 +243,8 @@ export const demoFunc = () => html`
|
||||
const output = document.querySelector('#selection-output');
|
||||
if (output) {
|
||||
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
|
||||
const selectedProducts = [];
|
||||
selectedCards.forEach((card: DeesShoppingProductcard) => {
|
||||
const selectedProducts: string[] = [];
|
||||
(selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
|
||||
if (card.selected) {
|
||||
selectedProducts.push(card.productData.name);
|
||||
}
|
||||
@@ -271,8 +271,8 @@ export const demoFunc = () => html`
|
||||
const output = document.querySelector('#selection-output');
|
||||
if (output) {
|
||||
const selectedCards = document.querySelectorAll('dees-shopping-productcard[selectable]');
|
||||
const selectedProducts = [];
|
||||
selectedCards.forEach((card: DeesShoppingProductcard) => {
|
||||
const selectedProducts: string[] = [];
|
||||
(selectedCards as NodeListOf<DeesShoppingProductcard>).forEach((card) => {
|
||||
if (card.selected) {
|
||||
selectedProducts.push(card.productData.name);
|
||||
}
|
||||
|
||||
@@ -46,7 +46,7 @@ export class DeesSimpleAppDash extends DeesElement {
|
||||
accessor terminalSetupCommand: string = `echo "Terminal ready"`;
|
||||
|
||||
@state()
|
||||
accessor selectedView: IView;
|
||||
accessor selectedView!: IView;
|
||||
|
||||
|
||||
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;
|
||||
super.firstUpdated(_changedProperties);
|
||||
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() {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
if (this.currentTerminal) {
|
||||
@@ -404,7 +404,7 @@ export class DeesSimpleAppDash extends DeesElement {
|
||||
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 terminal = new DeesWorkspaceTerminal();
|
||||
terminal.setupCommand = this.terminalSetupCommand;
|
||||
@@ -444,9 +444,9 @@ export class DeesSimpleAppDash extends DeesElement {
|
||||
}
|
||||
|
||||
|
||||
private currentView: DeesElement;
|
||||
private currentView!: DeesElement;
|
||||
public async loadView(viewArg: IView) {
|
||||
const appcontent = this.shadowRoot.querySelector('.appcontent');
|
||||
const appcontent = this.shadowRoot!.querySelector('.appcontent')!;
|
||||
const view = new viewArg.element();
|
||||
if (this.currentView) {
|
||||
this.currentView.remove();
|
||||
|
||||
@@ -141,15 +141,15 @@ export class DeesSimpleLogin extends DeesElement {
|
||||
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>): Promise<void> {
|
||||
super.firstUpdated(_changedProperties);
|
||||
|
||||
const form = this.shadowRoot.querySelector('dees-form') as any;
|
||||
const form = this.shadowRoot!.querySelector('dees-form') as any;
|
||||
if (form) {
|
||||
form.addEventListener('formData', (event: CustomEvent) => {
|
||||
form.addEventListener('formData', ((event: CustomEvent) => {
|
||||
this.dispatchEvent(new CustomEvent('login', {
|
||||
detail: event.detail,
|
||||
bubbles: true,
|
||||
composed: true
|
||||
}));
|
||||
});
|
||||
}) as EventListener);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -158,9 +158,9 @@ export class DeesSimpleLogin extends DeesElement {
|
||||
*/
|
||||
public async switchToSlottedContent() {
|
||||
const domtools = await this.domtoolsPromise;
|
||||
const loginDiv: HTMLDivElement = this.shadowRoot.querySelector('.login');
|
||||
const loginContainerDiv: HTMLDivElement = this.shadowRoot.querySelector('.loginContainer');
|
||||
const slotContainerDiv: HTMLDivElement = this.shadowRoot.querySelector('.slotContainer');
|
||||
const loginDiv = this.shadowRoot!.querySelector('.login') as HTMLDivElement;
|
||||
const loginContainerDiv = this.shadowRoot!.querySelector('.loginContainer') as HTMLDivElement;
|
||||
const slotContainerDiv = this.shadowRoot!.querySelector('.slotContainer') as HTMLDivElement;
|
||||
loginDiv.style.opacity = '0';
|
||||
loginDiv.style.transform = 'translateY(20px)';
|
||||
loginContainerDiv.style.pointerEvents = 'none';
|
||||
|
||||
@@ -15,7 +15,7 @@ export const demoFunc = () => {
|
||||
.filter(key => {
|
||||
// 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 isFunction = typeof lucideIcons[key] === 'function';
|
||||
const isFunction = typeof (lucideIcons as any)[key] === 'function';
|
||||
const notUtility = !['createElement', 'createIcons', 'default'].includes(key);
|
||||
return isFunction && isUppercaseFirst && notUtility;
|
||||
})
|
||||
@@ -63,7 +63,7 @@ export const demoFunc = () => {
|
||||
const searchIcons = (event: InputEvent) => {
|
||||
const searchTerm = (event.target as HTMLInputElement).value.toLowerCase().trim();
|
||||
// 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');
|
||||
|
||||
containers.forEach(container => {
|
||||
@@ -79,7 +79,7 @@ export const demoFunc = () => {
|
||||
});
|
||||
|
||||
// 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 countElement = section.querySelector('.icon-count');
|
||||
if (countElement) {
|
||||
|
||||
@@ -208,7 +208,7 @@ export class DeesIcon extends DeesElement {
|
||||
accessor icon: IconWithPrefix | undefined = undefined;
|
||||
|
||||
@property({ type: Number })
|
||||
accessor iconSize: number;
|
||||
accessor iconSize!: number;
|
||||
|
||||
@property({ type: String })
|
||||
accessor color: string = 'currentColor';
|
||||
@@ -292,13 +292,13 @@ export class DeesIcon extends DeesElement {
|
||||
const pascalCaseName = iconName.charAt(0).toUpperCase() + iconName.slice(1);
|
||||
|
||||
// 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`);
|
||||
return '';
|
||||
}
|
||||
|
||||
|
||||
// Use the exact pattern from Lucide documentation
|
||||
const svgElement = createElement(lucideIcons[pascalCaseName], {
|
||||
const svgElement = createElement((lucideIcons as any)[pascalCaseName], {
|
||||
color: this.color,
|
||||
size: this.iconSize,
|
||||
strokeWidth: this.strokeWidth
|
||||
@@ -404,9 +404,9 @@ export class DeesIcon extends DeesElement {
|
||||
// Convert to PascalCase
|
||||
const pascalCaseName = name.charAt(0).toUpperCase() + name.slice(1);
|
||||
|
||||
if (lucideIcons[pascalCaseName]) {
|
||||
if ((lucideIcons as any)[pascalCaseName]) {
|
||||
// Use the documented pattern from Lucide docs
|
||||
const svgElement = createElement(lucideIcons[pascalCaseName], {
|
||||
const svgElement = createElement((lucideIcons as any)[pascalCaseName], {
|
||||
color: this.color,
|
||||
size: this.iconSize,
|
||||
strokeWidth: this.strokeWidth
|
||||
|
||||
@@ -33,12 +33,12 @@ export class DeesUpdater extends DeesElement {
|
||||
@property({
|
||||
type: String,
|
||||
})
|
||||
accessor currentVersion: string;
|
||||
accessor currentVersion!: string;
|
||||
|
||||
@property({
|
||||
type: String,
|
||||
})
|
||||
accessor updatedVersion: string;
|
||||
accessor updatedVersion!: string;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
@@ -107,7 +107,7 @@ export class DeesUpdater extends DeesElement {
|
||||
}
|
||||
|
||||
public async destroy() {
|
||||
this.parentElement.removeChild(this);
|
||||
this.parentElement!.removeChild(this);
|
||||
}
|
||||
|
||||
private windowLayerClicked() {}
|
||||
|
||||
@@ -447,7 +447,7 @@ export class DeesWorkspaceFiletree extends DeesElement {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
const menuItems = [];
|
||||
const menuItems: Array<{ name?: string; iconName?: string; action?: () => Promise<void>; divider?: boolean }> = [];
|
||||
|
||||
if (node.type === 'directory') {
|
||||
// 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) {
|
||||
@@ -561,14 +561,14 @@ export class DeesWorkspaceFiletree extends DeesElement {
|
||||
menuOptions: [
|
||||
{
|
||||
name: 'Cancel',
|
||||
action: async (modalRef) => {
|
||||
action: async (modalRef: any) => {
|
||||
await modalRef.destroy();
|
||||
resolve(null);
|
||||
},
|
||||
},
|
||||
{
|
||||
name: options.buttonName || 'Create',
|
||||
action: async (modalRef) => {
|
||||
action: async (modalRef: any) => {
|
||||
// Query the input element directly and read its value
|
||||
const contentEl = modalRef.shadowRoot?.querySelector('.modal .content');
|
||||
const inputElement = contentEl?.querySelector('dees-input-text') as DeesInputText | null;
|
||||
|
||||
@@ -129,8 +129,8 @@ export class DeesWorkspaceMarkdown extends DeesElement {
|
||||
@state()
|
||||
accessor isDragging: boolean = false;
|
||||
|
||||
private resizeHandleElement: HTMLElement;
|
||||
private containerElement: HTMLElement;
|
||||
private resizeHandleElement!: HTMLElement;
|
||||
private containerElement!: HTMLElement;
|
||||
|
||||
public render() {
|
||||
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);
|
||||
|
||||
// Initialize current ratio from property
|
||||
this.currentSplitRatio = this.splitRatio;
|
||||
|
||||
// Cache elements
|
||||
this.containerElement = this.shadowRoot.querySelector('.splitContainer');
|
||||
this.resizeHandleElement = this.shadowRoot.querySelector('.resizeHandle');
|
||||
this.containerElement = this.shadowRoot!.querySelector('.splitContainer')!;
|
||||
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
|
||||
const markdownOutlet = this.shadowRoot.querySelector('dees-workspace-markdownoutlet');
|
||||
const markdownOutlet = this.shadowRoot!.querySelector('dees-workspace-markdownoutlet');
|
||||
const smartmarkdownInstance = new domtools.plugins.smartmarkdown.SmartMarkdown();
|
||||
const mdParsedResult = await smartmarkdownInstance.getMdParsedResultFromMarkdown('loading...')
|
||||
editor.contentSubject.subscribe(async contentArg => {
|
||||
await mdParsedResult.updateFromMarkdownString(contentArg)
|
||||
const html = mdParsedResult.html;
|
||||
markdownOutlet.updateHtmlText(html);
|
||||
markdownOutlet!.updateHtmlText(html);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -226,7 +226,7 @@ const hello = 'yes'
|
||||
document.removeEventListener('mouseup', this.handleMouseUp);
|
||||
|
||||
// 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) {
|
||||
// Monaco needs to be notified of size changes
|
||||
window.dispatchEvent(new Event('resize'));
|
||||
|
||||
@@ -381,7 +381,7 @@ export class DeesWorkspaceMarkdownoutlet extends DeesElement {
|
||||
];
|
||||
|
||||
// INSTANCE
|
||||
private outlet: HTMLElement;
|
||||
private outlet!: HTMLElement;
|
||||
|
||||
public render(): TemplateResult {
|
||||
return html`
|
||||
@@ -394,13 +394,13 @@ export class DeesWorkspaceMarkdownoutlet extends DeesElement {
|
||||
|
||||
public async firstUpdated(_changedProperties: Map<string | number | symbol, unknown>) {
|
||||
await super.firstUpdated(_changedProperties);
|
||||
this.outlet = this.shadowRoot.querySelector('.outlet');
|
||||
this.outlet = this.shadowRoot!.querySelector('.outlet')!;
|
||||
}
|
||||
|
||||
public async updateHtmlText(htmlTextArg: string) {
|
||||
await this.updateComplete;
|
||||
if (!this.outlet) {
|
||||
this.outlet = this.shadowRoot.querySelector('.outlet');
|
||||
this.outlet = this.shadowRoot!.querySelector('.outlet')!;
|
||||
}
|
||||
this.outlet.innerHTML = htmlTextArg;
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ export class DeesWorkspaceMonaco extends DeesElement {
|
||||
_changedProperties: Map<string | number | symbol, unknown>
|
||||
): Promise<void> {
|
||||
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}`;
|
||||
|
||||
if (!DeesWorkspaceMonaco.monacoDeferred) {
|
||||
@@ -174,7 +174,7 @@ export class DeesWorkspaceMonaco extends DeesElement {
|
||||
).text();
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.textContent = css;
|
||||
this.shadowRoot.append(styleElement);
|
||||
this.shadowRoot!.append(styleElement);
|
||||
|
||||
|
||||
// editor is setup let do the rest
|
||||
|
||||
@@ -537,15 +537,15 @@ export const zIndexShowcase = () => html`
|
||||
</p>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Cancel', action: async (modal) => modal.destroy() },
|
||||
{ name: 'Save', action: async (modal) => modal.destroy() }
|
||||
{ name: 'Cancel', action: async (modal) => modal!.destroy() },
|
||||
{ name: 'Save', action: async (modal) => modal!.destroy() }
|
||||
]
|
||||
});
|
||||
|
||||
// Add context menu to modal content
|
||||
const modalContent = modal.shadowRoot.querySelector('.modal .content');
|
||||
const modalContent = modal!.shadowRoot!.querySelector('.modal .content');
|
||||
if (modalContent) {
|
||||
modalContent.addEventListener('contextmenu', async (e: MouseEvent) => {
|
||||
(modalContent as HTMLElement).addEventListener('contextmenu', async (e: MouseEvent) => {
|
||||
DeesContextmenu.openContextMenuWithOptions(e, [
|
||||
{ name: 'Context menu in modal', iconName: 'check', action: async () => {} },
|
||||
{ divider: true },
|
||||
@@ -607,7 +607,7 @@ export const zIndexShowcase = () => html`
|
||||
></dees-input-dropdown>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Close', action: async (modal) => modal.destroy() }
|
||||
{ name: 'Close', action: async (modal) => modal!.destroy() }
|
||||
]
|
||||
});
|
||||
}}>Show Second Modal</dees-button>
|
||||
@@ -615,7 +615,7 @@ export const zIndexShowcase = () => html`
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Close All', action: async (modal) => {
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
// Also show a toast
|
||||
DeesToast.createAndShow({ message: 'All modals closed!', type: 'info' });
|
||||
}}
|
||||
@@ -694,10 +694,10 @@ export const zIndexShowcase = () => html`
|
||||
</div>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Cancel', action: async (modal) => modal.destroy() },
|
||||
{ name: 'Cancel', action: async (modal) => modal!.destroy() },
|
||||
{ name: 'Save', action: async (modal) => {
|
||||
DeesToast.createAndShow({ message: 'Document saved!', type: 'success' });
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
}}
|
||||
]
|
||||
});
|
||||
@@ -735,10 +735,10 @@ export const zIndexShowcase = () => html`
|
||||
</dees-form>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Cancel', action: async (modal) => modal.destroy() },
|
||||
{ name: 'Cancel', action: async (modal) => modal!.destroy() },
|
||||
{ name: 'Apply', action: async (modal) => {
|
||||
DeesToast.createAndShow({ message: 'Tags applied!', type: 'success' });
|
||||
modal.destroy();
|
||||
modal!.destroy();
|
||||
}}
|
||||
]
|
||||
});
|
||||
@@ -766,7 +766,7 @@ export const zIndexShowcase = () => html`
|
||||
></dees-input-dropdown>
|
||||
`,
|
||||
menuOptions: [
|
||||
{ name: 'Exit Fullscreen', action: async (modal) => modal.destroy() }
|
||||
{ name: 'Exit Fullscreen', action: async (modal) => modal!.destroy() }
|
||||
]
|
||||
});
|
||||
}}>Open Fullscreen</dees-button>
|
||||
|
||||
@@ -228,7 +228,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
|
||||
const module = await import(/* @vite-ignore */ url);
|
||||
|
||||
this.highlightJsLib = module.default;
|
||||
return this.highlightJsLib;
|
||||
return this.highlightJsLib!;
|
||||
})();
|
||||
|
||||
return this.highlightJsLoadingPromise;
|
||||
@@ -252,7 +252,7 @@ body > div[style*="top: -50000px"][style*="width: 50000px"] {
|
||||
const module = await import(/* @vite-ignore */ url);
|
||||
|
||||
this.apexChartsLib = module.default;
|
||||
return this.apexChartsLib;
|
||||
return this.apexChartsLib!;
|
||||
})();
|
||||
|
||||
return this.apexChartsLoadingPromise;
|
||||
|
||||
@@ -7,7 +7,7 @@ export const CDN_VERSIONS = {
|
||||
xtermAddonFit: '0.8.0',
|
||||
xtermAddonSearch: '0.13.0',
|
||||
highlightJs: '11.11.1',
|
||||
apexcharts: '5.10.3',
|
||||
apexcharts: '5.10.4',
|
||||
tiptap: '2.27.2',
|
||||
fontawesome: '7.2.0',
|
||||
} as const;
|
||||
|
||||
@@ -5,7 +5,8 @@
|
||||
"moduleResolution": "NodeNext",
|
||||
"esModuleInterop": true,
|
||||
"verbatimModuleSyntax": true,
|
||||
"skipLibCheck": false
|
||||
"skipLibCheck": false,
|
||||
"types": ["node"]
|
||||
},
|
||||
"exclude": [
|
||||
"dist_*/**/*.d.ts"
|
||||
|
||||
Reference in New Issue
Block a user