Compare commits

...

4 Commits

Author SHA1 Message Date
69840de3a6 v3.41.0
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-01-27 12:36:46 +00:00
85badfbd21 feat(docs): document new media & tile components and expand Workspace/IDE component docs; update component count to 90+ 2026-01-27 12:36:46 +00:00
264e460365 v3.40.0
Some checks failed
Default (tags) / security (push) Failing after 1s
Default (tags) / test (push) Failing after 1s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2026-01-27 11:36:24 +00:00
bfda6b75e7 feat(dees-tile): unify tile badge styling and markup; replace component-specific badge classes with shared tile-badge classes and update related imports/tests 2026-01-27 11:36:24 +00:00
19 changed files with 314 additions and 157 deletions

View File

@@ -1,5 +1,23 @@
# Changelog # Changelog
## 2026-01-27 - 3.41.0 - feat(docs)
document new media & tile components and expand Workspace/IDE component docs; update component count to 90+
- Updated README component count from 70+ to 90+.
- Added Media & Tile components documentation (DeesTilePdf, DeesTileImage, DeesTileAudio, DeesTileVideo, DeesTileNote, DeesTileFolder, DeesPreview, DeesPdfViewer, DeesImageViewer, DeesAudioViewer, DeesVideoViewer).
- Expanded Workspace/IDE documentation and introduced workspace subcomponents (DeesWorkspace, DeesWorkspaceMonaco, DeesWorkspaceDiffEditor, DeesWorkspaceFiletree, DeesWorkspaceTerminal, DeesWorkspaceTerminalPreview, DeesWorkspaceMarkdown, DeesWorkspaceMarkdownoutlet, DeesWorkspaceBottombar).
- Enhanced Contextmenu docs to demonstrate nested submenus and programmatic API usage.
- Added ITileFolderItem interface example for tile folder items.
## 2026-01-27 - 3.40.0 - feat(dees-tile)
unify tile badge styling and markup; replace component-specific badge classes with shared tile-badge classes and update related imports/tests
- Add shared badge styles: .tile-badge-corner, .tile-badge-topright, .tile-badge and layout rules in dees-tile-shared/styles.ts
- Update tile components (audio, video, image, folder, note, pdf) to use new badge markup and remove duplicated badge CSS
- Shift badge positioning when a tile label is present (.tile-container:has(.tile-label))
- Remove older per-component badge rules (duration-badge, item-count-badge, dimension-badge, note-language/note-line-indicator, preview-page-indicator) and replace with unified classes
- Update tests to import dees-contextmenu and dees-dashboardgrid from new 00group-overlay / 00group-layout paths to reflect folder reorganization
## 2026-01-27 - 3.39.1 - fix(dees-tile-note) ## 2026-01-27 - 3.39.1 - fix(dees-tile-note)
use horizontal pointer position to scroll note body by computing percentage from clientX and element width instead of clientY and height use horizontal pointer position to scroll note body by computing percentage from clientX and element width instead of clientY and height

View File

