293 lines
8.5 KiB
TypeScript
293 lines
8.5 KiB
TypeScript
import { html } from '@design.estate/dees-element';
|
|
import { icons, type IconWithPrefix } from './dees-icon.js';
|
|
import * as lucideIcons from 'lucide';
|
|
|
|
export const demoFunc = () => {
|
|
// Group FontAwesome icons by type
|
|
const faIcons = Object.keys(icons.fa);
|
|
|
|
// Extract Lucide icons from the lucideIcons object directly
|
|
// Log the first few keys to understand the structure
|
|
console.log('First few Lucide keys:', Object.keys(lucideIcons).slice(0, 5));
|
|
|
|
// Get all icon functions from lucideIcons (they have PascalCase names)
|
|
const lucideIconsList = Object.keys(lucideIcons)
|
|
.filter(key => {
|
|
// Skip utility functions and focus on icon components (first letter is uppercase)
|
|
const isUppercaseFirst = key[0] === key[0].toUpperCase() && key[0] !== key[0].toLowerCase();
|
|
const isFunction = typeof lucideIcons[key] === 'function';
|
|
const notUtility = !['createElement', 'createIcons', 'default'].includes(key);
|
|
return isFunction && isUppercaseFirst && notUtility;
|
|
})
|
|
.map(pascalName => {
|
|
// Convert PascalCase to camelCase
|
|
return pascalName.charAt(0).toLowerCase() + pascalName.slice(1);
|
|
});
|
|
|
|
// Log how many icons we found
|
|
console.log(`Found ${lucideIconsList.length} Lucide icons`);
|
|
|
|
// If we didn't find any, try an alternative approach
|
|
if (lucideIconsList.length === 0) {
|
|
console.log('Trying alternative approach to find Lucide icons');
|
|
|
|
// Try to get icon names from a known property if available
|
|
if (lucideIcons.icons) {
|
|
const iconSource = lucideIcons.icons || {};
|
|
lucideIconsList.push(...Object.keys(iconSource));
|
|
console.log(`Found ${lucideIconsList.length} icons via alternative method`);
|
|
}
|
|
}
|
|
|
|
// 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: 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: all 0.2s ease;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.iconContainer {
|
|
display: flex;
|
|
flex-direction: column;
|
|
align-items: center;
|
|
padding: 20px 16px 0px 16px;
|
|
border: 1px solid #333333;
|
|
margin-right: 10px;
|
|
margin-bottom: 10px;
|
|
border-radius: 4px;
|
|
transition: background-color 0.2s;
|
|
cursor: pointer;
|
|
position: relative;
|
|
}
|
|
|
|
.iconContainer:hover {
|
|
background-color: #222;
|
|
}
|
|
|
|
.iconName {
|
|
font-size: 12px;
|
|
text-align: center;
|
|
color: #ccc;
|
|
background: #333333;
|
|
padding: 6px 10px;
|
|
margin-left: -16px;
|
|
margin-right: -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">
|
|
<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>
|
|
`;
|
|
};
|