Compare commits
31 Commits
Author | SHA1 | Date | |
---|---|---|---|
68785d9a72 | |||
ab4396297a | |||
ef369f2955 | |||
1e73a9527b | |||
23a4faa5d1 | |||
b0020ace16 | |||
bb78d32dbf | |||
e83ad8d504 | |||
765b01afe0 | |||
00e34e7e6c | |||
bf2ee25390 | |||
bf6d8d0bc6 | |||
3399004e75 | |||
6c2f36f020 | |||
71f4d44782 | |||
6df2eb5acc | |||
469f8e0f21 | |||
3712f6ef90 | |||
d2646cd62c | |||
f29ca0ba0b | |||
0c273a818d | |||
6e8099c6f4 | |||
07c68b82a4 | |||
afd19dc912 | |||
f02572665f | |||
f93082e9b0 | |||
08f3bad5f9 | |||
563958813e | |||
1ae1703133 | |||
d2771dfc31 | |||
dd46d3e2f4 |
128
.gitlab-ci.yml
128
.gitlab-ci.yml
@ -1,128 +0,0 @@
|
|||||||
# gitzone ci_default
|
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|
||||||
|
|
||||||
cache:
|
|
||||||
paths:
|
|
||||||
- .npmci_cache/
|
|
||||||
key: '$CI_BUILD_STAGE'
|
|
||||||
|
|
||||||
stages:
|
|
||||||
- security
|
|
||||||
- test
|
|
||||||
- release
|
|
||||||
- metadata
|
|
||||||
|
|
||||||
before_script:
|
|
||||||
- pnpm install -g pnpm
|
|
||||||
- pnpm install -g @shipzone/npmci
|
|
||||||
- npmci npm prepare
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# security stage
|
|
||||||
# ====================
|
|
||||||
# ====================
|
|
||||||
# security stage
|
|
||||||
# ====================
|
|
||||||
auditProductionDependencies:
|
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci command npm config set registry https://registry.npmjs.org
|
|
||||||
- npmci command pnpm audit --audit-level=high --prod
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
auditDevDependencies:
|
|
||||||
image: registry.gitlab.com/hosttoday/ht-docker-node:npmci
|
|
||||||
stage: security
|
|
||||||
script:
|
|
||||||
- npmci command npm config set registry https://registry.npmjs.org
|
|
||||||
- npmci command pnpm audit --audit-level=high --dev
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
allow_failure: true
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# test stage
|
|
||||||
# ====================
|
|
||||||
|
|
||||||
testStable:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm test
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
testBuild:
|
|
||||||
stage: test
|
|
||||||
script:
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm install
|
|
||||||
- npmci npm build
|
|
||||||
coverage: /\d+.?\d+?\%\s*coverage/
|
|
||||||
tags:
|
|
||||||
- docker
|
|
||||||
|
|
||||||
release:
|
|
||||||
stage: release
|
|
||||||
script:
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm publish
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
# ====================
|
|
||||||
# metadata stage
|
|
||||||
# ====================
|
|
||||||
codequality:
|
|
||||||
stage: metadata
|
|
||||||
allow_failure: true
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
script:
|
|
||||||
- npmci command npm install -g typescript
|
|
||||||
- npmci npm prepare
|
|
||||||
- npmci npm install
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
- priv
|
|
||||||
|
|
||||||
trigger:
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci trigger
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
|
|
||||||
pages:
|
|
||||||
stage: metadata
|
|
||||||
script:
|
|
||||||
- npmci node install stable
|
|
||||||
- npmci npm install
|
|
||||||
- npmci command npm run buildDocs
|
|
||||||
tags:
|
|
||||||
- lossless
|
|
||||||
- docker
|
|
||||||
- notpriv
|
|
||||||
only:
|
|
||||||
- tags
|
|
||||||
artifacts:
|
|
||||||
expire_in: 1 week
|
|
||||||
paths:
|
|
||||||
- public
|
|
||||||
allow_failure: true
|
|
110
changelog.md
110
changelog.md
@ -1,5 +1,115 @@
|
|||||||
# Changelog
|
# 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
|
||||||
|
|
||||||
|
- Deleted .gitlab-ci.yml as the CI pipeline configuration is now managed elsewhere.
|
||||||
|
- Cleaned up CI stages for security, testing, release, and metadata.
|
||||||
|
|
||||||
|
## 2025-04-11 - 1.5.1 - fix(readme)
|
||||||
|
Update readme with comprehensive reference documentation: add a usage snippet for components like DeesButton, introduce a detailed overview table of all component categories, and enhance documentation sections for each component group.
|
||||||
|
|
||||||
|
- Added a code example showing how to import and use DeesButton.
|
||||||
|
- Introduced a components overview table that categorizes Core UI, Forms, Layout, Data Display, Visualization, Dialogs & Overlays, Navigation, and Development components.
|
||||||
|
- Expanded detailed documentation with usage examples for each component type.
|
||||||
|
- Reorganized content to improve clarity and ease of navigation for developers.
|
||||||
|
|
||||||
|
## 2025-04-11 - 1.5.0 - feat(badge)
|
||||||
|
Add dees-badge component with demo file and update packageManager field in package.json
|
||||||
|
|
||||||
|
- Introduce a new badge component allowing different types (default, primary, success, warning, error) with an optional rounded style
|
||||||
|
- Provide a demo for the badge component
|
||||||
|
- Export the badge component in the main elements index
|
||||||
|
- Update package.json to include an explicit packageManager field
|
||||||
|
|
||||||
|
## 2025-01-20 - 1.4.1 - fix(dependencies)
|
||||||
|
Update dependency versions for smartpromise, webcontainer/api, tapbundle, and @types/node
|
||||||
|
|
||||||
|
- Update @push.rocks/smartpromise to version ^4.2.0
|
||||||
|
- Downgrade @webcontainer/api to version 1.2.0
|
||||||
|
- Update @push.rocks/tapbundle to version ^5.5.6
|
||||||
|
- Update @types/node to version ^22.10.7
|
||||||
|
|
||||||
|
## 2025-01-20 - 1.4.0 - feat(dees-terminal)
|
||||||
|
Enhanced the dees-terminal component to support environment variable settings and improved setup command execution.
|
||||||
|
|
||||||
|
- Added environment property to pass custom environment variables.
|
||||||
|
- Introduced webcontainerDeferred to handle the promise for web container creation.
|
||||||
|
- Enhanced demo to illustrate environment variable usage.
|
||||||
|
- Improved async interaction with the terminal for setting environment variables and executing setup commands.
|
||||||
|
|
||||||
|
## 2025-01-15 - 1.3.4 - fix(chart)
|
||||||
|
Fix chart rendering and appearance issues in the DeesChartArea component.
|
||||||
|
|
||||||
|
- Resolved issues with chart dimensions calculation based on padding.
|
||||||
|
- Adjusted grid and axis lines appearance for better visibility.
|
||||||
|
- Updated tooltip and grid line styling for better accessibility.
|
||||||
|
- Improved series data representation as time-series for more accurate display.
|
||||||
|
|
||||||
|
## 2024-12-17 - 1.3.3 - fix(dees-input-multitoggle)
|
||||||
|
Add missing TypeScript declaration for dees-input-multitoggle
|
||||||
|
|
||||||
|
- Added a missing declaration to the HTMLElementTagNameMap for 'dees-input-multitoggle' element.
|
||||||
|
|
||||||
|
## 2024-12-09 - 1.3.2 - fix(metadata)
|
||||||
|
Updated package metadata and readme for better project description and structure.
|
||||||
|
|
||||||
|
- Updated package.json and npmextra.json with a detailed project description and list of keywords.
|
||||||
|
- Enhanced readme.md with installation instructions, component usage examples, and detailed component descriptions for clarity.
|
||||||
|
|
||||||
|
## 2024-11-07 - 1.3.1 - fix(DeesSimpleAppDash)
|
||||||
|
Fix: add border to controlbar in DeesSimpleAppDash
|
||||||
|
|
||||||
|
- Fixed the missing border at the top of the controlbar in DeesSimpleAppDash.
|
||||||
|
|
||||||
|
## 2024-11-07 - 1.3.0 - feat(dees-simple-appdash)
|
||||||
|
Enhance responsive styling and terminal setup command
|
||||||
|
|
||||||
|
- Added a new property `terminalSetupCommand` for configuring terminal setup commands.
|
||||||
|
- Improved responsive styling and positioning for components to achieve a fluid layout.
|
||||||
|
- Fixed layout shifts by switching positions to `absolute` for `appbar` and `appcontent`.
|
||||||
|
|
||||||
|
## 2024-10-07 - 1.2.0 - feat(index.ts)
|
||||||
|
Add export for colors module in index.ts
|
||||||
|
|
||||||
|
- The index.ts file now exports the colors module, making color utilities available for external use.
|
||||||
|
|
||||||
## 2024-10-06 - 1.1.13 - fix(dees-button)
|
## 2024-10-06 - 1.1.13 - fix(dees-button)
|
||||||
Fix styling issue in button component.
|
Fix styling issue in button component.
|
||||||
|
|
||||||
|
@ -5,23 +5,35 @@
|
|||||||
"githost": "code.foss.global",
|
"githost": "code.foss.global",
|
||||||
"gitscope": "design.estate",
|
"gitscope": "design.estate",
|
||||||
"gitrepo": "dees-catalog",
|
"gitrepo": "dees-catalog",
|
||||||
"description": "A library for building components and other projects",
|
"description": "A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.",
|
||||||
"npmPackagename": "@design.estate/dees-catalog",
|
"npmPackagename": "@design.estate/dees-catalog",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"projectDomain": "design.estate",
|
"projectDomain": "design.estate",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
"Web Components",
|
"Web Components",
|
||||||
"User Interface",
|
"User Interface",
|
||||||
"Design System",
|
|
||||||
"UI Library",
|
"UI Library",
|
||||||
"Component Library",
|
"Component Library",
|
||||||
"Web Development",
|
|
||||||
"JavaScript",
|
"JavaScript",
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
|
"Dynamic Components",
|
||||||
|
"Modular Architecture",
|
||||||
|
"Reusable Components",
|
||||||
|
"Web Development",
|
||||||
|
"Application UI",
|
||||||
"Custom Elements",
|
"Custom Elements",
|
||||||
"Shadow DOM",
|
"Shadow DOM",
|
||||||
"CSS",
|
"UI Elements",
|
||||||
"HTML"
|
"Dashboard Interfaces",
|
||||||
|
"Form Handling",
|
||||||
|
"Data Display",
|
||||||
|
"Visualization",
|
||||||
|
"Charting",
|
||||||
|
"Interactive Components",
|
||||||
|
"Responsive Design",
|
||||||
|
"Web Applications",
|
||||||
|
"Modern Web",
|
||||||
|
"Frontend Development"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
58
package.json
58
package.json
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "@design.estate/dees-catalog",
|
"name": "@design.estate/dees-catalog",
|
||||||
"version": "1.1.13",
|
"version": "1.5.6",
|
||||||
"private": false,
|
"private": false,
|
||||||
"description": "A library for building components and other projects",
|
"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",
|
||||||
"typings": "dist_ts_web/index.d.ts",
|
"typings": "dist_ts_web/index.d.ts",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
@ -15,23 +15,24 @@
|
|||||||
"author": "Lossless GmbH",
|
"author": "Lossless GmbH",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@design.estate/dees-domtools": "^2.0.61",
|
"@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.6.0",
|
"@fortawesome/fontawesome-svg-core": "^6.7.2",
|
||||||
"@fortawesome/free-brands-svg-icons": "^6.6.0",
|
"@fortawesome/free-brands-svg-icons": "^6.7.2",
|
||||||
"@fortawesome/free-regular-svg-icons": "^6.6.0",
|
"@fortawesome/free-regular-svg-icons": "^6.7.2",
|
||||||
"@fortawesome/free-solid-svg-icons": "^6.6.0",
|
"@fortawesome/free-solid-svg-icons": "^6.7.2",
|
||||||
"@push.rocks/smarti18n": "^1.0.4",
|
"@push.rocks/smarti18n": "^1.0.4",
|
||||||
"@push.rocks/smartpromise": "^4.0.4",
|
"@push.rocks/smartpromise": "^4.2.0",
|
||||||
"@push.rocks/smartstring": "^4.0.15",
|
"@push.rocks/smartstring": "^4.0.15",
|
||||||
"@tsclass/tsclass": "^4.1.2",
|
"@tsclass/tsclass": "^9.0.0",
|
||||||
"@webcontainer/api": "1.2.0",
|
"@webcontainer/api": "1.2.0",
|
||||||
"apexcharts": "^3.54.0",
|
"apexcharts": "^4.3.0",
|
||||||
"highlight.js": "11.10.0",
|
"highlight.js": "11.11.1",
|
||||||
"ibantools": "^4.5.1",
|
"ibantools": "^4.5.1",
|
||||||
"monaco-editor": "^0.52.0",
|
"lucide": "^0.501.0",
|
||||||
"pdfjs-dist": "^4.6.82",
|
"monaco-editor": "^0.52.2",
|
||||||
|
"pdfjs-dist": "^4.10.38",
|
||||||
"xterm": "^5.3.0",
|
"xterm": "^5.3.0",
|
||||||
"xterm-addon-fit": "^0.8.0"
|
"xterm-addon-fit": "^0.8.0"
|
||||||
},
|
},
|
||||||
@ -39,10 +40,10 @@
|
|||||||
"@git.zone/tsbuild": "^2.1.84",
|
"@git.zone/tsbuild": "^2.1.84",
|
||||||
"@git.zone/tsbundle": "^2.0.15",
|
"@git.zone/tsbundle": "^2.0.15",
|
||||||
"@git.zone/tstest": "^1.0.90",
|
"@git.zone/tstest": "^1.0.90",
|
||||||
"@git.zone/tswatch": "^2.0.23",
|
"@git.zone/tswatch": "^2.0.37",
|
||||||
"@push.rocks/projectinfo": "^5.0.2",
|
"@push.rocks/projectinfo": "^5.0.2",
|
||||||
"@push.rocks/tapbundle": "^5.3.0",
|
"@push.rocks/tapbundle": "^5.5.6",
|
||||||
"@types/node": "^22.7.4"
|
"@types/node": "^22.14.1"
|
||||||
},
|
},
|
||||||
"files": [
|
"files": [
|
||||||
"ts/**/*",
|
"ts/**/*",
|
||||||
@ -62,15 +63,28 @@
|
|||||||
"keywords": [
|
"keywords": [
|
||||||
"Web Components",
|
"Web Components",
|
||||||
"User Interface",
|
"User Interface",
|
||||||
"Design System",
|
|
||||||
"UI Library",
|
"UI Library",
|
||||||
"Component Library",
|
"Component Library",
|
||||||
"Web Development",
|
|
||||||
"JavaScript",
|
"JavaScript",
|
||||||
"TypeScript",
|
"TypeScript",
|
||||||
|
"Dynamic Components",
|
||||||
|
"Modular Architecture",
|
||||||
|
"Reusable Components",
|
||||||
|
"Web Development",
|
||||||
|
"Application UI",
|
||||||
"Custom Elements",
|
"Custom Elements",
|
||||||
"Shadow DOM",
|
"Shadow DOM",
|
||||||
"CSS",
|
"UI Elements",
|
||||||
"HTML"
|
"Dashboard Interfaces",
|
||||||
]
|
"Form Handling",
|
||||||
|
"Data Display",
|
||||||
|
"Visualization",
|
||||||
|
"Charting",
|
||||||
|
"Interactive Components",
|
||||||
|
"Responsive Design",
|
||||||
|
"Web Applications",
|
||||||
|
"Modern Web",
|
||||||
|
"Frontend Development"
|
||||||
|
],
|
||||||
|
"packageManager": "pnpm@10.7.0+sha512.6b865ad4b62a1d9842b61d674a393903b871d9244954f652b8842c2b553c72176b278f64c463e52d40fff8aba385c235c8c9ecf5cc7de4fd78b8bb6d49633ab6"
|
||||||
}
|
}
|
||||||
|
6557
pnpm-lock.yaml
generated
6557
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -1 +1,4 @@
|
|||||||
|
!!! Please pay attention to the following points when writing the readme: !!!
|
||||||
|
* Give a short rundown of components and a few points abputspecific features on each.
|
||||||
|
* Try to list all components in a summary.
|
||||||
|
* Then list all components with a short description.
|
@ -3,6 +3,6 @@
|
|||||||
*/
|
*/
|
||||||
export const commitinfo = {
|
export const commitinfo = {
|
||||||
name: '@design.estate/dees-catalog',
|
name: '@design.estate/dees-catalog',
|
||||||
version: '1.1.13',
|
version: '1.5.6',
|
||||||
description: 'A library for building components and other projects'
|
description: 'A comprehensive library that provides dynamic web components for building sophisticated and modern web applications using JavaScript and TypeScript.'
|
||||||
}
|
}
|
||||||
|
12
ts_web/elements/dees-badge.demo.ts
Normal file
12
ts_web/elements/dees-badge.demo.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
import { html } from '@design.estate/dees-element';
|
||||||
|
|
||||||
|
export const demoFunc = () => html`
|
||||||
|
<div style="display: flex; gap: 8px; align-items: center;">
|
||||||
|
<dees-badge .text=${'Default'}></dees-badge>
|
||||||
|
<dees-badge .type=${'primary'} .text=${'Primary'}></dees-badge>
|
||||||
|
<dees-badge .type=${'success'} .text=${'Success'}></dees-badge>
|
||||||
|
<dees-badge .type=${'warning'} .text=${'Warning'}></dees-badge>
|
||||||
|
<dees-badge .type=${'error'} .text=${'Error'}></dees-badge>
|
||||||
|
<dees-badge .type=${'primary'} .rounded=${true} .text=${'Rounded'}></dees-badge>
|
||||||
|
</div>
|
||||||
|
`;
|
96
ts_web/elements/dees-badge.ts
Normal file
96
ts_web/elements/dees-badge.ts
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
import {
|
||||||
|
DeesElement,
|
||||||
|
css,
|
||||||
|
cssManager,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
property,
|
||||||
|
type CSSResult,
|
||||||
|
type TemplateResult,
|
||||||
|
} from '@design.estate/dees-element';
|
||||||
|
|
||||||
|
import * as domtools from '@design.estate/dees-domtools';
|
||||||
|
import { demoFunc } from './dees-badge.demo.js';
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-badge': DeesBadge;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@customElement('dees-badge')
|
||||||
|
export class DeesBadge extends DeesElement {
|
||||||
|
public static demo = demoFunc;
|
||||||
|
|
||||||
|
@property({ type: String })
|
||||||
|
public type: 'default' | 'primary' | 'success' | 'warning' | 'error' = 'default';
|
||||||
|
|
||||||
|
@property({ type: String })
|
||||||
|
public text: string = '';
|
||||||
|
|
||||||
|
@property({ type: Boolean })
|
||||||
|
public rounded: boolean = false;
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super();
|
||||||
|
domtools.elementBasic.setup();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static styles = [
|
||||||
|
cssManager.defaultStyles,
|
||||||
|
css`
|
||||||
|
:host {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge {
|
||||||
|
display: inline-flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
padding: 2px 8px;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: 500;
|
||||||
|
line-height: 1.5;
|
||||||
|
border-radius: 4px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.rounded {
|
||||||
|
border-radius: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.default {
|
||||||
|
background: ${cssManager.bdTheme('#f5f5f5', '#333')};
|
||||||
|
color: ${cssManager.bdTheme('#666', '#ccc')};
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.primary {
|
||||||
|
background: #0050b9;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.success {
|
||||||
|
background: #2e7d32;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.warning {
|
||||||
|
background: #ed6c02;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.badge.error {
|
||||||
|
background: #e4002b;
|
||||||
|
color: #ffffff;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
|
||||||
|
public render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<div class="badge ${this.type} ${this.rounded ? 'rounded' : ''}">
|
||||||
|
${this.text}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
@ -38,7 +38,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
super();
|
super();
|
||||||
domtools.elementBasic.setup();
|
domtools.elementBasic.setup();
|
||||||
|
|
||||||
this.resizeObserver = new ResizeObserver(entries => {
|
this.resizeObserver = new ResizeObserver((entries) => {
|
||||||
for (let entry of entries) {
|
for (let entry of entries) {
|
||||||
if (entry.target.classList.contains('mainbox')) {
|
if (entry.target.classList.contains('mainbox')) {
|
||||||
this.resizeChart(); // Call resizeChart when the .mainbox size changes
|
this.resizeChart(); // Call resizeChart when the .mainbox size changes
|
||||||
@ -55,7 +55,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
});
|
});
|
||||||
this.registerGarbageFunction(async () => {
|
this.registerGarbageFunction(async () => {
|
||||||
this.resizeObserver.disconnect();
|
this.resizeObserver.disconnect();
|
||||||
})
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static styles = [
|
public static styles = [
|
||||||
@ -71,7 +71,7 @@ export class DeesChartArea extends DeesElement {
|
|||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 400px;
|
height: 400px;
|
||||||
background: #222;
|
background: #111;
|
||||||
border-radius: 8px;
|
border-radius: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -95,10 +95,12 @@ export class DeesChartArea extends DeesElement {
|
|||||||
];
|
];
|
||||||
|
|
||||||
public render(): TemplateResult {
|
public render(): TemplateResult {
|
||||||
return html` <div class="mainbox">
|
return html`
|
||||||
<div class="chartTitle">${this.label}</div>
|
<div class="mainbox">
|
||||||
<div class="chartContainer"></div>
|
<div class="chartTitle">${this.label}</div>
|
||||||
</div> `;
|
<div class="chartContainer"></div>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async firstUpdated() {
|
public async firstUpdated() {
|
||||||
@ -107,11 +109,23 @@ export class DeesChartArea extends DeesElement {
|
|||||||
series: [
|
series: [
|
||||||
{
|
{
|
||||||
name: 'cpu',
|
name: 'cpu',
|
||||||
data: [31, 40, 28, 51, 42, 109, 100],
|
data: [
|
||||||
|
{ x: '2025-01-15T03:00:00', y: 25 },
|
||||||
|
{ x: '2025-01-15T07:00:00', y: 30 },
|
||||||
|
{ x: '2025-01-15T11:00:00', y: 20 },
|
||||||
|
{ x: '2025-01-15T15:00:00', y: 35 },
|
||||||
|
{ x: '2025-01-15T19:00:00', y: 25 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'memory',
|
name: 'memory',
|
||||||
data: [11, 32, 45, 32, 34, 52, 41],
|
data: [
|
||||||
|
{ x: '2025-01-15T03:00:00', y: 10 },
|
||||||
|
{ x: '2025-01-15T07:00:00', y: 12 },
|
||||||
|
{ x: '2025-01-15T11:00:00', y: 10 },
|
||||||
|
{ x: '2025-01-15T15:00:00', y: 30 },
|
||||||
|
{ x: '2025-01-15T19:00:00', y: 40 },
|
||||||
|
],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
chart: {
|
chart: {
|
||||||
@ -130,35 +144,62 @@ export class DeesChartArea extends DeesElement {
|
|||||||
curve: 'smooth',
|
curve: 'smooth',
|
||||||
},
|
},
|
||||||
xaxis: {
|
xaxis: {
|
||||||
crosshairs: {
|
type: 'datetime', // Time-series data
|
||||||
stroke: {
|
labels: {
|
||||||
width: 1,
|
format: 'hh:mm A', // Time formatting
|
||||||
color: '#444',
|
style: {
|
||||||
|
colors: '#9e9e9e', // Label color
|
||||||
|
fontSize: '12px',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
type: 'datetime',
|
axisBorder: {
|
||||||
categories: [
|
show: false, // Hide x-axis border
|
||||||
'2018-09-19T00:00:00.000Z',
|
},
|
||||||
'2018-09-19T01:30:00.000Z',
|
axisTicks: {
|
||||||
'2018-09-19T02:30:00.000Z',
|
show: false, // Hide x-axis ticks
|
||||||
'2018-09-19T03:30:00.000Z',
|
},
|
||||||
'2018-09-19T04:30:00.000Z',
|
|
||||||
'2018-09-19T05:30:00.000Z',
|
|
||||||
'2018-09-19T06:30:00.000Z',
|
|
||||||
],
|
|
||||||
},
|
},
|
||||||
yaxis: {
|
yaxis: {
|
||||||
crosshairs: {
|
min: 0,
|
||||||
stroke: {
|
labels: {
|
||||||
width: 1,
|
formatter: function (val: number) {
|
||||||
color: '#444',
|
return `${val} Mbps`; // Format Y-axis labels
|
||||||
},
|
},
|
||||||
|
style: {
|
||||||
|
colors: '#9e9e9e', // Label color
|
||||||
|
fontSize: '12px',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
axisBorder: {
|
||||||
|
show: false, // Hide y-axis border
|
||||||
|
},
|
||||||
|
axisTicks: {
|
||||||
|
show: false, // Hide y-axis ticks
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
tooltip: {
|
tooltip: {
|
||||||
|
shared: true, // Enables the tooltip to display across series
|
||||||
|
intersect: false, // Allows hovering anywhere on the chart
|
||||||
|
followCursor: true, // Makes tooltip follow mouse even between points
|
||||||
x: {
|
x: {
|
||||||
format: 'dd/MM/yy HH:mm',
|
format: 'dd/MM/yy HH:mm',
|
||||||
},
|
},
|
||||||
|
custom: function ({ series, seriesIndex, dataPointIndex, w }) {
|
||||||
|
// Get the x value
|
||||||
|
const xValue = w.globals.labels[dataPointIndex];
|
||||||
|
// Iterate through each series and get its value
|
||||||
|
let tooltipContent = `<div style="padding: 10px; background: #1e1e2f; color: white; border-radius: 5px;">`;
|
||||||
|
tooltipContent += ``; // `<strong>Time:</strong> ${xValue}<br/>`;
|
||||||
|
|
||||||
|
series.forEach((s, index) => {
|
||||||
|
const label = w.globals.seriesNames[index]; // Get series label
|
||||||
|
const value = s[dataPointIndex]; // Get value at data point
|
||||||
|
tooltipContent += `<strong>${label}:</strong> ${value} Mbps<br/>`;
|
||||||
|
});
|
||||||
|
|
||||||
|
tooltipContent += `</div>`;
|
||||||
|
return tooltipContent;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
grid: {
|
grid: {
|
||||||
xaxis: {
|
xaxis: {
|
||||||
@ -171,8 +212,8 @@ export class DeesChartArea extends DeesElement {
|
|||||||
show: true,
|
show: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
borderColor: '#666', // Set the color of the grid lines
|
borderColor: '#333', // Set the color of the grid lines
|
||||||
strokeDashArray: 2, // Solid line
|
strokeDashArray: 0, // Solid line
|
||||||
row: {
|
row: {
|
||||||
colors: [], // This can be used to alternate the shading of the horizontal rows
|
colors: [], // This can be used to alternate the shading of the horizontal rows
|
||||||
opacity: 0.1,
|
opacity: 0.1,
|
||||||
@ -182,6 +223,15 @@ export class DeesChartArea extends DeesElement {
|
|||||||
opacity: 0.1,
|
opacity: 0.1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
fill: {
|
||||||
|
type: 'gradient', // Gradient fill for the area
|
||||||
|
gradient: {
|
||||||
|
shade: 'dark',
|
||||||
|
type: 'vertical',
|
||||||
|
gradientToColors: ['#9c27b0'], // Gradient color ending
|
||||||
|
stops: [0, 100],
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
this.chart = new ApexCharts(this.shadowRoot.querySelector('.chartContainer'), options);
|
this.chart = new ApexCharts(this.shadowRoot.querySelector('.chartContainer'), options);
|
||||||
await this.chart.render();
|
await this.chart.render();
|
||||||
@ -189,20 +239,22 @@ export class DeesChartArea extends DeesElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async resizeChart() {
|
public async resizeChart() {
|
||||||
const element = this.shadowRoot.querySelector('.chartContainer');
|
const mainbox: HTMLDivElement = this.shadowRoot.querySelector('.mainbox');
|
||||||
|
const chartContainer: HTMLDivElement = this.shadowRoot.querySelector('.chartContainer');
|
||||||
|
|
||||||
// Get computed style of the element
|
// Get computed style of the element
|
||||||
const style = window.getComputedStyle(element);
|
const styleMainbox = window.getComputedStyle(mainbox);
|
||||||
|
const styleChartContainer = window.getComputedStyle(chartContainer);
|
||||||
|
|
||||||
// Extract padding values
|
// Extract padding values
|
||||||
const paddingTop = parseInt(style.paddingTop, 10);
|
const paddingTop = parseInt(styleChartContainer.paddingTop, 10);
|
||||||
const paddingBottom = parseInt(style.paddingBottom, 10);
|
const paddingBottom = parseInt(styleChartContainer.paddingBottom, 10);
|
||||||
const paddingLeft = parseInt(style.paddingLeft, 10);
|
const paddingLeft = parseInt(styleChartContainer.paddingLeft, 10);
|
||||||
const paddingRight = parseInt(style.paddingRight, 10);
|
const paddingRight = parseInt(styleChartContainer.paddingRight, 10);
|
||||||
|
|
||||||
// Calculate the actual width and height to use, subtracting padding
|
// Calculate the actual width and height to use, subtracting padding
|
||||||
const actualWidth = element.clientWidth - paddingLeft - paddingRight;
|
const actualWidth = mainbox.clientWidth - paddingLeft - paddingRight;
|
||||||
const actualHeight = element.clientHeight - paddingTop - paddingBottom;
|
const actualHeight = mainbox.offsetHeight - paddingTop - paddingBottom;
|
||||||
|
|
||||||
await this.chart.updateOptions({
|
await this.chart.updateOptions({
|
||||||
chart: {
|
chart: {
|
||||||
|
@ -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);
|
||||||
|
|
||||||
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>
|
<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>
|
||||||
|
`;
|
||||||
|
};
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
}
|
}
|
@ -12,6 +12,12 @@ import {
|
|||||||
|
|
||||||
const { demoFunc } = await import('./dees-input-multitoggle.demo.js');
|
const { demoFunc } = await import('./dees-input-multitoggle.demo.js');
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
'dees-input-multitoggle': DeesInputMultitoggle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement('dees-input-multitoggle')
|
@customElement('dees-input-multitoggle')
|
||||||
export class DeesInputMultitoggle extends DeesElement {
|
export class DeesInputMultitoggle extends DeesElement {
|
||||||
public static demo = demoFunc;
|
public static demo = demoFunc;
|
||||||
|
@ -39,6 +39,9 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
@property()
|
@property()
|
||||||
public viewTabs: IView[] = [];
|
public viewTabs: IView[] = [];
|
||||||
|
|
||||||
|
@property()
|
||||||
|
public terminalSetupCommand: string = `pnpm install @serve.zone/cli && clear && servezone info`;
|
||||||
|
|
||||||
public static styles = [
|
public static styles = [
|
||||||
cssManager.defaultStyles,
|
cssManager.defaultStyles,
|
||||||
css`
|
css`
|
||||||
@ -46,22 +49,25 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
color: ${cssManager.bdTheme('#333', '#ccc')};
|
color: ${cssManager.bdTheme('#333', '#ccc')};
|
||||||
user-select: none;
|
user-select: none;
|
||||||
display: block;
|
display: block;
|
||||||
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.maincontainer {
|
.maincontainer {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
top: 0px;
|
top: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
|
right: 0px;
|
||||||
|
bottom: 0px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appbar {
|
.appbar {
|
||||||
position: fixed;
|
position: absolute;
|
||||||
top: 0;
|
top: 0px;
|
||||||
|
left: 0px;
|
||||||
height: calc(100% - 24px);
|
height: calc(100% - 24px);
|
||||||
width: 200px;
|
width: 200px;
|
||||||
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
|
background: ${cssManager.bdTheme('#eeeeeb', '#000')};
|
||||||
@ -115,7 +121,7 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
|
|
||||||
.appcontent {
|
.appcontent {
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
position: fixed;
|
position: absolute;
|
||||||
top: 0px;
|
top: 0px;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
height: calc(100vh - 24px);
|
height: calc(100vh - 24px);
|
||||||
@ -132,6 +138,7 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
bottom: 0px;
|
bottom: 0px;
|
||||||
left: 0px;
|
left: 0px;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
border-top: 1px solid #44444480;
|
||||||
height: 24px;
|
height: 24px;
|
||||||
background: ${cssManager.bdTheme(colors.bright.blueMuted, colors.dark.blueMuted)};
|
background: ${cssManager.bdTheme(colors.bright.blueMuted, colors.dark.blueMuted)};
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
@ -192,9 +199,12 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
await this.loadView(this.viewTabs[0]);
|
await this.loadView(this.viewTabs[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public currentTerminal: DeesTerminal;
|
||||||
public async launchTerminal() {
|
public async launchTerminal() {
|
||||||
const maincontainer = this.shadowRoot.querySelector('.maincontainer');
|
const maincontainer = this.shadowRoot.querySelector('.maincontainer');
|
||||||
const terminal = new DeesTerminal();
|
const terminal = new DeesTerminal();
|
||||||
|
terminal.setupCommand = this.terminalSetupCommand;
|
||||||
|
this.currentTerminal = terminal;
|
||||||
maincontainer.appendChild(terminal);
|
maincontainer.appendChild(terminal);
|
||||||
terminal.style.position = 'absolute';
|
terminal.style.position = 'absolute';
|
||||||
terminal.style.zIndex = '1';
|
terminal.style.zIndex = '1';
|
||||||
@ -208,6 +218,7 @@ export class DeesSimpleAppDash extends DeesElement {
|
|||||||
await domtools.plugins.smartdelay.delayFor(0);
|
await domtools.plugins.smartdelay.delayFor(0);
|
||||||
terminal.style.opacity = '1';
|
terminal.style.opacity = '1';
|
||||||
terminal.style.transform = 'translateY(0px)';
|
terminal.style.transform = 'translateY(0px)';
|
||||||
|
return terminal;
|
||||||
}
|
}
|
||||||
|
|
||||||
private currentView: DeesElement;
|
private currentView: DeesElement;
|
||||||
|
@ -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;
|
||||||
|
@ -22,13 +22,25 @@ declare global {
|
|||||||
|
|
||||||
@customElement('dees-terminal')
|
@customElement('dees-terminal')
|
||||||
export class DeesTerminal extends DeesElement {
|
export class DeesTerminal extends DeesElement {
|
||||||
public static demo = () => html` <dees-terminal></dees-terminal> `;
|
public static demo = () => html` <dees-terminal
|
||||||
|
.environment=${{
|
||||||
|
NODE_ENV: 'development',
|
||||||
|
PORT: '3000',
|
||||||
|
}}
|
||||||
|
></dees-terminal> `;
|
||||||
|
|
||||||
// INSTANCE
|
// INSTANCE
|
||||||
private resizeObserver: ResizeObserver;
|
private resizeObserver: ResizeObserver;
|
||||||
|
|
||||||
@property()
|
@property()
|
||||||
public setupCommand = `pnpm install @git.zone/tsbuild && clear && echo 'welcome'`;
|
public setupCommand = `pnpm install @serve.zone/cli && servezone cli\n`;
|
||||||
|
|
||||||
|
@property()
|
||||||
|
environment: {[key: string]: string} = {};
|
||||||
|
|
||||||
|
// exposing webcontainer
|
||||||
|
private webcontainerDeferred = new domtools.plugins.smartpromise.Deferred<webcontainer.WebContainer>();
|
||||||
|
public webcontainerPromise = this.webcontainerDeferred.promise;
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
@ -282,8 +294,15 @@ export class DeesTerminal extends DeesElement {
|
|||||||
input.write(data);
|
input.write(data);
|
||||||
});
|
});
|
||||||
await this.waitForPrompt(term, '~/');
|
await this.waitForPrompt(term, '~/');
|
||||||
|
// lets set the environment variables
|
||||||
|
await this.setEnvironmentVariables(this.environment, webcontainerInstance);
|
||||||
|
input.write(`source source.env\n`);
|
||||||
|
await this.waitForPrompt(term, '~/');
|
||||||
|
// lets run the setup command
|
||||||
input.write(this.setupCommand);
|
input.write(this.setupCommand);
|
||||||
input.write(`\n`);
|
await this.waitForPrompt(term, '~/');
|
||||||
|
input.write(`clear && echo 'welcome'\n`);
|
||||||
|
this.webcontainerDeferred.resolve(webcontainerInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
async connectedCallback(): Promise<void> {
|
async connectedCallback(): Promise<void> {
|
||||||
@ -300,14 +319,16 @@ export class DeesTerminal extends DeesElement {
|
|||||||
this.fitAddon.fit();
|
this.fitAddon.fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async waitForPrompt(term: Terminal, prompt: string): Promise<void> {
|
public async waitForPrompt(term: Terminal, prompt: string): Promise<void> {
|
||||||
return new Promise<void>((resolve) => {
|
return new Promise<void>((resolve) => {
|
||||||
const checkPrompt = () => {
|
const checkPrompt = () => {
|
||||||
const lines = term.buffer.active;
|
const lines = term.buffer.active;
|
||||||
for (let i = 0; i < lines.length; i++) {
|
for (let i = 0; i < lines.length; i++) {
|
||||||
const line = lines.getLine(i);
|
const line = lines.getLine(i);
|
||||||
if (line && line.translateToString().includes(prompt)) {
|
if (line && line.translateToString().includes(prompt)) {
|
||||||
resolve();
|
setTimeout(() => {
|
||||||
|
resolve();
|
||||||
|
}, 100);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -317,4 +338,18 @@ export class DeesTerminal extends DeesElement {
|
|||||||
checkPrompt();
|
checkPrompt();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async setEnvironmentVariables(envArg: {[key: string]: string}, webcontainerInstanceArg?: webcontainer.WebContainer) {
|
||||||
|
const webcontainerInstance = webcontainerInstanceArg ||await this.webcontainerPromise;
|
||||||
|
let envFile = ``
|
||||||
|
for (const key in envArg) {
|
||||||
|
envFile += `export ${key}="${envArg[key]}"\n`;
|
||||||
|
}
|
||||||
|
|
||||||
|
await webcontainerInstance.mount({'source.env': {
|
||||||
|
file: {
|
||||||
|
contents: envFile,
|
||||||
|
}
|
||||||
|
}});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ export * from './dees-appui-base.js';
|
|||||||
export * from './dees-appui-maincontent.js';
|
export * from './dees-appui-maincontent.js';
|
||||||
export * from './dees-appui-mainmenu.js';
|
export * from './dees-appui-mainmenu.js';
|
||||||
export * from './dees-appui-mainselector.js';
|
export * from './dees-appui-mainselector.js';
|
||||||
|
export * from './dees-badge.js';
|
||||||
export * from './dees-button-exit.js';
|
export * from './dees-button-exit.js';
|
||||||
export * from './dees-button.js';
|
export * from './dees-button.js';
|
||||||
export * from './dees-chart-area.js';
|
export * from './dees-chart-area.js';
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
export * from './elements/index.js';
|
export * from './elements/index.js';
|
||||||
|
import * as colors from './elements/00colors.js';
|
||||||
|
export { colors };
|
||||||
export { commitinfo } from './00_commitinfo_data.js';
|
export { commitinfo } from './00_commitinfo_data.js';
|
||||||
|
Reference in New Issue
Block a user