@@ -1,6 +1,6 @@
{ {
"name": "@design.estate/dees-catalog", "name": "@design.estate/dees-catalog",
"version": "3.39.1", "version": "3.41.0",
"private": false, "private": false,
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.", "description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
"main": "dist_ts_web/index.js", "main": "dist_ts_web/index.js",

274
readme.md
View File

@@ -1,6 +1,6 @@
# @design.estate/dees-catalog # @design.estate/dees-catalog
A comprehensive web components library built with TypeScript and LitElement, providing **70+ production-ready UI components** for building modern web applications with consistent design and behavior. 🚀 A comprehensive web components library built with TypeScript and LitElement, providing **90+ production-ready UI components** for building modern web applications with consistent design and behavior. 🚀
[![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/) [![TypeScript](https://img.shields.io/badge/TypeScript-5.0+-blue.svg)](https://www.typescriptlang.org/)
[![LitElement](https://img.shields.io/badge/LitElement-4.0+-orange.svg)](https://lit.dev/) [![LitElement](https://img.shields.io/badge/LitElement-4.0+-orange.svg)](https://lit.dev/)
@@ -18,6 +18,8 @@ For reporting bugs, issues, or security vulnerabilities, please visit [community
- 🔧 **TypeScript-First** — Fully typed APIs with excellent IDE support - 🔧 **TypeScript-First** — Fully typed APIs with excellent IDE support
- 🧩 **Modular** — Use only what you need, tree-shakeable architecture - 🧩 **Modular** — Use only what you need, tree-shakeable architecture
- 🏗️ **Full App Shell**`dees-appui` provides a complete application framework with menus, routing, activity log, and bottom bar - 🏗️ **Full App Shell**`dees-appui` provides a complete application framework with menus, routing, activity log, and bottom bar
- 🎬 **Media Components** — Rich tile-based previews for PDFs, images, audio, video, notes, and folders
- 💻 **IDE Workspace** — Full workspace component with Monaco editor, file tree, terminal, and diff viewer
## 📦 Installation ## 📦 Installation
@@ -55,12 +57,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) | | **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) | | **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) | | **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) |
| **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) | | **Visualization** | [`DeesChartArea`](#deeschartarea), [`DeesChartLog`](#deeschartlog) |
| **Dialogs & Overlays** | [`DeesModal`](#deesmodal), [`DeesContextmenu`](#deescontextmenu), [`DeesSpeechbubble`](#deesspeechbubble), [`DeesWindowlayer`](#deeswindowlayer) | | **Dialogs & Overlays** | [`DeesModal`](#deesmodal), [`DeesContextmenu`](#deescontextmenu), [`DeesSpeechbubble`](#deesspeechbubble), [`DeesWindowlayer`](#deeswindowlayer) |
| **Navigation** | [`DeesStepper`](#deesstepper), [`DeesProgressbar`](#deesprogressbar) | | **Navigation** | [`DeesStepper`](#deesstepper), [`DeesProgressbar`](#deesprogressbar) |
| **Workspace / IDE** | [`DeesEditor`](#deeseditor), [`DeesTerminal`](#deesterminal), [`DeesUpdater`](#deesupdater) | | **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) |
| **Pre-built Templates** | [`DeesSimpleAppdash`](#deessimpleappdash), [`DeesSimpleLogin`](#deessimplelogin) | | **Pre-built Templates** | [`DeesSimpleAppdash`](#deessimpleappdash), [`DeesSimpleLogin`](#deessimplelogin) |
| **Shopping** | [`DeesShoppingProductcard`](#deesshoppingproductcard) | | **Shopping** | [`DeesShoppingProductcard`](#deesshoppingproductcard) |
@@ -1234,6 +1237,146 @@ Pagination component for navigating through large datasets.
--- ---
### Media & Tile Components 🎬
A rich collection of tile-based preview components for displaying media files in grids. All tiles share a consistent base class (`DeesTileBase`) with lazy loading via `IntersectionObserver`, hover interactions, click events, context menus, and three size variants (`small`, `default`, `large`).
All tile badges use a unified styling system with label-awareness — when a `label` is set, bottom badges automatically shift up to avoid overlapping.
#### `DeesTilePdf`
PDF document tile with live page preview on hover.
```typescript
<dees-tile-pdf
pdfUrl="/documents/report.pdf"
label="Annual Report"
clickable
@tile-click=${handleClick}
></dees-tile-pdf>
```
**Key Features:**
- Renders first page as canvas preview
- Hover to scrub through pages (mouse X position maps to page number)
- Shows page count badge, hover page indicator
- Detects A4/Letter vs non-standard aspect ratios
#### `DeesTileImage`
Image tile with lazy loading and dimension display.
```typescript
<dees-tile-image
src="/photos/landscape.jpg"
alt="Mountain landscape"
label="landscape.jpg"
clickable
@tile-click=${handleClick}
></dees-tile-image>
```
**Key Features:**
- Lazy loads image on scroll into view
- Shows image dimensions on hover (e.g. "1920 × 1080")
- Checkerboard background for transparent images
#### `DeesTileAudio`
Audio file tile with waveform visualization.
```typescript
<dees-tile-audio
src="/music/track.mp3"
title="Summer Vibes"
artist="DJ Example"
clickable
@tile-click=${handleClick}
></dees-tile-audio>
```
**Key Features:**
- Generates waveform visualization from audio data
- Shows duration badge (e.g. "3:42")
- Displays title and artist metadata
- Play overlay on hover
#### `DeesTileVideo`
Video tile with thumbnail capture and hover preview.
```typescript
<dees-tile-video
src="/videos/intro.mp4"
poster="/thumbs/intro.jpg"
label="Introduction"
clickable
@tile-click=${handleClick}
></dees-tile-video>
```
**Key Features:**
- Auto-captures first frame as thumbnail (or uses provided `poster`)
- Plays video preview on hover
- Shows duration badge
- Play button overlay
#### `DeesTileNote`
Code/text snippet tile with syntax-aware display.
```typescript
<dees-tile-note
title="config.ts"
language="TypeScript"
.content=${codeString}
clickable
@tile-click=${handleClick}
></dees-tile-note>
```
**Key Features:**
- Monospace font with line numbers
- Language badge (top-right)
- Scrollable content on hover (mouse X position controls scroll)
- Line indicator badge while scrolling
- Gradient fade at bottom
#### `DeesTileFolder`
Folder tile with 2×2 content preview grid.
```typescript
<dees-tile-folder
name="Project Assets"
.items=${[
{ type: 'image', name: 'logo.png', thumbnailSrc: '/thumbs/logo.png' },
{ type: 'pdf', name: 'spec.pdf' },
{ type: 'audio', name: 'jingle.mp3' },
{ type: 'video', name: 'demo.mp4' },
]}
clickable
@tile-click=${handleClick}
></dees-tile-folder>
```
**Key Features:**
- 2×2 preview grid showing first 4 items (thumbnails or type icons)
- Item count badge (e.g. "12 items")
- Folder icon header with name
- Supports: `pdf`, `image`, `audio`, `video`, `note`, `folder`, `unknown` types
#### `DeesPreview`
Unified preview component that auto-selects the right tile type based on content.
#### `DeesPdfViewer` / `DeesPdfPreview`
Full PDF viewing components with navigation controls.
#### `DeesImageViewer`
Full-screen image viewer with zoom and pan.
#### `DeesAudioViewer`
Audio playback component with waveform and controls.
#### `DeesVideoViewer`
Video playback component with standard controls.
---
### Visualization Components ### Visualization Components
#### `DeesChartArea` #### `DeesChartArea`
@@ -1294,16 +1437,41 @@ DeesModal.createAndShow({
``` ```
#### `DeesContextmenu` #### `DeesContextmenu`
Context menu component for right-click actions. Context menu component for right-click actions with nested submenu support.
```typescript ```typescript
<dees-contextmenu // Programmatic usage
.items=${[ DeesContextmenu.openContextMenuWithOptions(mouseEvent, [
{ label: 'Edit', icon: 'edit', action: () => handleEdit() }, {
{ label: 'Delete', icon: 'trash', action: () => handleDelete() } name: 'Edit',
]} iconName: 'lucide:edit',
position="right" action: async () => handleEdit()
></dees-contextmenu> },
{ divider: true },
{
name: 'More Options',
iconName: 'lucide:moreHorizontal',
submenu: [
{ name: 'Duplicate', iconName: 'lucide:copy', action: async () => handleDuplicate() },
{ name: 'Archive', iconName: 'lucide:archive', action: async () => handleArchive() },
]
},
{
name: 'Delete',
iconName: 'lucide:trash2',
action: async () => handleDelete()
}
]);
// Component-based (implement getContextMenuItems on any element)
class MyComponent extends DeesElement {
getContextMenuItems() {
return [
{ name: 'View Details', iconName: 'lucide:eye', action: async () => { ... } },
{ name: 'Edit', iconName: 'lucide:edit', action: async () => { ... } },
];
}
}
``` ```
#### `DeesSpeechbubble` #### `DeesSpeechbubble`
@@ -1395,51 +1563,68 @@ Theme provider component that wraps children and provides CSS custom properties
--- ---
### Workspace / IDE Components ### Workspace / IDE Components 💻
#### `DeesEditor` A full-featured IDE workspace component suite for building browser-based code editors, terminal interfaces, and documentation viewers.
Code editor component with syntax highlighting and code completion, powered by Monaco Editor.
#### `DeesWorkspace`
Top-level workspace shell that composes editor, file tree, terminal, and bottom bar into an IDE-like layout.
```typescript ```typescript
<dees-editor <dees-workspace></dees-workspace>
```
#### `DeesWorkspaceMonaco`
Monaco Editor integration for code editing with full IntelliSense, syntax highlighting, and language support.
```typescript
<dees-workspace-monaco
.value=${code} .value=${code}
@change=${handleCodeChange}
.language=${'typescript'} .language=${'typescript'}
.theme=${'vs-dark'} @change=${handleCodeChange}
.options=${{ ></dees-workspace-monaco>
lineNumbers: true,
minimap: { enabled: true },
autoClosingBrackets: 'always'
}}
></dees-editor>
``` ```
#### `DeesTerminal` #### `DeesWorkspaceDiffEditor`
Terminal emulator component for command-line interface. Side-by-side diff editor powered by Monaco for comparing file versions.
```typescript ```typescript
<dees-terminal <dees-workspace-diff-editor
.commands=${{ .originalValue=${originalCode}
'echo': (args) => `Echo: ${args.join(' ')}`, .modifiedValue=${modifiedCode}
'help': () => 'Available commands: echo, help' .language=${'typescript'}
}} ></dees-workspace-diff-editor>
.prompt=${'$'}
.welcomeMessage=${'Welcome! Type "help" for available commands.'}
></dees-terminal>
``` ```
#### `DeesUpdater` #### `DeesWorkspaceFiletree`
Component for managing application updates and version control. File tree navigation component with expand/collapse, file icons, and selection.
```typescript ```typescript
<dees-updater <dees-workspace-filetree
.currentVersion=${'1.5.2'} .files=${fileTreeData}
.checkInterval=${3600000} @file-select=${handleFileSelect}
.autoUpdate=${false} ></dees-workspace-filetree>
@update-available=${handleUpdateAvailable}
></dees-updater>
``` ```
#### `DeesWorkspaceTerminal`
Terminal emulator component powered by xterm.js.
```typescript
<dees-workspace-terminal></dees-workspace-terminal>
```
#### `DeesWorkspaceTerminalPreview`
Terminal with integrated preview pane for output visualization.
#### `DeesWorkspaceMarkdown`
Markdown editor with live preview.
#### `DeesWorkspaceMarkdownoutlet`
Read-only markdown renderer for documentation display.
#### `DeesWorkspaceBottombar`
IDE-style bottom status bar for the workspace.
--- ---
### Pre-built Templates ### Pre-built Templates
@@ -1582,6 +1767,13 @@ interface IViewActivationContext {
viewId: string; viewId: string;
params?: Record<string, string>; params?: Record<string, string>;
} }
// Tile folder item (for DeesTileFolder)
interface ITileFolderItem {
type: 'pdf' | 'image' | 'audio' | 'video' | 'note' | 'folder' | 'unknown';
thumbnailSrc?: string;
name: string;
}
``` ```
--- ---

View File

@@ -1,6 +1,6 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
import { demoFunc } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.demo.js'; import { demoFunc } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.demo.js';
tap.test('should render context menu demo', async () => { tap.test('should render context menu demo', async () => {
// Create demo container // Create demo container

View File

@@ -1,5 +1,5 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
tap.test('should close all parent menus when clicking action in nested submenu', async () => { tap.test('should close all parent menus when clicking action in nested submenu', async () => {
let actionCalled = false; let actionCalled = false;

View File

@@ -1,5 +1,5 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
import { DeesElement, customElement, html } from '@design.estate/dees-element'; import { DeesElement, customElement, html } from '@design.estate/dees-element';
// Create a test element with shadow DOM // Create a test element with shadow DOM

View File

@@ -1,5 +1,5 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
tap.test('should show context menu with nested submenu', async () => { tap.test('should show context menu with nested submenu', async () => {
// Create a test element with context menu items // Create a test element with context menu items

View File

@@ -3,8 +3,8 @@ import { tap, expect } from '@git.zone/tstest/tapbundle';
import { import {
resolveWidgetPlacement, resolveWidgetPlacement,
collectCollisions, collectCollisions,
} from '../ts_web/elements/dees-dashboardgrid/layout.ts'; } from '../ts_web/elements/00group-layout/dees-dashboardgrid/layout.ts';
import type { DashboardWidget } from '../ts_web/elements/dees-dashboardgrid/types.ts'; import type { DashboardWidget } from '../ts_web/elements/00group-layout/dees-dashboardgrid/types.ts';
tap.test('dashboardgrid does not overlap widgets after swap attempt', async () => { tap.test('dashboardgrid does not overlap widgets after swap attempt', async () => {
const widgets: DashboardWidget[] = [ const widgets: DashboardWidget[] = [

View File

@@ -1,6 +1,6 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesInputWysiwyg } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.js'; import { DeesInputWysiwyg } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.js';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
tap.test('should change block type via context menu', async () => { tap.test('should change block type via context menu', async () => {
// Create WYSIWYG editor with a paragraph // Create WYSIWYG editor with a paragraph

View File

@@ -1,6 +1,6 @@
import { expect, tap } from '@git.zone/tstest/tapbundle'; import { expect, tap } from '@git.zone/tstest/tapbundle';
import { DeesInputWysiwyg } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.js'; import { DeesInputWysiwyg } from '../ts_web/elements/00group-input/dees-input-wysiwyg/dees-input-wysiwyg.js';
import { DeesContextmenu } from '../ts_web/elements/dees-contextmenu/dees-contextmenu.js'; import { DeesContextmenu } from '../ts_web/elements/00group-overlay/dees-contextmenu/dees-contextmenu.js';
tap.test('should show context menu on WYSIWYG blocks', async () => { tap.test('should show context menu on WYSIWYG blocks', async () => {
// Create WYSIWYG editor // Create WYSIWYG editor

View File

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

View File

@@ -84,20 +84,6 @@ export class DeesTileAudio extends DeesTileBase {
display: block; display: block;
} }
.duration-badge {
position: absolute;
bottom: 8px;
right: 8px;
padding: 3px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.6)', 'hsl(0 0% 100% / 0.85)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 10px;
font-weight: 600;
font-variant-numeric: tabular-nums;
backdrop-filter: blur(8px);
z-index: 10;
}
.play-overlay { .play-overlay {
position: absolute; position: absolute;
@@ -177,7 +163,7 @@ export class DeesTileAudio extends DeesTileBase {
</div> </div>
${this.duration > 0 ? html` ${this.duration > 0 ? html`
<div class="duration-badge">${this.formatTime(this.duration)}</div> <div class="tile-badge-corner">${this.formatTime(this.duration)}</div>
` : ''} ` : ''}
<div class="play-overlay"> <div class="play-overlay">

View File

@@ -109,19 +109,6 @@ export class DeesTileFolder extends DeesTileBase {
background: ${cssManager.bdTheme('hsl(215 15% 96%)', 'hsl(215 20% 16%)')}; background: ${cssManager.bdTheme('hsl(215 15% 96%)', 'hsl(215 20% 16%)')};
} }
.item-count-badge {
position: absolute;
bottom: 8px;
right: 8px;
padding: 3px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.6)', 'hsl(0 0% 100% / 0.85)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 10px;
font-weight: 600;
backdrop-filter: blur(8px);
z-index: 10;
}
`, `,
] as any; ] as any;
@@ -158,7 +145,7 @@ export class DeesTileFolder extends DeesTileBase {
</div> </div>
</div> </div>
<div class="item-count-badge"> <div class="tile-badge-corner">
${this.items.length} item${this.items.length !== 1 ? 's' : ''} ${this.items.length} item${this.items.length !== 1 ? 's' : ''}
</div> </div>

View File

@@ -55,24 +55,12 @@ export class DeesTileImage extends DeesTileBase {
opacity: 0; opacity: 0;
} }
.dimension-badge { .tile-badge-topright.dimension-badge {
position: absolute;
top: 8px;
right: 8px;
padding: 3px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.6)', 'hsl(0 0% 100% / 0.85)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 10px;
font-weight: 600;
backdrop-filter: blur(8px);
z-index: 15;
pointer-events: none;
opacity: 0; opacity: 0;
transition: opacity 0.2s ease; transition: opacity 0.2s ease;
} }
.tile-container.clickable:hover .dimension-badge { .tile-container.clickable:hover .tile-badge-topright.dimension-badge {
opacity: 1; opacity: 1;
} }
`, `,
@@ -110,7 +98,7 @@ export class DeesTileImage extends DeesTileBase {
</div> </div>
${this.imageWidth > 0 && this.imageHeight > 0 ? html` ${this.imageWidth > 0 && this.imageHeight > 0 ? html`
<div class="dimension-badge"> <div class="tile-badge-topright dimension-badge">
${this.imageWidth} × ${this.imageHeight} ${this.imageWidth} × ${this.imageHeight}
</div> </div>
` : ''} ` : ''}

View File

@@ -81,16 +81,10 @@ export class DeesTileNote extends DeesTileBase {
pointer-events: none; pointer-events: none;
} }
.note-language { .tile-badge-topright.note-language {
position: absolute;
top: 8px;
right: 8px;
padding: 2px 6px;
background: ${cssManager.bdTheme('hsl(215 20% 92%)', 'hsl(215 20% 88%)')}; background: ${cssManager.bdTheme('hsl(215 20% 92%)', 'hsl(215 20% 88%)')};
color: ${cssManager.bdTheme('hsl(215 16% 50%)', 'hsl(215 16% 40%)')}; color: ${cssManager.bdTheme('hsl(215 16% 50%)', 'hsl(215 16% 40%)')};
border-radius: 3px;
font-size: 9px; font-size: 9px;
font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
z-index: 5; z-index: 5;
} }
@@ -116,21 +110,6 @@ export class DeesTileNote extends DeesTileBase {
padding-right: 6px; padding-right: 6px;
} }
.note-line-indicator {
position: absolute;
bottom: 8px;
right: 8px;
padding: 3px 8px;
background: rgba(0, 0, 0, 0.6);
color: white;
border-radius: 4px;
font-size: 9px;
font-weight: 600;
font-variant-numeric: tabular-nums;
backdrop-filter: blur(8px);
z-index: 10;
pointer-events: none;
}
`, `,
] as any; ] as any;
@@ -154,7 +133,7 @@ export class DeesTileNote extends DeesTileBase {
return html` return html`
<div class="note-content"> <div class="note-content">
${this.language ? html` ${this.language ? html`
<div class="note-language">${this.language}</div> <div class="tile-badge-topright note-language">${this.language}</div>
` : ''} ` : ''}
${this.title ? html` ${this.title ? html`
@@ -169,7 +148,7 @@ export class DeesTileNote extends DeesTileBase {
</div> </div>
${this.isHovering && lines.length > 12 ? html` ${this.isHovering && lines.length > 12 ? html`
<div class="note-line-indicator"> <div class="tile-badge-corner">
Line ${this.getVisibleLineRange(lines.length)} Line ${this.getVisibleLineRange(lines.length)}
</div> </div>
` : ''} ` : ''}

View File

@@ -55,15 +55,14 @@ export class DeesTilePdf extends DeesTileBase {
</div> </div>
${this.pageCount > 1 && this.isHovering ? html` ${this.pageCount > 1 && this.isHovering ? html`
<div class="preview-page-indicator"> <div class="tile-badge">
Page ${this.currentPreviewPage} of ${this.pageCount} Page ${this.currentPreviewPage} of ${this.pageCount}
</div> </div>
` : ''} ` : ''}
${this.pageCount > 0 && !this.isHovering ? html` ${this.pageCount > 0 && !this.isHovering ? html`
<div class="tile-info"> <div class="tile-badge-corner">
<dees-icon icon="lucide:FileText"></dees-icon> ${this.pageCount} page${this.pageCount > 1 ? 's' : ''}
<span class="tile-info-text">${this.pageCount} page${this.pageCount > 1 ? 's' : ''}</span>
</div> </div>
` : ''} ` : ''}

View File

@@ -35,24 +35,6 @@ export const tilePdfStyles = css`
border-radius: 4px; border-radius: 4px;
} }
.preview-page-indicator {
position: absolute;
top: 8px;
left: 8px;
right: 8px;
padding: 5px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.7)', 'hsl(0 0% 100% / 0.9)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 11px;
font-weight: 600;
text-align: center;
backdrop-filter: blur(12px);
z-index: 15;
pointer-events: none;
animation: fadeIn 0.2s ease;
}
/* Grid optimizations */ /* Grid optimizations */
:host([grid-mode]) .preview-canvas { :host([grid-mode]) .preview-canvas {
image-rendering: -webkit-optimize-contrast; image-rendering: -webkit-optimize-contrast;

View File

@@ -117,6 +117,46 @@ export const tileBaseStyles = [
animation: fadeIn 0.2s ease; animation: fadeIn 0.2s ease;
} }
.tile-badge-corner {
position: absolute;
bottom: 8px;
right: 8px;
padding: 3px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.6)', 'hsl(0 0% 100% / 0.85)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 10px;
font-weight: 600;
font-variant-numeric: tabular-nums;
backdrop-filter: blur(8px);
z-index: 10;
pointer-events: none;
}
.tile-badge-topright {
position: absolute;
top: 8px;
right: 8px;
padding: 3px 8px;
background: ${cssManager.bdTheme('hsl(0 0% 0% / 0.6)', 'hsl(0 0% 100% / 0.85)')};
color: ${cssManager.bdTheme('white', 'hsl(215 20% 12%)')};
border-radius: 4px;
font-size: 10px;
font-weight: 600;
backdrop-filter: blur(8px);
z-index: 15;
pointer-events: none;
}
/* Shift bottom badges up when label is present */
.tile-container:has(.tile-label) .tile-badge-corner {
bottom: 33px;
}
.tile-container:has(.tile-label) .tile-info {
bottom: 33px;
}
.tile-loading, .tile-loading,
.tile-error { .tile-error {
position: absolute; position: absolute;

View File

@@ -54,20 +54,6 @@ export class DeesTileVideo extends DeesTileBase {
display: block; display: block;
} }
.duration-badge {
position: absolute;
bottom: 8px;
right: 8px;
padding: 3px 8px;
background: rgba(0, 0, 0, 0.7);
color: white;
border-radius: 4px;
font-size: 10px;
font-weight: 600;
font-variant-numeric: tabular-nums;
backdrop-filter: blur(8px);
z-index: 10;
}
.play-overlay { .play-overlay {
position: absolute; position: absolute;
@@ -155,7 +141,7 @@ export class DeesTileVideo extends DeesTileBase {
</div> </div>
${this.duration > 0 ? html` ${this.duration > 0 ? html`
<div class="duration-badge">${this.formatTime(this.duration)}</div> <div class="tile-badge-corner">${this.formatTime(this.duration)}</div>
` : ''} ` : ''}
${!this.isHovering ? html` ${!this.isHovering ? html`