Compare commits

...

9 Commits

Author SHA1 Message Date
12861b2230 1.7.0
Some checks failed
Default (tags) / security (push) Failing after 17s
Default (tags) / test (push) Failing after 8s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-04-22 12:49:57 +00:00
b7f672e0f2 feat(dees-searchbar): Add dees-searchbar component with live search and filter demo 2025-04-22 12:49:57 +00:00
fcb44dfd24 1.6.0
Some checks failed
Default (tags) / security (push) Failing after 20s
Default (tags) / test (push) Failing after 9s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-04-22 12:30:22 +00:00
f17b880b59 feat(documentation/dees-heading): Add codex documentation overview and dees-heading component demo 2025-04-22 12:30:22 +00:00
68785d9a72 1.5.6
Some checks failed
Default (tags) / security (push) Failing after 20s
Default (tags) / test (push) Failing after 8s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-04-18 17:07:43 +00:00
ab4396297a fix(dependencies): Bump dependency versions and update demo code references 2025-04-18 17:07:43 +00:00
ef369f2955 update 2025-04-13 17:32:44 +00:00
1e73a9527b 1.5.5
Some checks failed
Default (tags) / security (push) Failing after 19s
Default (tags) / test (push) Failing after 9s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-04-12 14:35:56 +00:00
23a4faa5d1 fix(catalog): No code or documentation changes were detected. This commit records an empty update in commit information and confirms that the current state remains stable. 2025-04-12 14:35:55 +00:00
14 changed files with 1069 additions and 156 deletions

View File

@ -1,5 +1,35 @@
# Changelog # Changelog
## 2025-04-22 - 1.7.0 - feat(dees-searchbar)
Add dees-searchbar component with live search and filter demo
- Introduces a new dees-searchbar element with an input field, a search button, and filters
- Wires up events for 'search-changed' and 'search-submit' to provide realtime feedback
- Adds a demo file to showcase usage and logging of search events
## 2025-04-22 - 1.6.0 - feat(documentation/dees-heading)
Add codex documentation overview and dees-heading component demo
- Introduce 'codex.md' to provide a high-level overview of project layout, component patterns, and build workflow
- Add and update dees-heading component with demo to support multiple heading levels and horizontal rule styles
- Update component export index to include dees-heading
## 2025-04-18 - 1.5.6 - fix(dependencies)
Bump dependency versions and update demo code references
- Upgrade @design.estate/dees-element from ^2.0.39 to ^2.0.41
- Upgrade @tsclass/tsclass from ^4.4.0 to ^9.0.0
- Upgrade lucide from ^0.488.0 to ^0.501.0
- Update @types/node from ^22.10.7 to ^22.14.1
- Update dees-icon demo: scope search to demo container and adjust hover scaling
- Replace resolveExec with directives.resolveExec in dees-table for proper rendering
## 2025-04-12 - 1.5.5 - fix(catalog)
No code or documentation changes were detected. This commit records an empty update in commit information and confirms that the current state remains stable.
- Verified that there are no modifications in source, documentation, or demos
- Commit metadata and build configuration remain unchanged
## 2025-04-11 - 1.5.4 - fix(readme) ## 2025-04-11 - 1.5.4 - fix(readme)
Update readme with company and trademark guidelines, clarifying legal usage without exposing licensing details. Update readme with company and trademark guidelines, clarifying legal usage without exposing licensing details.

43
codex.md Normal file
View File

@ -0,0 +1,43 @@
# Codex: Project Overview and Codebase Structure
## Project Overview
- Package: `@design.estate/dees-catalog`
- Focus: Web Components library providing UI elements and layouts for modern web apps.
## Directory Layout
- ts_web/: TypeScript source files
- elements/: Individual Web Component definitions
- pages/: Page-level templates for composite layouts
- html/: Demo/app entry point loading the bundled scripts
- dist_bundle/: Bundled browser JS and source maps
- dist_ts_web/: ES module outputs for TypeScript/web consumers
- dist_watch/: Watch-mode development bundle with live reload
- test/: Browser-based tests using `@push.rocks/tapbundle`
## Component Patterns
- Each component in ts_web/elements/:
- Decorated with `@customElement('tag-name')`
- Extends `DeesElement` from `@design.estate/dees-element`
- Uses `@property` for reactive, reflected attributes
- Defines `static styles = [cssManager.defaultStyles, css`...`]`
- Implements `render()` returning a Lit `html` template with slots or markup
- Exposes a demo via `public static demo` linking to `.demo.ts` files
## Build & Development Workflow
- Install dependencies: `npm install` or `pnpm install`
- Build production bundle: `npm run build`
- Start dev watch mode: `npm run watch`
- Run tests: `npm test` (launches browser fixtures)
## Theming & Utilities
- Default global styles via `cssManager.defaultStyles`
- Theme-aware values with `cssManager.bdTheme(light, dark)`
- DOM utilities set up in `html/index.ts` using `@design.estate/dees-domtools`
## Documentation
- `readme.md` provides an overview of all components and basic usage
- Live examples in `.demo.ts` files
accessible via component `demo` static property
## Updates to this file
If you have pattern insisights or general changes to the codebase, please update this file.

View File

