Compare commits

...

9 Commits

Author SHA1 Message Date
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
b0020ace16 1.5.4
Some checks failed
Default (tags) / security (push) Failing after 12s
Default (tags) / test (push) Failing after 12s
Default (tags) / release (push) Has been skipped
Default (tags) / metadata (push) Has been skipped
2025-04-11 11:19:58 +00:00
bb78d32dbf fix(readme): Update readme with company and trademark guidelines, clarifying legal usage without exposing licensing details. 2025-04-11 11:19:58 +00:00
e83ad8d504 1.5.3
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-11 11:19:24 +00:00
765b01afe0 fix(readme): Update readme.md: remove redundant usage section and refine component documentation with improved examples. 2025-04-11 11:19:23 +00:00
8 changed files with 1696 additions and 224 deletions

View File

@ -1,5 +1,41 @@
# Changelog
## 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)
Update readme with company and trademark guidelines, clarifying legal usage without exposing licensing details.
- Added sections detailing company information and trademark guidelines.
- Outlined legal disclaimers for trademark usage.
## 2025-04-11 - 1.5.3 - fix(readme)
Update readme.md: remove redundant usage section and refine component documentation with improved examples.
- Removed the standalone manual import and usage example for components.
- Added refined examples demonstrating both basic and option-based usage (e.g. for DeesButton).
- Improved markdown formatting and consistency across component documentation.
## 2025-04-11 - 1.5.3 - fix(readme)
Update readme.md for clearer documentation: removed redundant 'Usage' section and refined component examples (e.g., DeesButton's basic and options usage) for improved clarity and consistency.
- Removed standalone usage example showing manual import and creation of components
- Added refined examples demonstrating both basic and option-based usage of components
- Improved overall readme formatting and consistency across component documentation
## 2025-04-11 - 1.5.2 - fix(ci)
Remove obsolete GitLab CI configuration file

View File

@ -1,6 +1,6 @@
{
"name": "@design.estate/dees-catalog",
"version": "1.5.2",
"version": "1.5.6",
"private": false,
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
"main": "dist_ts_web/index.js",
@ -16,7 +16,7 @@
"license": "MIT",
"dependencies": {
"@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",
"@fortawesome/fontawesome-svg-core": "^6.7.2",
"@fortawesome/free-brands-svg-icons": "^6.7.2",
@ -25,11 +25,12 @@
"@push.rocks/smarti18n": "^1.0.4",
"@push.rocks/smartpromise": "^4.2.0",
"@push.rocks/smartstring": "^4.0.15",
"@tsclass/tsclass": "^4.4.0",
"@tsclass/tsclass": "^9.0.0",
"@webcontainer/api": "1.2.0",
"apexcharts": "^4.3.0",
"highlight.js": "11.11.1",
"ibantools": "^4.5.1",
"lucide": "^0.501.0",
"monaco-editor": "^0.52.2",
"pdfjs-dist": "^4.10.38",
"xterm": "^5.3.0",
@ -42,7 +43,7 @@
"@git.zone/tswatch": "^2.0.37",
"@push.rocks/projectinfo": "^5.0.2",
"@push.rocks/tapbundle": "^5.5.6",
"@types/node": "^22.10.7"
"@types/node": "^22.14.1"
},
"files": [
"ts/**/*",

223
pnpm-lock.yaml generated
View File

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

1067
readme.md

File diff suppressed because it is too large Load Diff

View File

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

View File

@ -1,31 +1,155 @@
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);
export const demoFunc = () => html`
// 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`);
}
}
// 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>
.demoContainer {
width: 100%;
box-sizing: border-box;
display: flex;
flex-wrap: wrap;
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 {
transition: color 0.02s;
transition: all 0.2s ease;
color: #ffffff;
}
dees-icon:hover {
color: #e4002b;
}
.iconContainer {
display: block;
padding: 16px 16px 0px 16px;
display: flex;
flex-direction: column;
align-items: center;
padding: 20px 16px 0px 16px;
border: 1px solid #333333;
margin-right: 8px;
margin-bottom: 8px;
margin-right: 10px;
margin-bottom: 10px;
border-radius: 4px;
transition: background-color 0.2s;
cursor: pointer;
position: relative;
}
.iconContainer:hover {
background-color: #222;
}
.iconName {
@ -33,23 +157,136 @@ export const demoFunc = () => html`
text-align: center;
color: #ccc;
background: #333333;
padding: 4px 8px;
padding-bottom: 4px;
padding: 6px 10px;
margin-left: -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>
<div class="demoContainer">
${Object.keys(faIcons).map(
(iconName) => html`
<div class="iconContainer">
<dees-icon .iconFA=${iconName as any}></dees-icon>
<div class="iconName">${iconName}</div>
</div>
`
)}
<div class="search-container">
<input type="text" id="iconSearch" placeholder="Search icons..." @input=${searchIcons}>
</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';
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
arrowRight: faArrowRightSolid,
arrowUpRightFromSquare: faArrowUpRightFromSquareSolid,
@ -136,7 +141,32 @@ export const faIcons = {
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 {
interface HTMLElementTagNameMap {
@ -148,31 +178,170 @@ declare global {
export class DeesIcon extends DeesElement {
public static demo = demoFunc;
/**
* @deprecated Use the `icon` property instead with format "fa:iconName" or "lucide:iconName"
*/
@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;
@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() {
super();
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 = [
cssManager.defaultStyles,
css`
:host {
display: block;
white-space: nowrap;
display: flex;
display: inline-flex;
align-items: 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`
${domtools.elementBasic.styles}
<style>
#iconContainer svg {
display: block;
#iconContainer {
width: ${this.iconSize}px;
height: ${this.iconSize}px;
}
</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) {
this.iconSize = parseInt(globalThis.getComputedStyle(this).fontSize.replace(/\D/g,''));
}
if (this.iconFA) {
this.shadowRoot.querySelector('#iconContainer').innerHTML = this.iconFA
? icon(faIcons[this.iconFA]).html[0]
: 'icon not found';
// Get the effective icon (either from icon or iconFA property)
const effectiveIcon = this.getEffectiveIcon();
// 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

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