Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 1795235c6d | |||
| ba7d387acb | |||
| 26ca16a284 | |||
| 3ab3eb5e5e | |||
| da5dbc70e2 | |||
| 19b7981542 | |||
| bad105074e | |||
| f124091784 |
32
changelog.md
32
changelog.md
@@ -1,5 +1,37 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## 2026-03-09 - 3.43.4 - fix(media)
|
||||||
|
remove deprecated dees-pdf and dees-pdf-preview components and bump several dependencies
|
||||||
|
|
||||||
|
- Removed deprecated PDF components and related demos/styles: ts_web/elements/00group-media/dees-pdf/* and ts_web/elements/00group-media/dees-pdf-preview/*
|
||||||
|
- Removed exports for dees-pdf and dees-pdf-preview from ts_web/elements/00group-media/index.ts (public API removal)
|
||||||
|
- Dependency upgrades: @design.estate/dees-domtools → ^2.3.9, apexcharts → ^5.10.3, lucide → ^0.577.0, @fortawesome/* → ^7.2.0
|
||||||
|
- DevDependency upgrades: @git.zone/tsbuild → ^4.3.0, @git.zone/tsbundle → ^2.9.1, @git.zone/tstest → ^3.3.2, @git.zone/tswatch → ^3.2.5, @types/node → ^25.3.5
|
||||||
|
- Updated ts_web/services/versions.ts to align CDN/version constants (apexcharts, tiptap → 2.27.2, fontawesome)
|
||||||
|
|
||||||
|
## 2026-02-24 - 3.43.3 - fix(dees-table)
|
||||||
|
use lucide icon identifier for Search action in dees-table
|
||||||
|
|
||||||
|
- Replaced iconName 'magnifyingGlass' with 'lucide:Search' in ts_web/elements/00group-dataview/dees-table/dees-table.ts
|
||||||
|
- Updates the icon identifier for the header 'Search' action; no functional behavior changed
|
||||||
|
|
||||||
|
## 2026-02-21 - 3.43.2 - fix(dees-chart-log)
|
||||||
|
avoid duplicate log entries, optimize incremental updates, enforce maxEntries, and respect filters when writing logs
|
||||||
|
|
||||||
|
- Prevent property-bound logEntries from duplicating entries already present in logBuffer by deduplicating on timestamp|message
|
||||||
|
- Call updateMetrics() when replaying or appending log entries so metrics stay accurate
|
||||||
|
- Skip processing entirely when the incoming logEntries array is unchanged
|
||||||
|
- Optimize append-only updates by writing only the new tail entries instead of full re-render
|
||||||
|
- Enforce maxEntries when appending to the logBuffer to maintain buffer size
|
||||||
|
- Respect filterMode and searchQuery when deciding whether to write appended entries to the terminal
|
||||||
|
|
||||||
|
## 2026-02-21 - 3.43.1 - fix(dees-chart-log)
|
||||||
|
replay buffered log entries when terminal becomes ready and sync logEntries updates to re-render filtered logs
|
||||||
|
|
||||||
|
- Replay entries stored in logBuffer after terminal initialization to avoid losing entries that arrived early
|
||||||
|
- Add updated() lifecycle hook to copy logEntries into logBuffer and call reRenderFilteredLogs when terminalReady
|
||||||
|
- Call super.updated(changedProperties) to preserve base class behavior
|
||||||
|
|
||||||
## 2026-02-17 - 3.43.0 - feat(dees-form)
|
## 2026-02-17 - 3.43.0 - feat(dees-form)
|
||||||
add layout styles to dees-form and standardize demo input grouping
|
add layout styles to dees-form and standardize demo input grouping
|
||||||
|
|
||||||
|
|||||||
26
package.json
26
package.json
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "@design.estate/dees-catalog",
|
"name": "@design.estate/dees-catalog",
|
||||||
"version": "3.43.0",
|
"version": "3.43.4",
|
||||||
"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",
|
||||||
@@ -16,13 +16,13 @@
|
|||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@design.estate/dees-domtools": "^2.3.8",
|
"@design.estate/dees-domtools": "^2.3.9",
|
||||||
"@design.estate/dees-element": "^2.1.6",
|
"@design.estate/dees-element": "^2.1.6",
|
||||||
"@design.estate/dees-wcctools": "^3.8.0",
|
"@design.estate/dees-wcctools": "^3.8.0",
|
||||||
"@fortawesome/fontawesome-svg-core": "^7.1.0",
|
"@fortawesome/fontawesome-svg-core": "^7.2.0",
|
||||||
"@fortawesome/free-brands-svg-icons": "^7.1.0",
|
"@fortawesome/free-brands-svg-icons": "^7.2.0",
|
||||||
"@fortawesome/free-regular-svg-icons": "^7.1.0",
|
"@fortawesome/free-regular-svg-icons": "^7.2.0",
|
||||||
"@fortawesome/free-solid-svg-icons": "^7.1.0",
|
"@fortawesome/free-solid-svg-icons": "^7.2.0",
|
||||||
"@push.rocks/smarti18n": "^1.0.4",
|
"@push.rocks/smarti18n": "^1.0.4",
|
||||||
"@push.rocks/smartpromise": "^4.2.0",
|
"@push.rocks/smartpromise": "^4.2.0",
|
||||||
"@push.rocks/smartstring": "^4.1.0",
|
"@push.rocks/smartstring": "^4.1.0",
|
||||||
@@ -34,22 +34,22 @@
|
|||||||
"@tiptap/extension-underline": "^2.23.0",
|
"@tiptap/extension-underline": "^2.23.0",
|
||||||
"@tiptap/starter-kit": "^2.23.0",
|
"@tiptap/starter-kit": "^2.23.0",
|
||||||
"@tsclass/tsclass": "^9.3.0",
|
"@tsclass/tsclass": "^9.3.0",
|
||||||
"apexcharts": "^5.5.0",
|
"apexcharts": "^5.10.3",
|
||||||
"highlight.js": "11.11.1",
|
"highlight.js": "11.11.1",
|
||||||
"ibantools": "^4.5.1",
|
"ibantools": "^4.5.1",
|
||||||
"lucide": "^0.564.0",
|
"lucide": "^0.577.0",
|
||||||
"monaco-editor": "0.55.1",
|
"monaco-editor": "0.55.1",
|
||||||
"pdfjs-dist": "^4.10.38",
|
"pdfjs-dist": "^4.10.38",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@git.zone/tsbuild": "^4.1.2",
|
"@git.zone/tsbuild": "^4.3.0",
|
||||||
"@git.zone/tsbundle": "^2.8.3",
|
"@git.zone/tsbundle": "^2.9.1",
|
||||||
"@git.zone/tstest": "^3.1.8",
|
"@git.zone/tstest": "^3.3.2",
|
||||||
"@git.zone/tswatch": "^3.1.0",
|
"@git.zone/tswatch": "^3.2.5",
|
||||||
"@push.rocks/projectinfo": "^5.0.2",
|
"@push.rocks/projectinfo": "^5.0.2",
|
||||||
"@types/node": "^25.2.3"
|
"@types/node": "^25.3.5"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
|
|||||||
4825
pnpm-lock.yaml
generated
4825
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-catalog',
|
name: '@design.estate/dees-catalog',
|
||||||
version: '3.43.0',
|
version: '3.43.4',
|
||||||
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.'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -385,11 +385,23 @@ export class DeesChartLog extends DeesElement {
|
|||||||
this.domtoolsInstance = await this.domtoolsPromise;
|
this.domtoolsInstance = await this.domtoolsPromise;
|
||||||
await this.initializeTerminal();
|
await this.initializeTerminal();
|
||||||
|
|
||||||
// Process any initial log entries
|
// initializeTerminal() already replayed logBuffer (from addLog/updateLog).
|
||||||
if (this.logEntries.length > 0) {
|
// Now handle logEntries set via property binding before terminal was ready.
|
||||||
|
if (this.logEntries.length > 0 && this.logBuffer.length === 0) {
|
||||||
|
this.logBuffer = [...this.logEntries];
|
||||||
for (const entry of this.logEntries) {
|
for (const entry of this.logEntries) {
|
||||||
|
this.updateMetrics(entry.level);
|
||||||
this.writeLogEntry(entry);
|
this.writeLogEntry(entry);
|
||||||
}
|
}
|
||||||
|
} else if (this.logEntries.length > 0 && this.logBuffer.length > 0) {
|
||||||
|
const bufferSet = new Set(this.logBuffer.map(e => `${e.timestamp}|${e.message}`));
|
||||||
|
for (const entry of this.logEntries) {
|
||||||
|
if (!bufferSet.has(`${entry.timestamp}|${entry.message}`)) {
|
||||||
|
this.logBuffer.push(entry);
|
||||||
|
this.updateMetrics(entry.level);
|
||||||
|
this.writeLogEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -445,6 +457,58 @@ export class DeesChartLog extends DeesElement {
|
|||||||
this.rateInterval = setInterval(() => this.calculateRate(), 1000);
|
this.rateInterval = setInterval(() => this.calculateRate(), 1000);
|
||||||
|
|
||||||
this.terminalReady = true;
|
this.terminalReady = true;
|
||||||
|
|
||||||
|
// Replay any entries that arrived via updateLog()/addLog() before terminal was ready
|
||||||
|
for (const entry of this.logBuffer) {
|
||||||
|
this.writeLogEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public updated(changedProperties: Map<string, any>) {
|
||||||
|
super.updated(changedProperties);
|
||||||
|
if (changedProperties.has('logEntries') && this.terminalReady && this.logEntries.length > 0) {
|
||||||
|
const oldEntries: ILogEntry[] = changedProperties.get('logEntries') || [];
|
||||||
|
const newEntries = this.logEntries;
|
||||||
|
|
||||||
|
// Same content? Skip entirely.
|
||||||
|
if (
|
||||||
|
oldEntries.length === newEntries.length &&
|
||||||
|
oldEntries.length > 0 &&
|
||||||
|
oldEntries[oldEntries.length - 1].timestamp === newEntries[newEntries.length - 1].timestamp &&
|
||||||
|
oldEntries[oldEntries.length - 1].message === newEntries[newEntries.length - 1].message
|
||||||
|
) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Append-only? Write only the new tail entries incrementally.
|
||||||
|
if (
|
||||||
|
newEntries.length > oldEntries.length &&
|
||||||
|
oldEntries.length > 0 &&
|
||||||
|
oldEntries[oldEntries.length - 1].timestamp === newEntries[oldEntries.length - 1].timestamp &&
|
||||||
|
oldEntries[oldEntries.length - 1].message === newEntries[oldEntries.length - 1].message
|
||||||
|
) {
|
||||||
|
const tailEntries = newEntries.slice(oldEntries.length);
|
||||||
|
for (const entry of tailEntries) {
|
||||||
|
this.logBuffer.push(entry);
|
||||||
|
this.updateMetrics(entry.level);
|
||||||
|
|
||||||
|
// Enforce maxEntries
|
||||||
|
if (this.logBuffer.length > this.maxEntries) {
|
||||||
|
this.logBuffer.shift();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Respect filter mode
|
||||||
|
if (!this.filterMode || !this.searchQuery || this.entryMatchesFilter(entry)) {
|
||||||
|
this.writeLogEntry(entry);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Different content — full re-render
|
||||||
|
this.logBuffer = [...newEntries];
|
||||||
|
this.reRenderFilteredLogs();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private getTerminalTheme() {
|
private getTerminalTheme() {
|
||||||
|
|||||||
@@ -544,7 +544,7 @@ export class DeesTable<T> extends DeesElement {
|
|||||||
if (!existing) {
|
if (!existing) {
|
||||||
this.dataActions.unshift({
|
this.dataActions.unshift({
|
||||||
name: 'Search',
|
name: 'Search',
|
||||||
iconName: 'magnifyingGlass',
|
iconName: 'lucide:Search',
|
||||||
type: ['header'],
|
type: ['header'],
|
||||||
actionFunc: async () => {
|
actionFunc: async () => {
|
||||||
console.log('open search');
|
console.log('open search');
|
||||||
|
|||||||
@@ -1,24 +0,0 @@
|
|||||||
import { customElement } from '@design.estate/dees-element';
|
|
||||||
import { DeesTilePdf } from '../dees-tile-pdf/component.js';
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
'dees-pdf-preview': DeesPdfPreview;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use <dees-tile-pdf> instead. This component will be removed in a future release.
|
|
||||||
*/
|
|
||||||
@customElement('dees-pdf-preview')
|
|
||||||
export class DeesPdfPreview extends DeesTilePdf {
|
|
||||||
public static demoGroups: never[] = []; // Hide from demo catalog
|
|
||||||
|
|
||||||
public connectedCallback(): Promise<void> {
|
|
||||||
console.warn(
|
|
||||||
'[dees-pdf-preview] is deprecated. Use <dees-tile-pdf> instead. ' +
|
|
||||||
'This component will be removed in a future release.'
|
|
||||||
);
|
|
||||||
return super.connectedCallback();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,189 +0,0 @@
|
|||||||
import { html } from '@design.estate/dees-element';
|
|
||||||
|
|
||||||
export const demo = () => {
|
|
||||||
const samplePdfs = [
|
|
||||||
'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf',
|
|
||||||
'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf',
|
|
||||||
];
|
|
||||||
|
|
||||||
const generateGridItems = (count: number) => {
|
|
||||||
const items = [];
|
|
||||||
for (let i = 0; i < count; i++) {
|
|
||||||
const pdfUrl = samplePdfs[i % samplePdfs.length];
|
|
||||||
items.push(html`
|
|
||||||
<dees-pdf-preview
|
|
||||||
pdfUrl="${pdfUrl}"
|
|
||||||
maxPages="3"
|
|
||||||
stackOffset="6"
|
|
||||||
clickable="true"
|
|
||||||
grid-mode
|
|
||||||
@pdf-preview-click=${(e: CustomEvent) => {
|
|
||||||
console.log('PDF Preview clicked:', e.detail);
|
|
||||||
alert(`PDF clicked: ${e.detail.pageCount} pages`);
|
|
||||||
}}
|
|
||||||
></dees-pdf-preview>
|
|
||||||
`);
|
|
||||||
}
|
|
||||||
return items;
|
|
||||||
};
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
.demo-container {
|
|
||||||
padding: 40px;
|
|
||||||
background: #f5f5f5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.demo-section {
|
|
||||||
margin-bottom: 60px;
|
|
||||||
}
|
|
||||||
|
|
||||||
h3 {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
font-size: 18px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
|
|
||||||
gap: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-row {
|
|
||||||
display: flex;
|
|
||||||
gap: 24px;
|
|
||||||
align-items: center;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-label {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
min-width: 100px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.performance-stats {
|
|
||||||
margin-top: 20px;
|
|
||||||
padding: 16px;
|
|
||||||
background: white;
|
|
||||||
border-radius: 8px;
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stats-grid {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: repeat(auto-fill, minmax(150px, 1fr));
|
|
||||||
gap: 12px;
|
|
||||||
margin-top: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-item {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-label {
|
|
||||||
font-size: 12px;
|
|
||||||
color: #666;
|
|
||||||
}
|
|
||||||
|
|
||||||
.stat-value {
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
|
||||||
<div class="demo-container">
|
|
||||||
<div class="demo-section">
|
|
||||||
<h3>Single PDF Preview with Stacked Pages</h3>
|
|
||||||
<dees-pdf-preview
|
|
||||||
pdfUrl="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/web/compressed.tracemonkey-pldi-09.pdf"
|
|
||||||
maxPages="3"
|
|
||||||
stackOffset="8"
|
|
||||||
clickable="true"
|
|
||||||
></dees-pdf-preview>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="demo-section">
|
|
||||||
<h3>Different Sizes</h3>
|
|
||||||
<div class="preview-row">
|
|
||||||
<div class="preview-label">Small:</div>
|
|
||||||
<dees-pdf-preview
|
|
||||||
size="small"
|
|
||||||
pdfUrl="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf"
|
|
||||||
maxPages="2"
|
|
||||||
stackOffset="6"
|
|
||||||
clickable="true"
|
|
||||||
></dees-pdf-preview>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="preview-row">
|
|
||||||
<div class="preview-label">Default:</div>
|
|
||||||
<dees-pdf-preview
|
|
||||||
pdfUrl="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf"
|
|
||||||
maxPages="3"
|
|
||||||
stackOffset="8"
|
|
||||||
clickable="true"
|
|
||||||
></dees-pdf-preview>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="preview-row">
|
|
||||||
<div class="preview-label">Large:</div>
|
|
||||||
<dees-pdf-preview
|
|
||||||
size="large"
|
|
||||||
pdfUrl="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf"
|
|
||||||
maxPages="4"
|
|
||||||
stackOffset="10"
|
|
||||||
clickable="true"
|
|
||||||
></dees-pdf-preview>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="demo-section">
|
|
||||||
<h3>Non-Clickable Preview</h3>
|
|
||||||
<dees-pdf-preview
|
|
||||||
pdfUrl="https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf"
|
|
||||||
maxPages="3"
|
|
||||||
stackOffset="8"
|
|
||||||
clickable="false"
|
|
||||||
></dees-pdf-preview>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="demo-section">
|
|
||||||
<h3>Performance Grid - 50 PDFs with Lazy Loading</h3>
|
|
||||||
<p style="margin-bottom: 20px; font-size: 14px; color: #666;">
|
|
||||||
This grid demonstrates the performance optimizations with 50 PDF previews.
|
|
||||||
Scroll to see lazy loading in action - previews render only when visible.
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div class="preview-grid">
|
|
||||||
${generateGridItems(50)}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="performance-stats">
|
|
||||||
<h4>Performance Features</h4>
|
|
||||||
<div class="stats-grid">
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">Lazy Loading</span>
|
|
||||||
<span class="stat-value">✓ Enabled</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">Canvas Pooling</span>
|
|
||||||
<span class="stat-value">✓ Active</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">Memory Management</span>
|
|
||||||
<span class="stat-value">✓ Optimized</span>
|
|
||||||
</div>
|
|
||||||
<div class="stat-item">
|
|
||||||
<span class="stat-label">Intersection Observer</span>
|
|
||||||
<span class="stat-value">200px margin</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
};
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from './component.js';
|
|
||||||
@@ -1,223 +0,0 @@
|
|||||||
import { css, cssManager } from '@design.estate/dees-element';
|
|
||||||
|
|
||||||
export const previewStyles = [
|
|
||||||
cssManager.defaultStyles,
|
|
||||||
css`
|
|
||||||
:host {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-container {
|
|
||||||
position: relative;
|
|
||||||
width: 200px;
|
|
||||||
height: 260px;
|
|
||||||
background: ${cssManager.bdTheme('hsl(0 0% 98%)', 'hsl(215 20% 14%)')};
|
|
||||||
border-radius: 4px;
|
|
||||||
overflow: hidden;
|
|
||||||
transition: transform 0.2s ease, box-shadow 0.2s ease;
|
|
||||||
box-shadow: 0 1px 3px ${cssManager.bdTheme('rgba(0, 0, 0, 0.12)', 'rgba(0, 0, 0, 0.24)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-container.clickable {
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-container.clickable:hover {
|
|
||||||
transform: translateY(-2px);
|
|
||||||
box-shadow: 0 8px 24px ${cssManager.bdTheme('rgba(0, 0, 0, 0.12)', 'rgba(0, 0, 0, 0.3)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-container.clickable:hover .preview-overlay {
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-stack {
|
|
||||||
position: relative;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
box-sizing: border-box;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-stack.non-a4 {
|
|
||||||
padding: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-canvas {
|
|
||||||
position: relative;
|
|
||||||
background: white;
|
|
||||||
display: block;
|
|
||||||
max-width: 100%;
|
|
||||||
max-height: 100%;
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
object-fit: contain;
|
|
||||||
image-rendering: auto;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
box-shadow: 0 1px 3px ${cssManager.bdTheme('rgba(0, 0, 0, 0.1)', 'rgba(0, 0, 0, 0.3)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.non-a4 .preview-canvas {
|
|
||||||
border: 1px solid ${cssManager.bdTheme('hsl(214 31% 92%)', 'hsl(217 25% 24%)')};
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-info {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 8px;
|
|
||||||
left: 8px;
|
|
||||||
right: 8px;
|
|
||||||
padding: 6px 10px;
|
|
||||||
background: ${cssManager.bdTheme('hsl(0 0% 100% / 0.92)', 'hsl(215 20% 12% / 0.92)')};
|
|
||||||
border-radius: 6px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 6px;
|
|
||||||
font-size: 12px;
|
|
||||||
color: ${cssManager.bdTheme('hsl(215 16% 45%)', 'hsl(215 16% 75%)')};
|
|
||||||
backdrop-filter: blur(12px);
|
|
||||||
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-info dees-icon {
|
|
||||||
font-size: 13px;
|
|
||||||
color: ${cssManager.bdTheme('hsl(217 91% 60%)', 'hsl(213 93% 68%)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-pages {
|
|
||||||
font-weight: 500;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-overlay {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
background: ${cssManager.bdTheme('rgba(0, 0, 0, 0.7)', 'rgba(0, 0, 0, 0.8)')};
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 8px;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.2s ease;
|
|
||||||
z-index: 20;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-overlay dees-icon {
|
|
||||||
font-size: 24px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-overlay span {
|
|
||||||
font-size: 14px;
|
|
||||||
font-weight: 500;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-loading,
|
|
||||||
.preview-error {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
right: 0;
|
|
||||||
bottom: 0;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 12px;
|
|
||||||
color: ${cssManager.bdTheme('hsl(215 16% 45%)', 'hsl(215 16% 75%)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-loading {
|
|
||||||
background: ${cssManager.bdTheme('hsl(0 0% 99%)', 'hsl(215 20% 14%)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-error {
|
|
||||||
background: ${cssManager.bdTheme('hsl(0 72% 98%)', 'hsl(0 62% 20%)')};
|
|
||||||
color: ${cssManager.bdTheme('hsl(0 72% 40%)', 'hsl(0 70% 68%)')};
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-spinner {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
border-radius: 50%;
|
|
||||||
border: 2px solid ${cssManager.bdTheme('hsl(214 31% 86%)', 'hsl(217 25% 28%)')};
|
|
||||||
border-top-color: ${cssManager.bdTheme('hsl(217 91% 60%)', 'hsl(213 93% 68%)')};
|
|
||||||
animation: spin 0.8s linear infinite;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes spin {
|
|
||||||
to {
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-text {
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: 500;
|
|
||||||
}
|
|
||||||
|
|
||||||
.preview-error dees-icon {
|
|
||||||
font-size: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fadeIn {
|
|
||||||
from {
|
|
||||||
opacity: 0;
|
|
||||||
transform: translateY(-4px);
|
|
||||||
}
|
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateY(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Responsive sizes */
|
|
||||||
:host([size="small"]) .preview-container {
|
|
||||||
width: 150px;
|
|
||||||
height: 195px;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([size="large"]) .preview-container {
|
|
||||||
width: 250px;
|
|
||||||
height: 325px;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Grid optimizations */
|
|
||||||
:host([grid-mode]) .preview-container {
|
|
||||||
will-change: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([grid-mode]) .preview-canvas {
|
|
||||||
image-rendering: -webkit-optimize-contrast;
|
|
||||||
image-rendering: crisp-edges;
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
@@ -1,161 +0,0 @@
|
|||||||
import { DeesElement, property, html, customElement, domtools, type TemplateResult, type CSSResult, } from '@design.estate/dees-element';
|
|
||||||
|
|
||||||
import { Deferred } from '@push.rocks/smartpromise';
|
|
||||||
import { DeesContextmenu } from '../../00group-overlay/dees-contextmenu/dees-contextmenu.js';
|
|
||||||
import '../../00group-utility/dees-icon/dees-icon.js';
|
|
||||||
|
|
||||||
// import type pdfjsTypes from 'pdfjs-dist';
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
'dees-pdf': DeesPdf;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @deprecated Use DeesPdfViewer or DeesTilePdf instead
|
|
||||||
* - DeesPdfViewer: Full-featured PDF viewing with controls, navigation, zoom
|
|
||||||
* - DeesTilePdf: Lightweight, performance-optimized tile preview for grids
|
|
||||||
*/
|
|
||||||
@customElement('dees-pdf')
|
|
||||||
export class DeesPdf extends DeesElement {
|
|
||||||
// DEMO
|
|
||||||
public static demo = () => html` <dees-pdf></dees-pdf> `;
|
|
||||||
public static demoGroups = ['Media', 'PDF'];
|
|
||||||
|
|
||||||
// INSTANCE
|
|
||||||
|
|
||||||
@property()
|
|
||||||
accessor pdfUrl: string =
|
|
||||||
'https://raw.githubusercontent.com/mozilla/pdf.js/ba2edeae/examples/learning/helloworld.pdf';
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
|
|
||||||
// you have access to all kinds of things through this.
|
|
||||||
// this.setAttribute('gotIt','true');
|
|
||||||
}
|
|
||||||
|
|
||||||
public render(): TemplateResult {
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
:host {
|
|
||||||
font-family: 'Geist Sans', sans-serif;
|
|
||||||
display: block;
|
|
||||||
box-sizing: border-box;
|
|
||||||
max-width: 800px;
|
|
||||||
}
|
|
||||||
:host([hidden]) {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pdfcanvas {
|
|
||||||
box-shadow: 0px 0px 5px #ccc;
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<canvas
|
|
||||||
id="pdfcanvas"
|
|
||||||
.height=${0}
|
|
||||||
.width=${0}
|
|
||||||
|
|
||||||
></canvas>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static pdfJsReady: Promise<any>;
|
|
||||||
public static pdfjsLib: any // typeof pdfjsTypes;
|
|
||||||
public async connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
if (!DeesPdf.pdfJsReady) {
|
|
||||||
const pdfJsReadyDeferred = domtools.plugins.smartpromise.defer();
|
|
||||||
DeesPdf.pdfJsReady = pdfJsReadyDeferred.promise;
|
|
||||||
// @ts-ignore
|
|
||||||
DeesPdf.pdfjsLib = await import('https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/+esm');
|
|
||||||
DeesPdf.pdfjsLib.GlobalWorkerOptions.workerSrc = 'https://cdn.jsdelivr.net/npm/pdfjs-dist@4.0.379/build/pdf.worker.mjs';
|
|
||||||
pdfJsReadyDeferred.resolve();
|
|
||||||
}
|
|
||||||
await DeesPdf.pdfJsReady;
|
|
||||||
this.displayContent();
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public async displayContent() {
|
|
||||||
await DeesPdf.pdfJsReady;
|
|
||||||
|
|
||||||
// Asynchronous download of PDF
|
|
||||||
const loadingTask = DeesPdf.pdfjsLib.getDocument(this.pdfUrl);
|
|
||||||
loadingTask.promise.then(
|
|
||||||
(pdf) => {
|
|
||||||
console.log('PDF loaded');
|
|
||||||
|
|
||||||
// Fetch the first page
|
|
||||||
const pageNumber = 1;
|
|
||||||
pdf.getPage(pageNumber).then((page) => {
|
|
||||||
console.log('Page loaded');
|
|
||||||
|
|
||||||
const scale = 10;
|
|
||||||
const viewport = page.getViewport({ scale: scale });
|
|
||||||
|
|
||||||
// Prepare canvas using PDF page dimensions
|
|
||||||
const canvas: any = this.shadowRoot.querySelector('#pdfcanvas');
|
|
||||||
const context = canvas.getContext('2d');
|
|
||||||
canvas.height = viewport.height;
|
|
||||||
canvas.width = viewport.width;
|
|
||||||
|
|
||||||
// Render PDF page into canvas context
|
|
||||||
const renderContext = {
|
|
||||||
canvasContext: context,
|
|
||||||
viewport: viewport,
|
|
||||||
};
|
|
||||||
|
|
||||||
const renderTask = page.render(renderContext);
|
|
||||||
renderTask.promise.then(function () {
|
|
||||||
console.log('Page rendered');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
(reason) => {
|
|
||||||
// PDF loading error
|
|
||||||
console.error(reason);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Provide context menu items for the global context menu handler
|
|
||||||
*/
|
|
||||||
public getContextMenuItems() {
|
|
||||||
return [
|
|
||||||
{
|
|
||||||
name: 'Open PDF in New Tab',
|
|
||||||
iconName: 'lucide:ExternalLink',
|
|
||||||
action: async () => {
|
|
||||||
window.open(this.pdfUrl, '_blank');
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{ divider: true },
|
|
||||||
{
|
|
||||||
name: 'Copy PDF URL',
|
|
||||||
iconName: 'lucide:Copy',
|
|
||||||
action: async () => {
|
|
||||||
await navigator.clipboard.writeText(this.pdfUrl);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'Download PDF',
|
|
||||||
iconName: 'lucide:Download',
|
|
||||||
action: async () => {
|
|
||||||
const link = document.createElement('a');
|
|
||||||
link.href = this.pdfUrl;
|
|
||||||
link.download = this.pdfUrl.split('/').pop() || 'document.pdf';
|
|
||||||
link.click();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
export * from './component.js';
|
|
||||||
@@ -5,8 +5,6 @@ export * from './dees-video-viewer/index.js';
|
|||||||
export * from './dees-preview/index.js';
|
export * from './dees-preview/index.js';
|
||||||
|
|
||||||
// PDF Components
|
// PDF Components
|
||||||
export * from './dees-pdf/index.js'; // @deprecated - Use dees-pdf-viewer or dees-tile-pdf instead
|
|
||||||
export * from './dees-pdf-preview/index.js'; // @deprecated - Use dees-tile-pdf instead
|
|
||||||
export * from './dees-pdf-shared/index.js';
|
export * from './dees-pdf-shared/index.js';
|
||||||
export * from './dees-pdf-viewer/index.js';
|
export * from './dees-pdf-viewer/index.js';
|
||||||
|
|
||||||
|
|||||||
@@ -7,9 +7,9 @@ export const CDN_VERSIONS = {
|
|||||||
xtermAddonFit: '0.8.0',
|
xtermAddonFit: '0.8.0',
|
||||||
xtermAddonSearch: '0.13.0',
|
xtermAddonSearch: '0.13.0',
|
||||||
highlightJs: '11.11.1',
|
highlightJs: '11.11.1',
|
||||||
apexcharts: '5.3.6',
|
apexcharts: '5.10.3',
|
||||||
tiptap: '2.23.0',
|
tiptap: '2.27.2',
|
||||||
fontawesome: '7.1.0',
|
fontawesome: '7.2.0',
|
||||||
} as const;
|
} as const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user