@ -1,6 +1,6 @@
{ {
"name": "@design.estate/dees-catalog", "name": "@design.estate/dees-catalog",
"version": "1.5.4", "version": "1.7.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",
@ -16,7 +16,7 @@
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"@design.estate/dees-domtools": "^2.1.1", "@design.estate/dees-domtools": "^2.1.1",
"@design.estate/dees-element": "^2.0.39", "@design.estate/dees-element": "^2.0.41",
"@design.estate/dees-wcctools": "^1.0.90", "@design.estate/dees-wcctools": "^1.0.90",
"@fortawesome/fontawesome-svg-core": "^6.7.2", "@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2", "@fortawesome/free-brands-svg-icons": "^6.7.2",
@ -25,11 +25,12 @@
"@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.0.15", "@push.rocks/smartstring": "^4.0.15",
"@tsclass/tsclass": "^4.4.0", "@tsclass/tsclass": "^9.0.0",
"@webcontainer/api": "1.2.0", "@webcontainer/api": "1.2.0",
"apexcharts": "^4.3.0", "apexcharts": "^4.3.0",
"highlight.js": "11.11.1", "highlight.js": "11.11.1",
"ibantools": "^4.5.1", "ibantools": "^4.5.1",
"lucide": "^0.501.0",
"monaco-editor": "^0.52.2", "monaco-editor": "^0.52.2",
"pdfjs-dist": "^4.10.38", "pdfjs-dist": "^4.10.38",
"xterm": "^5.3.0", "xterm": "^5.3.0",
@ -42,7 +43,7 @@
"@git.zone/tswatch": "^2.0.37", "@git.zone/tswatch": "^2.0.37",
"@push.rocks/projectinfo": "^5.0.2", "@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/tapbundle": "^5.5.6", "@push.rocks/tapbundle": "^5.5.6",
"@types/node": "^22.10.7" "@types/node": "^22.14.1"
}, },
"files": [ "files": [
"ts/**/*", "ts/**/*",

223
pnpm-lock.yaml generated
View File

@ -12,8 +12,8 @@ importers:
specifier: ^2.1.1 specifier: ^2.1.1
version: 2.3.2 version: 2.3.2
'@design.estate/dees-element': '@design.estate/dees-element':
specifier: ^2.0.39 specifier: ^2.0.41
version: 2.0.39 version: 2.0.41
'@design.estate/dees-wcctools': '@design.estate/dees-wcctools':
specifier: ^1.0.90 specifier: ^1.0.90
version: 1.0.90 version: 1.0.90
@ -39,8 +39,8 @@ importers:
specifier: ^4.0.15 specifier: ^4.0.15
version: 4.0.15 version: 4.0.15
'@tsclass/tsclass': '@tsclass/tsclass':
specifier: ^4.4.0 specifier: ^9.0.0
version: 4.4.4 version: 9.0.0
'@webcontainer/api': '@webcontainer/api':
specifier: 1.2.0 specifier: 1.2.0
version: 1.2.0 version: 1.2.0
@ -53,6 +53,9 @@ importers:
ibantools: ibantools:
specifier: ^4.5.1 specifier: ^4.5.1
version: 4.5.1 version: 4.5.1
lucide:
specifier: ^0.501.0
version: 0.501.0
monaco-editor: monaco-editor:
specifier: ^0.52.2 specifier: ^0.52.2
version: 0.52.2 version: 0.52.2
@ -85,8 +88,8 @@ importers:
specifier: ^5.5.6 specifier: ^5.5.6
version: 5.6.3(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4) version: 5.6.3(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)
'@types/node': '@types/node':
specifier: ^22.10.7 specifier: ^22.14.1
version: 22.14.0 version: 22.14.1
packages: packages:
@ -99,8 +102,8 @@ packages:
'@api.global/typedrequest@3.1.10': '@api.global/typedrequest@3.1.10':
resolution: {integrity: sha512-EiCp44XVcMjBvEs4oM1nMUaeY4ySU0Pzt3+mDwVG5DNP6EV87Nwancbr2jKScvaFNel9eeDgGtgEnFBKjOnApA==} resolution: {integrity: sha512-EiCp44XVcMjBvEs4oM1nMUaeY4ySU0Pzt3+mDwVG5DNP6EV87Nwancbr2jKScvaFNel9eeDgGtgEnFBKjOnApA==}
'@api.global/typedserver@3.0.72': '@api.global/typedserver@3.0.74':
resolution: {integrity: sha512-GO6SzPEAIlBrW3xUnorYJAzJycktpq5UG6FzGnfk8GkWwAMUFc3anWc7MPXrM79Mbwqtm0D3Lh9fBWPY56z2Jw==} resolution: {integrity: sha512-lrXaCPaVZLihlF9w39pEqTw2kiHFCheRKTZuK07S7gTGyfdXKPmccVR/EK4ox58E1gjh9A2K8yY8ZWGcjuSJkw==}
'@api.global/typedsocket@3.0.1': '@api.global/typedsocket@3.0.1':
resolution: {integrity: sha512-xojiAVNXtHoxkpBo8U2HHJG8FrVXXuLvDNndSHXwx4C9VslUwDn5zSCI+PdBl8iAg+ZuBmKjqkpZZ9sL6DC5yQ==} resolution: {integrity: sha512-xojiAVNXtHoxkpBo8U2HHJG8FrVXXuLvDNndSHXwx4C9VslUwDn5zSCI+PdBl8iAg+ZuBmKjqkpZZ9sL6DC5yQ==}
@ -280,8 +283,8 @@ packages:
resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==} resolution: {integrity: sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==}
engines: {node: '>=6.9.0'} engines: {node: '>=6.9.0'}
'@cloudflare/workers-types@4.20250410.0': '@cloudflare/workers-types@4.20250418.0':
resolution: {integrity: sha512-Yx9VUi6QpmXtUIhOL+em+V02gue12kmVBVL6RGH5mhFh50M0x9JyOmm6wKwKZUny2uQd+22nuouE2q3z1OrsIQ==} resolution: {integrity: sha512-cPnHbEAryOX1FwEjjMXXCLudkxXUlfy7Hf55lqTPpYRSUA76NGLFfkhUF7+KkRrFg2u6pNpXTj24Gv5pMEHlqg==}
'@colors/colors@1.6.0': '@colors/colors@1.6.0':
resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==} resolution: {integrity: sha512-Ir+AOibqzrIsL6ajt3Rz3LskB7OiMVHqltZmspbW/TJuTVuyOMirVqAkjfY6JISiLHgyNqicAC8AyHHGzNd/dA==}
@ -299,8 +302,8 @@ packages:
'@design.estate/dees-domtools@2.3.2': '@design.estate/dees-domtools@2.3.2':
resolution: {integrity: sha512-RfXR2t67M9kaCoF6CBkKJtVdsdp6p1O7S1OaWjrs8V0S3277ch4bSYfO+8f+QYweXKkI6Tr2PKaq3PIlwFSC1g==} resolution: {integrity: sha512-RfXR2t67M9kaCoF6CBkKJtVdsdp6p1O7S1OaWjrs8V0S3277ch4bSYfO+8f+QYweXKkI6Tr2PKaq3PIlwFSC1g==}
'@design.estate/dees-element@2.0.39': '@design.estate/dees-element@2.0.41':
resolution: {integrity: sha512-AQdGU/+GmWmU5M5pDf+GWT7GU8UN073WZvtIkfqQZemxd35HYU1vpi629m8/PjKd5dIHAU7QN2mKb6IQ8anPgw==} resolution: {integrity: sha512-Ss3wq4FJZnPn/6Zcl/oPZJARZElrkm1lmIUFdl5NXwSXBdYthk0sK2agPbrOPIEfutx65R6G4XZZ4rLhirHVBQ==}
'@design.estate/dees-wcctools@1.0.90': '@design.estate/dees-wcctools@1.0.90':
resolution: {integrity: sha512-EHYWHiOe+P261e9fBbOBmkD7lIsOpD+tu4VZQr20oc8vhsFjeUGJqYeBm/Ghwg+Gck/dto+K9zyJNIyQ642cEw==} resolution: {integrity: sha512-EHYWHiOe+P261e9fBbOBmkD7lIsOpD+tu4VZQr20oc8vhsFjeUGJqYeBm/Ghwg+Gck/dto+K9zyJNIyQ642cEw==}
@ -685,8 +688,8 @@ packages:
'@lit-labs/ssr-dom-shim@1.3.0': '@lit-labs/ssr-dom-shim@1.3.0':
resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==} resolution: {integrity: sha512-nQIWonJ6eFAvUUrSlwyHDm/aE8PBDu5kRpL0vHMg6K8fK3Diq1xdPjTnsJSwxABhaZ+5eBi1btQB5ShUTKo4nQ==}
'@lit/reactive-element@2.0.4': '@lit/reactive-element@2.1.0':
resolution: {integrity: sha512-GFn91inaUa2oHLak8awSIigYz0cU0Payr1rcFsrkf5OJ5eSPxElyZfKh0f2p9FsTiZWXQdWGJeXZICEfXXYSXQ==} resolution: {integrity: sha512-L2qyoZSQClcBmq0qajBVbhYEcG6iK0XfLn66ifLe/RfC0/ihpc+pl0Wdn8bJ8o+hj38cG0fGXRgSS20MuXn7qA==}
'@mixmark-io/domino@2.2.0': '@mixmark-io/domino@2.2.0':
resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==} resolution: {integrity: sha512-Y28PR25bHXUg88kCV7nivXrP2Nj2RueZ3/l/jdx6J9f8J4nsEGcgX0Qe6lt7Pa+J79+kPiJU3LguR6O/6zrLOw==}
@ -864,8 +867,8 @@ packages:
'@push.rocks/smartbucket@3.3.7': '@push.rocks/smartbucket@3.3.7':
resolution: {integrity: sha512-RiOuEtwHJ+HFbV1nlZgh5VuMvP6PXElX6rVe7OSQsyNCBybRQa/d1qDic92+2Ejx852DGeHlyREELQCxd/a/7w==} resolution: {integrity: sha512-RiOuEtwHJ+HFbV1nlZgh5VuMvP6PXElX6rVe7OSQsyNCBybRQa/d1qDic92+2Ejx852DGeHlyREELQCxd/a/7w==}
'@push.rocks/smartbuffer@3.0.4': '@push.rocks/smartbuffer@3.0.5':
resolution: {integrity: sha512-TLfhx/JD61YC8XGO9TI6Ux6US38R14HaIM84QT8hZZod8axfXrg+h8xA8tMUBpSV8PXsQy9LzxmOq0Il1fmDXw==} resolution: {integrity: sha512-pWYF08Mn8s/KF/9nHRk7pZPzuMjmYVQay2c5gGexdayxn1W4eCSYYhWH73vR2JBfGeGq/izbRNuUuEaIEeTIKA==}
'@push.rocks/smartcache@1.0.16': '@push.rocks/smartcache@1.0.16':
resolution: {integrity: sha512-UAXf74eDuH4/RebJhydIbHlYVR3ACYJjniEY/9ZePblu7bIPgwFZqLBE9g1lcKVogbH9yY62dk3rSpgBzenyfQ==} resolution: {integrity: sha512-UAXf74eDuH4/RebJhydIbHlYVR3ACYJjniEY/9ZePblu7bIPgwFZqLBE9g1lcKVogbH9yY62dk3rSpgBzenyfQ==}
@ -879,8 +882,8 @@ packages:
'@push.rocks/smartcrypto@2.0.4': '@push.rocks/smartcrypto@2.0.4':
resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==} resolution: {integrity: sha512-1+/5bsjyataf5uUkUNnnVXGRAt+gHVk1KDzozjTqgqJxHvQk1d9fVDohL6CxUhUucTPtu5VR5xNBiV8YCDuGyw==}
'@push.rocks/smartdata@5.6.0': '@push.rocks/smartdata@5.9.2':
resolution: {integrity: sha512-cqGMAGnagmnbuhRIdbS3IY68hYuh1EtdxjgpKx5lXZHnTgYWtJnF0CM/MBsQZUoA+JI9Zti+cZsKNI0y7OvIYw==} resolution: {integrity: sha512-w/Yi98B8u6yfZIPrlERmBnkWStJVFkv+dePwptg3oA5nWLdLgwQT/t/aEu+HP0nQy7Hgi9fb55AOY4UCFVD+lg==}
'@push.rocks/smartdelay@3.0.5': '@push.rocks/smartdelay@3.0.5':
resolution: {integrity: sha512-mUuI7kj2f7ztjpic96FvRIlf2RsKBa5arw81AHNsndbxO6asRcxuWL8dTVxouEIK8YsBUlj0AsrCkHhMbLQdHw==} resolution: {integrity: sha512-mUuI7kj2f7ztjpic96FvRIlf2RsKBa5arw81AHNsndbxO6asRcxuWL8dTVxouEIK8YsBUlj0AsrCkHhMbLQdHw==}
@ -1431,8 +1434,11 @@ packages:
'@tsclass/tsclass@4.4.4': '@tsclass/tsclass@4.4.4':
resolution: {integrity: sha512-YZOAF+u+r4u5rCev2uUd1KBTBdfyFdtDmcv4wuN+864lMccbdfRICR3SlJwCfYS1lbeV3QNLYGD30wjRXgvCJA==} resolution: {integrity: sha512-YZOAF+u+r4u5rCev2uUd1KBTBdfyFdtDmcv4wuN+864lMccbdfRICR3SlJwCfYS1lbeV3QNLYGD30wjRXgvCJA==}
'@tsclass/tsclass@8.2.0': '@tsclass/tsclass@8.2.1':
resolution: {integrity: sha512-qh3hhW5k030n3XVz6hDNrRPYZTTAvy7FZSnKYZXCRYV/JpNZw84daI4G4CgECOX/LAWAiW57MRwsFbShTddYBA==} resolution: {integrity: sha512-bRDCfJTipsTcK6eEokWdsOR1mGCQFeM7zTg6PRHzbxTWQcWQD9AhEr2q3CrPcmAbvIS7fvkO6/pU/mPm1MZxhQ==}
'@tsclass/tsclass@9.0.0':
resolution: {integrity: sha512-QuV2WKzi3p1ONq0UR+hNulG62D6vRPJxOXunWvN9zpWx6Uj70DKntMu8nqEIWUPgL3UKIPe7GN8l6mPCdxdcEg==}
'@types/accepts@1.3.7': '@types/accepts@1.3.7':
resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==} resolution: {integrity: sha512-Pay9fq2lM2wXPWbteBsRAGiWH2hig4ZE2asK+mm7kUzlxRTfL961rj89I6zV/E3PcIkDqyuBEcMxFT7rccugeQ==}
@ -1579,8 +1585,8 @@ packages:
'@types/node-forge@1.3.11': '@types/node-forge@1.3.11':
resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==} resolution: {integrity: sha512-FQx220y22OKNTqaByeBGqHWYz4cl94tpcxeFdvBo3wjG6XPBuZ0BNgNZRV5J5TFmmcsJ4IzsLkmGRiQbnYsBEQ==}
'@types/node@22.14.0': '@types/node@22.14.1':
resolution: {integrity: sha512-Kmpl+z84ILoG+3T/zQFyAJsU6EPTmOCj8/2+83fSN6djd6I4o7uOuGIH6vq3PrjY5BGitSbFuMN18j3iknubbA==} resolution: {integrity: sha512-u0HuPQwe/dHrItgHHpmw3N2fYCR6x4ivMNbPHRkBVP4CvN+kiRrKHWk3i8tXiO/joPwXLMYvF9TTF0eqgHIuOw==}
'@types/parse5@6.0.3': '@types/parse5@6.0.3':
resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==}
@ -3007,14 +3013,14 @@ packages:
lines-and-columns@1.2.4: lines-and-columns@1.2.4:
resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==} resolution: {integrity: sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==}
lit-element@4.1.1: lit-element@4.2.0:
resolution: {integrity: sha512-HO9Tkkh34QkTeUmEdNYhMT8hzLid7YlMlATSi1q4q17HE5d9mrrEHJ/o8O2D0cMi182zK1F3v7x0PWFjrhXFew==} resolution: {integrity: sha512-MGrXJVAI5x+Bfth/pU9Kst1iWID6GHDLEzFEnyULB/sFiRLgkd8NPK/PeeXxktA3T6EIIaq8U3KcbTU5XFcP2Q==}
lit-html@3.2.1: lit-html@3.3.0:
resolution: {integrity: sha512-qI/3lziaPMSKsrwlxH/xMgikhQ0EGOX2ICU73Bi/YHFvz2j/yMCIrw4+puF2IpQ4+upd3EWbvnHM9+PnJn48YA==} resolution: {integrity: sha512-RHoswrFAxY2d8Cf2mm4OZ1DgzCoBKUKSPvA1fhtSELxUERq2aQQ2h05pO9j81gS1o7RIRJ+CePLogfyahwmynw==}
lit@3.2.1: lit@3.3.0:
resolution: {integrity: sha512-1BBa1E/z0O9ye5fZprPtdqnc0BFzxIxTTOO/tQFmyC/hj1O3jL4TfmLBw0WEwjAokdLwpclkvGgDJwTIh0/22w==} resolution: {integrity: sha512-DGVsqsOIHBww2DqnuZzW7QsuCdahp50ojuDaBPC7jUDRpYoH0z7kHBBYZewRzer75FwtrkmkKk7iOAwSaWdBmw==}
locate-path@5.0.0: locate-path@5.0.0:
resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==} resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
@ -3092,6 +3098,9 @@ packages:
resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==} resolution: {integrity: sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==}
engines: {node: '>=16.14'} engines: {node: '>=16.14'}
lucide@0.501.0:
resolution: {integrity: sha512-ufrFxsi7s5dcuDgR/z21CqP61jyMshh2BghKaEviz3nrFohrJWZtjvHvlamDaNzeJU1tGTxxPMbWqkmTPBijjA==}
make-dir@3.1.0: make-dir@3.1.0:
resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==} resolution: {integrity: sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==}
engines: {node: '>=8'} engines: {node: '>=8'}
@ -4116,8 +4125,8 @@ packages:
resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==} resolution: {integrity: sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==}
engines: {node: '>=12'} engines: {node: '>=12'}
tr46@5.1.0: tr46@5.1.1:
resolution: {integrity: sha512-IUWnUK7ADYR5Sl1fZlO1INDUhVhatWl7BtJWsIhwJ0UAK7ilzzIa8uIqOO/aYVWHZPJkKbEL+362wrzoeRF7bw==} resolution: {integrity: sha512-hdF5ZgjTqgAntKkklYw0R03MG2x/bSzTtkxmIRw/sTNV8YXsCJ1tfLAX23lhxhHJlEf3CRCOCGGWw3vI3GaSPw==}
engines: {node: '>=18'} engines: {node: '>=18'}
tree-kill@1.2.2: tree-kill@1.2.2:
@ -4163,8 +4172,8 @@ packages:
resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==} resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
engines: {node: '>=12.20'} engines: {node: '>=12.20'}
type-fest@4.39.1: type-fest@4.40.0:
resolution: {integrity: sha512-uW9qzd66uyHYxwyVBYiwS4Oi0qZyUqwjU+Oevr6ZogYiXt99EOYtwvzMSLw1c3lYo2HzJsep/NB23iEVEgjG/w==} resolution: {integrity: sha512-ABHZ2/tS2JkvH1PEjxFDTUWC8dB5OsIGZP4IFLhR293GqT5Y5qB1WwL2kMPYhQW9DVgVD8Hd7I8gjwPIf5GFkw==}
engines: {node: '>=16'} engines: {node: '>=16'}
type-is@1.6.18: type-is@1.6.18:
@ -4395,8 +4404,8 @@ packages:
resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==} resolution: {integrity: sha512-2OQsPNEmBCvXuFlIni/a+Rn+R2pHW9INm0BxXJ4hVDA8TirqMj+J/Rp9ItLatT/5pZqWwefVrTQcHpixsxnVlA==}
engines: {node: '>= 4.0.0'} engines: {node: '>= 4.0.0'}
zod@3.24.2: zod@3.24.3:
resolution: {integrity: sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ==} resolution: {integrity: sha512-HhY1oqzWCQWuUqvBFnsyrtZRhyPeR7SUGv+C4+MsisMuVfSPx8HpwWqH8tRahSlt6M3PiFAcoeFhZAqIXTxoSg==}
zwitch@2.0.4: zwitch@2.0.4:
resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==} resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
@ -4412,19 +4421,19 @@ snapshots:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@push.rocks/isounique': 1.0.5 '@push.rocks/isounique': 1.0.5
'@push.rocks/lik': 6.1.0 '@push.rocks/lik': 6.1.0
'@push.rocks/smartbuffer': 3.0.4 '@push.rocks/smartbuffer': 3.0.5
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
'@push.rocks/smartguard': 3.1.0 '@push.rocks/smartguard': 3.1.0
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
'@push.rocks/webrequest': 3.0.37 '@push.rocks/webrequest': 3.0.37
'@push.rocks/webstream': 1.0.10 '@push.rocks/webstream': 1.0.10
'@api.global/typedserver@3.0.72': '@api.global/typedserver@3.0.74':
dependencies: dependencies:
'@api.global/typedrequest': 3.1.10 '@api.global/typedrequest': 3.1.10
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedsocket': 3.0.1 '@api.global/typedsocket': 3.0.1
'@cloudflare/workers-types': 4.20250410.0 '@cloudflare/workers-types': 4.20250418.0
'@design.estate/dees-comms': 1.0.27 '@design.estate/dees-comms': 1.0.27
'@push.rocks/lik': 6.1.0 '@push.rocks/lik': 6.1.0
'@push.rocks/smartchok': 1.0.34 '@push.rocks/smartchok': 1.0.34
@ -4451,13 +4460,13 @@ snapshots:
'@push.rocks/taskbuffer': 3.1.7 '@push.rocks/taskbuffer': 3.1.7
'@push.rocks/webrequest': 3.0.37 '@push.rocks/webrequest': 3.0.37
'@push.rocks/webstore': 2.0.20 '@push.rocks/webstore': 2.0.20
'@tsclass/tsclass': 8.2.0 '@tsclass/tsclass': 8.2.1
'@types/express': 5.0.1 '@types/express': 5.0.1
body-parser: 1.20.3 body-parser: 1.20.3
cors: 2.8.5 cors: 2.8.5
express: 4.21.2 express: 4.21.2
express-force-ssl: 0.3.2 express-force-ssl: 0.3.2
lit: 3.2.1 lit: 3.3.0
transitivePeerDependencies: transitivePeerDependencies:
- '@nuxt/kit' - '@nuxt/kit'
- bufferutil - bufferutil
@ -5035,7 +5044,7 @@ snapshots:
dependencies: dependencies:
regenerator-runtime: 0.14.1 regenerator-runtime: 0.14.1
'@cloudflare/workers-types@4.20250410.0': {} '@cloudflare/workers-types@4.20250418.0': {}
'@colors/colors@1.6.0': {} '@colors/colors@1.6.0': {}
@ -5074,7 +5083,7 @@ snapshots:
'@push.rocks/websetup': 3.0.19 '@push.rocks/websetup': 3.0.19
'@push.rocks/webstore': 2.0.20 '@push.rocks/webstore': 2.0.20
lenis: 1.2.3 lenis: 1.2.3
lit: 3.2.1 lit: 3.3.0
sweet-scroll: 4.0.0 sweet-scroll: 4.0.0
transitivePeerDependencies: transitivePeerDependencies:
- '@nuxt/kit' - '@nuxt/kit'
@ -5082,12 +5091,12 @@ snapshots:
- supports-color - supports-color
- vue - vue
'@design.estate/dees-element@2.0.39': '@design.estate/dees-element@2.0.41':
dependencies: dependencies:
'@design.estate/dees-domtools': 2.3.2 '@design.estate/dees-domtools': 2.3.2
'@push.rocks/isounique': 1.0.5 '@push.rocks/isounique': 1.0.5
'@push.rocks/smartrx': 3.0.7 '@push.rocks/smartrx': 3.0.7
lit: 3.2.1 lit: 3.3.0
transitivePeerDependencies: transitivePeerDependencies:
- '@nuxt/kit' - '@nuxt/kit'
- react - react
@ -5097,9 +5106,9 @@ snapshots:
'@design.estate/dees-wcctools@1.0.90': '@design.estate/dees-wcctools@1.0.90':
dependencies: dependencies:
'@design.estate/dees-domtools': 2.3.2 '@design.estate/dees-domtools': 2.3.2
'@design.estate/dees-element': 2.0.39 '@design.estate/dees-element': 2.0.41
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
lit: 3.2.1 lit: 3.3.0
transitivePeerDependencies: transitivePeerDependencies:
- '@nuxt/kit' - '@nuxt/kit'
- react - react
@ -5331,7 +5340,7 @@ snapshots:
'@git.zone/tstest@1.0.96(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)(typescript@5.7.3)': '@git.zone/tstest@1.0.96(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)(typescript@5.7.3)':
dependencies: dependencies:
'@api.global/typedserver': 3.0.72 '@api.global/typedserver': 3.0.74
'@git.zone/tsbundle': 2.2.5 '@git.zone/tsbundle': 2.2.5
'@git.zone/tsrun': 1.3.3 '@git.zone/tsrun': 1.3.3
'@push.rocks/consolecolor': 2.0.2 '@push.rocks/consolecolor': 2.0.2
@ -5365,7 +5374,7 @@ snapshots:
'@git.zone/tswatch@2.1.0': '@git.zone/tswatch@2.1.0':
dependencies: dependencies:
'@api.global/typedserver': 3.0.72 '@api.global/typedserver': 3.0.74
'@git.zone/tsbundle': 2.2.5 '@git.zone/tsbundle': 2.2.5
'@git.zone/tsrun': 1.3.3 '@git.zone/tsrun': 1.3.3
'@push.rocks/early': 4.0.4 '@push.rocks/early': 4.0.4
@ -5412,7 +5421,7 @@ snapshots:
'@jest/schemas': 29.6.3 '@jest/schemas': 29.6.3
'@types/istanbul-lib-coverage': 2.0.6 '@types/istanbul-lib-coverage': 2.0.6
'@types/istanbul-reports': 3.0.4 '@types/istanbul-reports': 3.0.4
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/yargs': 17.0.33 '@types/yargs': 17.0.33
chalk: 4.1.2 chalk: 4.1.2
@ -5430,7 +5439,7 @@ snapshots:
'@lit-labs/ssr-dom-shim@1.3.0': {} '@lit-labs/ssr-dom-shim@1.3.0': {}
'@lit/reactive-element@2.0.4': '@lit/reactive-element@2.1.0':
dependencies: dependencies:
'@lit-labs/ssr-dom-shim': 1.3.0 '@lit-labs/ssr-dom-shim': 1.3.0
@ -5518,7 +5527,7 @@ snapshots:
'@open-wc/scoped-elements@3.0.5': '@open-wc/scoped-elements@3.0.5':
dependencies: dependencies:
'@open-wc/dedupe-mixin': 1.4.0 '@open-wc/dedupe-mixin': 1.4.0
lit: 3.2.1 lit: 3.3.0
'@open-wc/semantic-dom-diff@0.20.1': '@open-wc/semantic-dom-diff@0.20.1':
dependencies: dependencies:
@ -5532,8 +5541,8 @@ snapshots:
'@open-wc/testing-helpers@3.0.1': '@open-wc/testing-helpers@3.0.1':
dependencies: dependencies:
'@open-wc/scoped-elements': 3.0.5 '@open-wc/scoped-elements': 3.0.5
lit: 3.2.1 lit: 3.3.0
lit-html: 3.2.1 lit-html: 3.3.0
'@open-wc/testing@4.0.0': '@open-wc/testing@4.0.0':
dependencies: dependencies:
@ -5698,7 +5707,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- aws-crt - aws-crt
'@push.rocks/smartbuffer@3.0.4': '@push.rocks/smartbuffer@3.0.5':
dependencies: dependencies:
uint8array-extras: 1.4.0 uint8array-extras: 1.4.0
@ -5732,7 +5741,7 @@ snapshots:
'@types/node-forge': 1.3.11 '@types/node-forge': 1.3.11
node-forge: 1.3.1 node-forge: 1.3.1
'@push.rocks/smartdata@5.6.0(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)': '@push.rocks/smartdata@5.9.2(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)':
dependencies: dependencies:
'@push.rocks/lik': 6.1.0 '@push.rocks/lik': 6.1.0
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
@ -5744,7 +5753,7 @@ snapshots:
'@push.rocks/smarttime': 4.1.1 '@push.rocks/smarttime': 4.1.1
'@push.rocks/smartunique': 3.0.9 '@push.rocks/smartunique': 3.0.9
'@push.rocks/taskbuffer': 3.1.7 '@push.rocks/taskbuffer': 3.1.7
'@tsclass/tsclass': 8.2.0 '@tsclass/tsclass': 8.2.1
mongodb: 6.15.0(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4) mongodb: 6.15.0(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)
transitivePeerDependencies: transitivePeerDependencies:
- '@aws-sdk/credential-providers' - '@aws-sdk/credential-providers'
@ -5900,7 +5909,7 @@ snapshots:
'@push.rocks/smartmongo@2.0.12(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)': '@push.rocks/smartmongo@2.0.12(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)':
dependencies: dependencies:
'@push.rocks/mongodump': 1.0.8 '@push.rocks/mongodump': 1.0.8
'@push.rocks/smartdata': 5.6.0(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4) '@push.rocks/smartdata': 5.9.2(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)
'@push.rocks/smartpath': 5.0.18 '@push.rocks/smartpath': 5.0.18
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
mongodb-memory-server: 10.1.4(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4) mongodb-memory-server: 10.1.4(@aws-sdk/credential-providers@3.787.0)(socks@2.8.4)
@ -5942,7 +5951,7 @@ snapshots:
'@push.rocks/smartntml@2.0.8': '@push.rocks/smartntml@2.0.8':
dependencies: dependencies:
'@design.estate/dees-element': 2.0.39 '@design.estate/dees-element': 2.0.41
'@happy-dom/global-registrator': 15.11.7 '@happy-dom/global-registrator': 15.11.7
'@push.rocks/smartpromise': 4.2.3 '@push.rocks/smartpromise': 4.2.3
fake-indexeddb: 6.0.0 fake-indexeddb: 6.0.0
@ -5965,7 +5974,7 @@ snapshots:
'@push.rocks/smartpdf@3.2.2(typescript@5.7.3)': '@push.rocks/smartpdf@3.2.2(typescript@5.7.3)':
dependencies: dependencies:
'@push.rocks/smartbuffer': 3.0.4 '@push.rocks/smartbuffer': 3.0.5
'@push.rocks/smartdelay': 3.0.5 '@push.rocks/smartdelay': 3.0.5
'@push.rocks/smartfile': 11.2.0 '@push.rocks/smartfile': 11.2.0
'@push.rocks/smartnetwork': 3.0.2 '@push.rocks/smartnetwork': 3.0.2
@ -6051,7 +6060,7 @@ snapshots:
'@push.rocks/smartsocket@2.1.0': '@push.rocks/smartsocket@2.1.0':
dependencies: dependencies:
'@api.global/typedrequest-interfaces': 3.0.19 '@api.global/typedrequest-interfaces': 3.0.19
'@api.global/typedserver': 3.0.72 '@api.global/typedserver': 3.0.74
'@push.rocks/isohash': 2.0.1 '@push.rocks/isohash': 2.0.1
'@push.rocks/isounique': 1.0.5 '@push.rocks/isounique': 1.0.5
'@push.rocks/lik': 6.1.0 '@push.rocks/lik': 6.1.0
@ -6769,22 +6778,26 @@ snapshots:
'@tsclass/tsclass@4.4.4': '@tsclass/tsclass@4.4.4':
dependencies: dependencies:
type-fest: 4.39.1 type-fest: 4.40.0
'@tsclass/tsclass@8.2.0': '@tsclass/tsclass@8.2.1':
dependencies: dependencies:
type-fest: 4.39.1 type-fest: 4.40.0
'@tsclass/tsclass@9.0.0':
dependencies:
type-fest: 4.40.0
'@types/accepts@1.3.7': '@types/accepts@1.3.7':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/babel__code-frame@7.0.6': {} '@types/babel__code-frame@7.0.6': {}
'@types/body-parser@1.19.5': '@types/body-parser@1.19.5':
dependencies: dependencies:
'@types/connect': 3.4.38 '@types/connect': 3.4.38
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/buffer-json@2.0.3': {} '@types/buffer-json@2.0.3': {}
@ -6800,17 +6813,17 @@ snapshots:
'@types/clean-css@4.2.11': '@types/clean-css@4.2.11':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
source-map: 0.6.1 source-map: 0.6.1
'@types/co-body@6.1.3': '@types/co-body@6.1.3':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/qs': 6.9.18 '@types/qs': 6.9.18
'@types/connect@3.4.38': '@types/connect@3.4.38':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/content-disposition@0.5.8': {} '@types/content-disposition@0.5.8': {}
@ -6821,11 +6834,11 @@ snapshots:
'@types/connect': 3.4.38 '@types/connect': 3.4.38
'@types/express': 5.0.1 '@types/express': 5.0.1
'@types/keygrip': 1.0.6 '@types/keygrip': 1.0.6
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/cors@2.8.17': '@types/cors@2.8.17':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/debounce@1.2.4': {} '@types/debounce@1.2.4': {}
@ -6839,7 +6852,7 @@ snapshots:
'@types/express-serve-static-core@5.0.6': '@types/express-serve-static-core@5.0.6':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/qs': 6.9.18 '@types/qs': 6.9.18
'@types/range-parser': 1.2.7 '@types/range-parser': 1.2.7
'@types/send': 0.17.4 '@types/send': 0.17.4
@ -6856,30 +6869,30 @@ snapshots:
'@types/from2@2.3.5': '@types/from2@2.3.5':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/fs-extra@11.0.4': '@types/fs-extra@11.0.4':
dependencies: dependencies:
'@types/jsonfile': 6.1.4 '@types/jsonfile': 6.1.4
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/fs-extra@9.0.13': '@types/fs-extra@9.0.13':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/glob@7.2.0': '@types/glob@7.2.0':
dependencies: dependencies:
'@types/minimatch': 5.1.2 '@types/minimatch': 5.1.2
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/glob@8.1.0': '@types/glob@8.1.0':
dependencies: dependencies:
'@types/minimatch': 5.1.2 '@types/minimatch': 5.1.2
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/gunzip-maybe@1.4.2': '@types/gunzip-maybe@1.4.2':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/hast@3.0.4': '@types/hast@3.0.4':
dependencies: dependencies:
@ -6913,7 +6926,7 @@ snapshots:
'@types/jsonfile@6.1.4': '@types/jsonfile@6.1.4':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/keygrip@1.0.6': {} '@types/keygrip@1.0.6': {}
@ -6930,7 +6943,7 @@ snapshots:
'@types/http-errors': 2.0.4 '@types/http-errors': 2.0.4
'@types/keygrip': 1.0.6 '@types/keygrip': 1.0.6
'@types/koa-compose': 3.2.8 '@types/koa-compose': 3.2.8
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/mdast@4.0.4': '@types/mdast@4.0.4':
dependencies: dependencies:
@ -6948,9 +6961,9 @@ snapshots:
'@types/node-forge@1.3.11': '@types/node-forge@1.3.11':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/node@22.14.0': '@types/node@22.14.1':
dependencies: dependencies:
undici-types: 6.21.0 undici-types: 6.21.0
@ -6968,19 +6981,19 @@ snapshots:
'@types/s3rver@3.7.4': '@types/s3rver@3.7.4':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/semver@7.7.0': {} '@types/semver@7.7.0': {}
'@types/send@0.17.4': '@types/send@0.17.4':
dependencies: dependencies:
'@types/mime': 1.3.5 '@types/mime': 1.3.5
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/serve-static@1.15.7': '@types/serve-static@1.15.7':
dependencies: dependencies:
'@types/http-errors': 2.0.4 '@types/http-errors': 2.0.4
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/send': 0.17.4 '@types/send': 0.17.4
'@types/sinon-chai@3.2.12': '@types/sinon-chai@3.2.12':
@ -7000,11 +7013,11 @@ snapshots:
'@types/tar-stream@2.2.3': '@types/tar-stream@2.2.3':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/through2@2.0.41': '@types/through2@2.0.41':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/triple-beam@1.3.5': {} '@types/triple-beam@1.3.5': {}
@ -7028,18 +7041,18 @@ snapshots:
'@types/whatwg-url@8.2.2': '@types/whatwg-url@8.2.2':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/webidl-conversions': 7.0.3 '@types/webidl-conversions': 7.0.3
'@types/which@3.0.4': {} '@types/which@3.0.4': {}
'@types/ws@7.4.7': '@types/ws@7.4.7':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/ws@8.18.1': '@types/ws@8.18.1':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
'@types/yargs-parser@21.0.3': {} '@types/yargs-parser@21.0.3': {}
@ -7049,7 +7062,7 @@ snapshots:
'@types/yauzl@2.10.3': '@types/yauzl@2.10.3':
dependencies: dependencies:
'@types/node': 22.14.0 '@types/node': 22.14.1
optional: true optional: true
'@ungap/structured-clone@1.3.0': {} '@ungap/structured-clone@1.3.0': {}
@ -7391,7 +7404,7 @@ snapshots:
dependencies: dependencies:
devtools-protocol: 0.0.1425554 devtools-protocol: 0.0.1425554
mitt: 3.0.1 mitt: 3.0.1
zod: 3.24.2 zod: 3.24.3
ci-info@3.9.0: {} ci-info@3.9.0: {}
@ -7672,7 +7685,7 @@ snapshots:
engine.io@6.6.4: engine.io@6.6.4:
dependencies: dependencies:
'@types/cors': 2.8.17 '@types/cors': 2.8.17
'@types/node': 22.14.0 '@types/node': 22.14.1
accepts: 1.3.8 accepts: 1.3.8
base64id: 2.0.0 base64id: 2.0.0
cookie: 0.7.2 cookie: 0.7.2
@ -8437,7 +8450,7 @@ snapshots:
jest-util@29.7.0: jest-util@29.7.0:
dependencies: dependencies:
'@jest/types': 29.6.3 '@jest/types': 29.6.3
'@types/node': 22.14.0 '@types/node': 22.14.1
chalk: 4.1.2 chalk: 4.1.2
ci-info: 3.9.0 ci-info: 3.9.0
graceful-fs: 4.2.11 graceful-fs: 4.2.11
@ -8549,21 +8562,21 @@ snapshots:
lines-and-columns@1.2.4: {} lines-and-columns@1.2.4: {}
lit-element@4.1.1: lit-element@4.2.0:
dependencies: dependencies:
'@lit-labs/ssr-dom-shim': 1.3.0 '@lit-labs/ssr-dom-shim': 1.3.0
'@lit/reactive-element': 2.0.4 '@lit/reactive-element': 2.1.0
lit-html: 3.2.1 lit-html: 3.3.0
lit-html@3.2.1: lit-html@3.3.0:
dependencies: dependencies:
'@types/trusted-types': 2.0.7 '@types/trusted-types': 2.0.7
lit@3.2.1: lit@3.3.0:
dependencies: dependencies:
'@lit/reactive-element': 2.0.4 '@lit/reactive-element': 2.1.0
lit-element: 4.1.1 lit-element: 4.2.0
lit-html: 3.2.1 lit-html: 3.3.0
locate-path@5.0.0: locate-path@5.0.0:
dependencies: dependencies:
@ -8640,6 +8653,8 @@ snapshots:
lru-cache@8.0.5: {} lru-cache@8.0.5: {}
lucide@0.501.0: {}
make-dir@3.1.0: make-dir@3.1.0:
dependencies: dependencies:
semver: 6.3.1 semver: 6.3.1
@ -9953,7 +9968,7 @@ snapshots:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1
tr46@5.1.0: tr46@5.1.1:
dependencies: dependencies:
punycode: 2.3.1 punycode: 2.3.1
@ -9988,7 +10003,7 @@ snapshots:
type-fest@2.19.0: {} type-fest@2.19.0: {}
type-fest@4.39.1: {} type-fest@4.40.0: {}
type-is@1.6.18: type-is@1.6.18:
dependencies: dependencies:
@ -10082,7 +10097,7 @@ snapshots:
whatwg-url@14.2.0: whatwg-url@14.2.0:
dependencies: dependencies:
tr46: 5.1.0 tr46: 5.1.1
webidl-conversions: 7.0.0 webidl-conversions: 7.0.0
which@2.0.2: which@2.0.2:
@ -10195,6 +10210,6 @@ snapshots:
ylru@1.4.0: {} ylru@1.4.0: {}
zod@3.24.2: {} zod@3.24.3: {}
zwitch@2.0.4: {} zwitch@2.0.4: {}

View File

@ -3,6 +3,6 @@
*/ */
export const commitinfo = { export const commitinfo = {
name: '@design.estate/dees-catalog', name: '@design.estate/dees-catalog',
version: '1.5.4', version: '1.7.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

@ -0,0 +1,14 @@
import { html } from '@design.estate/dees-element';
export function demoFunc() {
return html`
<dees-heading level="1">This is a H1 heading</dees-heading>
<dees-heading level="2">This is a H2 heading</dees-heading>
<dees-heading level="3">This is a H3 heading</dees-heading>
<dees-heading level="4">This is a H4 heading</dees-heading>
<dees-heading level="5">This is a H5 heading</dees-heading>
<dees-heading level="6">This is a H6 heading</dees-heading>
<dees-heading level="hr">This is an hr heading</dees-heading>
<dees-heading level="hr-small">This is an hr small heading</dees-heading>
`;
}

View File

@ -0,0 +1,115 @@
import {
customElement,
html,
css,
property,
cssManager,
type TemplateResult,
DeesElement,
type CSSResult,
} from '@design.estate/dees-element';
import { demoFunc } from './dees-heading.demo.js';
declare global {
interface HTMLElementTagNameMap {
'dees-heading': DeesHeading;
}
}
@customElement('dees-heading')
export class DeesHeading extends DeesElement {
// demo
public static demo = demoFunc;
// properties
/**
* Heading level: 1-6 for h1-h6, or 'hr' for horizontal rule style
*/
@property({ type: String, reflect: true })
public level: '1' | '2' | '3' | '4' | '5' | '6' | 'hr' | 'hr-small' = '1';
// STATIC STYLES
public static styles: CSSResult[] = [
cssManager.defaultStyles,
css`
/* Heading styles */
h1, h2, h3, h4, h5, h6 {
margin: 16px 0 8px;
font-weight: 600;
color: ${cssManager.bdTheme('#000', '#fff')};
}
h1 { font-size: 32px; font-family: 'Cal Sans'; letter-spacing: 0.025em;}
h2 { font-size: 28px; }
h3 { font-size: 24px; }
h4 { font-size: 20px; }
h5 { font-size: 16px; }
h6 { font-size: 14px; }
/* Horizontal rule style heading */
.heading-hr {
display: flex;
align-items: center;
text-align: center;
margin: 16px 0;
color: ${cssManager.bdTheme('#000', '#fff')};
}
/* Fade lines toward and away from text for hr style */
.heading-hr::before {
content: '';
flex: 1;
height: 1px;
/* fade in toward center */
background: ${cssManager.bdTheme(
'linear-gradient(to right, transparent, #ccc)',
'linear-gradient(to right, transparent, #333)'
)};
margin: 0 8px;
}
.heading-hr::after {
content: '';
flex: 1;
height: 1px;
/* fade out away from center */
background: ${cssManager.bdTheme(
'linear-gradient(to right, #ccc, transparent)',
'linear-gradient(to right, #333, transparent)'
)};
margin: 0 8px;
}
/* Small hr variant with reduced margins */
.heading-hr.heading-hr-small {
margin: 8px 0;
font-size: 12px;
}
.heading-hr.heading-hr-small::before,
.heading-hr.heading-hr-small::after {
margin: 0 8px;
}
`,
];
// INSTANCE
public render(): TemplateResult {
switch (this.level) {
case '1':
return html`<h1><slot></slot></h1>`;
case '2':
return html`<h2><slot></slot></h2>`;
case '3':
return html`<h3><slot></slot></h3>`;
case '4':
return html`<h4><slot></slot></h4>`;
case '5':
return html`<h5><slot></slot></h5>`;
case '6':
return html`<h6><slot></slot></h6>`;
case 'hr':
return html`<div class="heading-hr"><slot></slot></div>`;
case 'hr-small':
return html`<div class="heading-hr heading-hr-small"><slot></slot></div>`;
default:
return html`<h1><slot></slot></h1>`;
}
}
}

View File

@ -1,31 +1,155 @@
import { html } from '@design.estate/dees-element'; import { html } from '@design.estate/dees-element';
import { icons, type IconWithPrefix } from './dees-icon.js';
import * as lucideIcons from 'lucide';
import { faIcons } from './dees-icon.js'; export const demoFunc = () => {
// Group FontAwesome icons by type
const faIcons = Object.keys(icons.fa);
// Extract Lucide icons from the lucideIcons object directly
// Log the first few keys to understand the structure
console.log('First few Lucide keys:', Object.keys(lucideIcons).slice(0, 5));
// Get all icon functions from lucideIcons (they have PascalCase names)
const lucideIconsList = Object.keys(lucideIcons)
.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 notUtility = !['createElement', 'createIcons', 'default'].includes(key);
return isFunction && isUppercaseFirst && notUtility;
})
.map(pascalName => {
// Convert PascalCase to camelCase
return pascalName.charAt(0).toLowerCase() + pascalName.slice(1);
});
// Log how many icons we found
console.log(`Found ${lucideIconsList.length} Lucide icons`);
// If we didn't find any, try an alternative approach
if (lucideIconsList.length === 0) {
console.log('Trying alternative approach to find Lucide icons');
// Try to get icon names from a known property if available
if (lucideIcons.icons) {
const iconSource = lucideIcons.icons || {};
lucideIconsList.push(...Object.keys(iconSource));
console.log(`Found ${lucideIconsList.length} icons via alternative method`);
}
}
export const demoFunc = () => html` // Define the functions in TS scope instead of script tags
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 containers = demoContainer.querySelectorAll('.iconContainer');
containers.forEach(container => {
const iconName = container.getAttribute('data-name');
if (searchTerm === '') {
container.classList.remove('hidden');
} else if (iconName && iconName.includes(searchTerm)) {
container.classList.remove('hidden');
} else {
container.classList.add('hidden');
}
});
// Update counts - search within demoContainer
demoContainer.querySelectorAll('.section-container').forEach(section => {
const visibleIcons = section.querySelectorAll('.iconContainer:not(.hidden)').length;
const countElement = section.querySelector('.icon-count');
if (countElement) {
const totalIconsCount = section.classList.contains('fa-section')
? faIcons.length
: lucideIconsList.length;
countElement.textContent = visibleIcons === totalIconsCount
? `${totalIconsCount} icons`
: `${visibleIcons} of ${totalIconsCount} icons`;
}
});
};
const copyIconName = (iconNameToCopy: string, type: 'fa' | 'lucide') => {
// Use the new prefix format
const textToCopy = `${type}:${iconNameToCopy}`;
navigator.clipboard.writeText(textToCopy).then(() => {
// Find the event target
const currentEvent = window.event as MouseEvent;
const currentTarget = currentEvent.currentTarget as HTMLElement;
// Show feedback
const tooltip = currentTarget.querySelector('.copy-tooltip');
if (tooltip) {
tooltip.textContent = 'Copied!';
setTimeout(() => {
tooltip.textContent = 'Click to copy';
}, 2000);
}
});
};
return html`
<style> <style>
.demoContainer { .demoContainer {
width: 100%; width: 100%;
box-sizing: border-box;
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
background: #111111; background: #111111;
padding: 10px; font-size: 30px; padding: 20px;
font-size: 30px;
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen-Sans, Ubuntu, Cantarell, "Helvetica Neue", sans-serif;
} }
.search-container {
width: 100%;
margin-bottom: 20px;
display: flex;
}
#iconSearch {
flex: 1;
padding: 12px 16px;
font-size: 16px;
border: none;
border-radius: 4px;
background: #222;
color: #fff;
border: 1px solid #333;
}
#iconSearch:focus {
outline: none;
border-color: #e4002b;
}
dees-icon { dees-icon {
transition: color 0.02s; transition: all 0.2s ease;
color: #ffffff; color: #ffffff;
} }
dees-icon:hover {
color: #e4002b;
}
.iconContainer { .iconContainer {
display: block; display: flex;
padding: 16px 16px 0px 16px; flex-direction: column;
align-items: center;
padding: 20px 16px 0px 16px;
border: 1px solid #333333; border: 1px solid #333333;
margin-right: 8px; margin-right: 10px;
margin-bottom: 8px; margin-bottom: 10px;
border-radius: 4px;
transition: background-color 0.2s;
cursor: pointer;
position: relative;
}
.iconContainer:hover {
background-color: #222;
} }
.iconName { .iconName {
@ -33,23 +157,136 @@ export const demoFunc = () => html`
text-align: center; text-align: center;
color: #ccc; color: #ccc;
background: #333333; background: #333333;
padding: 4px 8px; padding: 6px 10px;
padding-bottom: 4px;
margin-left: -16px; margin-left: -16px;
margin-right: -16px; margin-right: -16px;
margin-top: 16px; margin-top: 20px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
max-width: 120px;
border-radius: 0 0 4px 4px;
}
.section-title {
width: 100%;
color: #ffffff;
font-size: 24px;
margin: 20px 0;
padding-bottom: 10px;
border-bottom: 1px solid #333333;
display: flex;
justify-content: space-between;
align-items: center;
}
.api-note {
font-size: 14px;
color: #e4002b;
margin-bottom: 20px;
padding: 10px;
border: 1px solid #e4002b;
border-radius: 4px;
background: rgba(228, 0, 43, 0.1);
}
.icon-count {
font-size: 14px;
color: #888;
font-weight: normal;
background: #222;
padding: 5px 10px;
border-radius: 20px;
}
.icons-grid {
display: flex;
flex-wrap: wrap;
width: 100%;
}
.section-container {
width: 100%;
margin-bottom: 30px;
}
.copy-tooltip {
position: absolute;
background: #333;
color: white;
padding: 5px 10px;
border-radius: 4px;
font-size: 12px;
top: -30px;
opacity: 0;
transition: opacity 0.3s;
pointer-events: none;
}
.iconContainer:hover .copy-tooltip {
opacity: 1;
}
.iconContainer:hover dees-icon {
transform: scale(1.1);
}
.hidden {
display: none !important;
} }
</style> </style>
<div class="demoContainer"> <div class="demoContainer">
${Object.keys(faIcons).map( <div class="search-container">
(iconName) => html` <input type="text" id="iconSearch" placeholder="Search icons..." @input=${searchIcons}>
<div class="iconContainer">
<dees-icon .iconFA=${iconName as any}></dees-icon>
<div class="iconName">${iconName}</div>
</div>
`
)}
</div> </div>
`; <div class="api-note">
New API: Use <code>icon="fa:iconName"</code> or <code>icon="lucide:iconName"</code> instead of <code>iconFA</code>.
Click any icon to copy its new format to clipboard.
</div>
<div class="section-container fa-section">
<div class="section-title">
FontAwesome Icons
<span class="icon-count">${faIcons.length} icons</span>
</div>
<div class="icons-grid">
${faIcons.map(
(iconName) => {
const prefixedName = `fa:${iconName}`;
return html`
<div class="iconContainer fa-icon" data-name=${iconName.toLowerCase()} @click=${() => copyIconName(iconName, 'fa')}>
<dees-icon .icon=${prefixedName as IconWithPrefix} iconSize="24"></dees-icon>
<div class="iconName">${iconName}</div>
<span class="copy-tooltip">Click to copy</span>
</div>
`;
}
)}
</div>
</div>
<div class="section-container lucide-section">
<div class="section-title">
Lucide Icons
<span class="icon-count">${lucideIconsList.length} icons</span>
</div>
<div class="icons-grid">
${lucideIconsList.map(
(iconName) => {
const prefixedName = `lucide:${iconName}`;
return html`
<div class="iconContainer lucide-icon" data-name=${iconName.toLowerCase()} @click=${() => copyIconName(iconName, 'lucide')}>
<dees-icon .icon=${prefixedName as IconWithPrefix} iconSize="24"></dees-icon>
<div class="iconName">${iconName}</div>
<span class="copy-tooltip">Click to copy</span>
</div>
`;
}
)}
</div>
</div>
</div>
`;
};

View File

@ -75,7 +75,12 @@ import {
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import { demoFunc } from './dees-icon.demo.js'; import { demoFunc } from './dees-icon.demo.js';
export const faIcons = { // Import Lucide icons and the createElement function
import * as lucideIcons from 'lucide';
import { createElement } from 'lucide';
// Collect FontAwesome icons
const faIcons = {
// normal // normal
arrowRight: faArrowRightSolid, arrowRight: faArrowRightSolid,
arrowUpRightFromSquare: faArrowUpRightFromSquareSolid, arrowUpRightFromSquare: faArrowUpRightFromSquareSolid,
@ -136,7 +141,32 @@ export const faIcons = {
twitter: faTwitter, twitter: faTwitter,
}; };
export type TIconKey = keyof typeof faIcons; // Create a string literal type for all FA icons
type FAIconKey = keyof typeof faIcons;
// Create union types for the icons with prefixes
export type IconWithPrefix = `fa:${FAIconKey}` | `lucide:${string}`;
// Export only FontAwesome icons directly
export const icons = {
fa: faIcons
};
// Legacy type for backward compatibility
export type TIconKey = FAIconKey | `lucide:${string}`;
// Use a global static cache for all icons to reduce rendering
const iconCache = new Map<string, string>();
// Clear cache items occasionally to prevent memory leaks
const MAX_CACHE_SIZE = 500;
function limitCacheSize() {
if (iconCache.size > MAX_CACHE_SIZE) {
// Remove oldest entries (first 20% of items)
const keysToDelete = Array.from(iconCache.keys()).slice(0, MAX_CACHE_SIZE / 5);
keysToDelete.forEach(key => iconCache.delete(key));
}
}
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
@ -148,31 +178,170 @@ declare global {
export class DeesIcon extends DeesElement { export class DeesIcon extends DeesElement {
public static demo = demoFunc; public static demo = demoFunc;
/**
* @deprecated Use the `icon` property instead with format "fa:iconName" or "lucide:iconName"
*/
@property({ @property({
type: String type: String,
converter: {
// Convert attribute string to property (for reflected attributes)
fromAttribute: (value: string): TIconKey => value as TIconKey,
// Convert property to attribute (for reflection)
toAttribute: (value: TIconKey): string => value
}
}) })
public iconFA: keyof typeof faIcons; public iconFA?: TIconKey;
@property() /**
* The preferred icon property. Use format "fa:iconName" or "lucide:iconName"
* Examples: "fa:check", "lucide:menu"
*/
@property({
type: String,
converter: {
fromAttribute: (value: string): IconWithPrefix => value as IconWithPrefix,
toAttribute: (value: IconWithPrefix): string => value
}
})
public icon?: IconWithPrefix;
@property({ type: Number })
public iconSize: number; public iconSize: number;
@property({ type: String })
public color: string = 'currentColor';
@property({ type: Number })
public strokeWidth: number = 2;
// For tracking when we need to re-render
private lastIcon: IconWithPrefix | TIconKey | null = null;
private lastIconSize: number | null = null;
private lastColor: string | null = null;
private lastStrokeWidth: number | null = null;
constructor() { constructor() {
super(); super();
domtools.elementBasic.setup(); domtools.elementBasic.setup();
} }
/**
* Gets the effective icon value, supporting both the new `icon` property
* and the legacy `iconFA` property for backward compatibility.
* Prefers `icon` if both are set.
*/
private getEffectiveIcon(): IconWithPrefix | TIconKey | null {
// Prefer the new API
if (this.icon) {
return this.icon;
}
// Fall back to the old API
if (this.iconFA) {
// If iconFA is already in the proper format (lucide:name), use it directly
if (this.iconFA.startsWith('lucide:')) {
return this.iconFA;
}
// For FontAwesome icons with no prefix, add the prefix
return `fa:${this.iconFA}` as IconWithPrefix;
}
return null;
}
/**
* Parses an icon string into its type and name parts
* @param iconStr The icon string in format "type:name"
* @returns Object with type and name properties
*/
private parseIconString(iconStr: string): { type: 'fa' | 'lucide', name: string } {
if (iconStr.startsWith('fa:')) {
return {
type: 'fa',
name: iconStr.substring(3) // Remove 'fa:' prefix
};
} else if (iconStr.startsWith('lucide:')) {
return {
type: 'lucide',
name: iconStr.substring(7) // Remove 'lucide:' prefix
};
} else {
// For backward compatibility, assume FontAwesome if no prefix
return {
type: 'fa',
name: iconStr
};
}
}
private renderLucideIcon(iconName: string): string {
// Create a cache key based on all visual properties
const cacheKey = `lucide:${iconName}:${this.iconSize}:${this.color}:${this.strokeWidth}`;
// Check if we already have this icon in the cache
if (iconCache.has(cacheKey)) {
return iconCache.get(cacheKey) || '';
}
try {
// Get the Pascal case icon name (Menu instead of menu)
const pascalCaseName = iconName.charAt(0).toUpperCase() + iconName.slice(1);
// Check if the icon exists in lucideIcons
if (!lucideIcons[pascalCaseName]) {
console.warn(`Lucide icon '${pascalCaseName}' not found in lucideIcons object`);
return '';
}
// Use the exact pattern from Lucide documentation
const svgElement = createElement(lucideIcons[pascalCaseName], {
color: this.color,
size: this.iconSize,
strokeWidth: this.strokeWidth
});
if (!svgElement) {
console.warn(`createElement returned empty result for ${pascalCaseName}`);
return '';
}
// Get the HTML
const result = svgElement.outerHTML;
// Cache the result for future use
iconCache.set(cacheKey, result);
limitCacheSize();
return result;
} catch (error) {
console.error(`Error rendering Lucide icon ${iconName}:`, error);
// Create a fallback SVG with the icon name
return `<svg xmlns="http://www.w3.org/2000/svg" width="${this.iconSize}" height="${this.iconSize}" viewBox="0 0 24 24" fill="none" stroke="${this.color}" stroke-width="${this.strokeWidth}" stroke-linecap="round" stroke-linejoin="round">
<text x="50%" y="50%" font-size="6" text-anchor="middle" dominant-baseline="middle" fill="${this.color}">${iconName}</text>
</svg>`;
}
}
public static styles = [ public static styles = [
cssManager.defaultStyles, cssManager.defaultStyles,
css` css`
:host { :host {
display: block; display: inline-flex;
white-space: nowrap;
display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
line-height: 1;
vertical-align: middle;
} }
* {
transition: inherit !important; /* Improve rendering performance */
#iconContainer svg {
display: block;
height: 100%;
width: 100%;
will-change: transform; /* Helps with animations */
contain: strict; /* Performance optimization */
} }
`, `,
]; ];
@ -181,8 +350,8 @@ export class DeesIcon extends DeesElement {
return html` return html`
${domtools.elementBasic.styles} ${domtools.elementBasic.styles}
<style> <style>
#iconContainer svg { #iconContainer {
display: block; width: ${this.iconSize}px;
height: ${this.iconSize}px; height: ${this.iconSize}px;
} }
</style> </style>
@ -190,14 +359,95 @@ export class DeesIcon extends DeesElement {
`; `;
} }
public async updated() { public updated() {
// If size is not specified, use font size as a base
if (!this.iconSize) { if (!this.iconSize) {
this.iconSize = parseInt(globalThis.getComputedStyle(this).fontSize.replace(/\D/g,'')); this.iconSize = parseInt(globalThis.getComputedStyle(this).fontSize.replace(/\D/g,''));
} }
if (this.iconFA) {
this.shadowRoot.querySelector('#iconContainer').innerHTML = this.iconFA // Get the effective icon (either from icon or iconFA property)
? icon(faIcons[this.iconFA]).html[0] const effectiveIcon = this.getEffectiveIcon();
: 'icon not found';
// Check if we actually need to update the icon
// This prevents unnecessary DOM operations when properties haven't changed
if (this.lastIcon === effectiveIcon &&
this.lastIconSize === this.iconSize &&
this.lastColor === this.color &&
this.lastStrokeWidth === this.strokeWidth) {
return; // No visual changes - skip update
}
// Update our "last properties" for future change detection
this.lastIcon = effectiveIcon;
this.lastIconSize = this.iconSize;
this.lastColor = this.color;
this.lastStrokeWidth = this.strokeWidth;
const container = this.shadowRoot?.querySelector('#iconContainer');
if (!container || !effectiveIcon) return;
try {
// Parse the icon string to get type and name
const { type, name } = this.parseIconString(effectiveIcon);
if (type === 'lucide') {
// For Lucide, use direct DOM manipulation as shown in the docs
// This approach avoids HTML string issues
container.innerHTML = ''; // Clear container
try {
// Convert to PascalCase
const pascalCaseName = name.charAt(0).toUpperCase() + name.slice(1);
if (lucideIcons[pascalCaseName]) {
// Use the documented pattern from Lucide docs
const svgElement = createElement(lucideIcons[pascalCaseName], {
color: this.color,
size: this.iconSize,
strokeWidth: this.strokeWidth
});
if (svgElement) {
// Directly append the element
container.appendChild(svgElement);
return; // Exit early since we've added the element
}
}
// If we reach here, something went wrong
throw new Error(`Could not create element for ${pascalCaseName}`);
} catch (error) {
console.error(`Error rendering Lucide icon:`, error);
// Fall back to the string-based approach
const iconHtml = this.renderLucideIcon(name);
if (iconHtml) {
container.innerHTML = iconHtml;
}
}
} else {
// Use FontAwesome rendering via HTML string
const faIcon = icons.fa[name as FAIconKey];
if (faIcon) {
const iconHtml = icon(faIcon).html[0];
container.innerHTML = iconHtml;
} else {
console.warn(`FontAwesome icon not found: ${name}`);
}
}
} catch (error) {
console.error(`Error updating icon ${effectiveIcon}:`, error);
} }
} }
}
// Clean up resources when element is removed
async disconnectedCallback() {
super.disconnectedCallback();
// Clear our references
this.lastIcon = null;
this.lastIconSize = null;
this.lastColor = null;
this.lastStrokeWidth = null;
}
}

View File

@ -0,0 +1,46 @@
import { html } from '@design.estate/dees-element';
export const demoFunc = () => {
const onChanged = (e: CustomEvent) => {
// find the demo wrapper and update the 'changed' log inside it
const wrapper = (e.target as HTMLElement).closest('.demoWrapper');
const el = wrapper?.querySelector('#changed');
if (el) el.textContent = `search-changed: ${e.detail.value}`;
};
const onSubmit = (e: CustomEvent) => {
// find the demo wrapper and update the 'submitted' log inside it
const wrapper = (e.target as HTMLElement).closest('.demoWrapper');
const el = wrapper?.querySelector('#submitted');
if (el) el.textContent = `search-submit: ${e.detail.value}`;
};
return html`
<style>
.demoWrapper {
display: block;
flex-direction: column;
align-items: center;
background: #888888;
}
.logs {
padding: 16px;
width: 600px;
color: #fff;
font-family: monospace;
}
.logs div {
margin: 4px 0;
}
</style>
<div class="demoWrapper">
<dees-searchbar
@search-changed=${onChanged}
@search-submit=${onSubmit}
></dees-searchbar>
<div class="logs">
<div id="changed">search-changed:</div>
<div id="submitted">search-submit:</div>
</div>
</div>
`;
};

View File

@ -0,0 +1,160 @@
import {
customElement,
DeesElement,
property,
html,
cssManager,
unsafeCSS,
css,
type TemplateResult,
domtools,
query,
} from '@design.estate/dees-element';
import * as colors from './00colors.js';
import { demoFunc } from './dees-searchbar.demo.js';
declare global {
interface HTMLElementTagNameMap {
'dees-searchbar': DeesSearchbar;
}
}
@customElement('dees-searchbar')
export class DeesSearchbar extends DeesElement {
// DEMO
public static demo = demoFunc;
// STATIC
public static styles = [
cssManager.defaultStyles,
css`
:host {
padding: 40px;
font-family: Dees Sans;
display: block;
background: ${cssManager.bdTheme('#eeeeeb', '#000000')};
}
.searchboxContainer {
position: relative;
margin: auto;
max-width: 800px;
background: ${cssManager.bdTheme('#00000015', '#ffffff15')};
--boxHeight: 60px;
height: var(--boxHeight);
border-radius: var(--boxHeight);
display: grid;
grid-template-columns: 1fr 140px;
justify-content: center;
align-items: center;
border-top: 1px solid ${cssManager.bdTheme('#00000015', '#ffffff20')};
}
input {
height: 100%;
width: 100%;
border: none;
background: none;
color: ${cssManager.bdTheme('#000000', '#eeeeeb')};
padding-left: 25px;
margin-right: -8px;
outline: none;
font-size: 16px;
}
.searchButton {
--buttonPadding: 8px;
background: ${cssManager.bdTheme('#eeeeeb', '#000000')};
color: ${cssManager.bdTheme('#000000', '#eeeeeb')};
line-height: calc(var(--boxHeight) - (var(--buttonPadding) * 2));
border-radius: var(--boxHeight);
transform: scale(1) ;
transform-origin: 50% 50%;
text-align: center;
transition: transform 0.1s, background 0.1s;
margin-right: var(--buttonPadding);
user-select: none;
}
.searchButton:hover {
color: #fff;
background: ${cssManager.bdTheme(colors.bright.blue, colors.dark.blue)};
}
.searchButton:active {
color: #fff;
background: ${cssManager.bdTheme(colors.bright.blueActive, colors.dark.blueActive)};
transform: scale(0.98);
}
.filters {
margin: auto;
max-width: 800px;
}
`,
];
// INSTANCE
@property()
public filters = [];
@query('input')
public searchInput!: HTMLInputElement;
@query('.searchButton')
public searchButton!: HTMLElement;
constructor() {
super();
}
public render(): TemplateResult {
return html`
<div class="searchboxContainer">
<input type="text" placeholder="Your Skills (e.g. TypeScript, Rust, Projectmanagement)" />
<div class="searchButton">Search -></div>
</div>
${this.filters.length > 0 ? html`
<div class="filters">
<dees-heading level="hr-small">Filters</dees-heading>
<dees-input-dropdown .label=${'location'}></dees-input-dropdown>
</div>
` : html``}
`;
}
/**
* Lifecycle: after first render, wire up events for input and submit actions
*/
public firstUpdated(): void {
// dispatch change on each input
this.searchInput.addEventListener('input', () => {
this.dispatchEvent(new CustomEvent('search-changed', {
bubbles: true,
composed: true,
detail: { value: this.searchInput.value }
}));
});
// submit on Enter key
this.searchInput.addEventListener('keydown', (e: KeyboardEvent) => {
if (e.key === 'Enter') {
this._dispatchSubmit();
}
});
// submit on button click
this.searchButton.addEventListener('click', () => this._dispatchSubmit());
}
/**
* Dispatch a submit event with the current search value
*/
private _dispatchSubmit(): void {
this.dispatchEvent(new CustomEvent('search-submit', {
bubbles: true,
composed: true,
detail: { value: this.searchInput.value }
}));
}
}

View File

@ -12,7 +12,7 @@ import {
unsafeCSS, unsafeCSS,
type CSSResult, type CSSResult,
state, state,
resolveExec, directives,
} from '@design.estate/dees-element'; } from '@design.estate/dees-element';
import { DeesContextmenu } from './dees-contextmenu.js'; import { DeesContextmenu } from './dees-contextmenu.js';
@ -415,7 +415,7 @@ export class DeesTable<T> extends DeesElement {
<div class="heading heading2">${this.heading2}</div> <div class="heading heading2">${this.heading2}</div>
</div> </div>
<div class="headerActions"> <div class="headerActions">
${resolveExec(async () => { ${directives.resolveExec(async () => {
const resultArray: TemplateResult[] = []; const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) { for (const action of this.dataActions) {
if (!action.type.includes('header')) continue; if (!action.type.includes('header')) continue;
@ -634,7 +634,7 @@ export class DeesTable<T> extends DeesElement {
selected selected
</div> </div>
<div class="footerActions"> <div class="footerActions">
${resolveExec(async () => { ${directives.resolveExec(async () => {
const resultArray: TemplateResult[] = []; const resultArray: TemplateResult[] = [];
for (const action of this.dataActions) { for (const action of this.dataActions) {
if (!action.type.includes('footer')) continue; if (!action.type.includes('footer')) continue;

View File

@ -18,6 +18,7 @@ export * from './dees-editor-markdown.js';
export * from './dees-editor-markdownoutlet.js'; export * from './dees-editor-markdownoutlet.js';
export * from './dees-form-submit.js'; export * from './dees-form-submit.js';
export * from './dees-form.js'; export * from './dees-form.js';
export * from './dees-heading.js';
export * from './dees-hint.js'; export * from './dees-hint.js';
export * from './dees-icon.js'; export * from './dees-icon.js';
export * from './dees-input-checkbox.js'; export * from './dees-input-checkbox.js';
@ -35,6 +36,7 @@ export * from './dees-mobilenavigation.js';
export * from './dees-modal.js'; export * from './dees-modal.js';
export * from './dees-input-multitoggle.js'; export * from './dees-input-multitoggle.js';
export * from './dees-pdf.js'; export * from './dees-pdf.js';
export * from './dees-searchbar.js';
export * from './dees-simple-appdash.js'; export * from './dees-simple-appdash.js';
export * from './dees-simple-login.js'; export * from './dees-simple-login.js';
export * from './dees-speechbubble.js'; export * from './dees-speechbubble.js';