File size: 6,335 Bytes
6c93a54 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 |
class CustomApiShowcase extends HTMLElement {
static get observedAttributes() {
return ['api-name', 'category', 'description', 'endpoint', 'docs-url'];
}
constructor() {
super();
this.apiName = 'API Name';
this.category = 'Category';
this.description = 'API description goes here.';
this.endpoint = 'https://api.example.com';
this.docsUrl = 'https://docs.example.com';
}
attributeChangedCallback(name, oldValue, newValue) {
if (oldValue !== newValue) {
this[name] = newValue;
this.render();
}
}
connectedCallback() {
this.render();
}
getCategoryColor() {
const colors = {
'Data Mocking': 'bg-blue-100 text-blue-800',
'Fun & Images': 'bg-purple-100 text-purple-800',
'Weather Data': 'bg-green-100 text-green-800',
'Finance': 'bg-emerald-100 text-emerald-800',
'Social': 'bg-pink-100 text-pink-800',
'Development': 'bg-orange-100 text-orange-800',
'Business': 'bg-indigo-100 text-indigo-800'
};
return colors[this.category] || 'bg-gray-100 text-gray-800';
}
render() {
const categoryColor = this.getCategoryColor();
this.attachShadow({ mode: 'open' });
this.shadowRoot.innerHTML = `
<style>
:host {
display: block;
}
.api-card {
transition: all 0.3s ease;
}
.api-card:hover {
transform: translateX(5px);
}
.endpoint-box {
font-family: 'Monaco', 'Menlo', 'Ubuntu Mono', monospace;
}
.copy-btn {
transition: all 0.2s ease;
}
.copy-btn:hover {
transform: scale(1.05);
}
.copy-btn:active {
transform: scale(0.95);
}
</style>
<div class="api-card bg-white rounded-xl border border-gray-200 p-6 hover:border-blue-300 hover:shadow-xl">
<div class="flex flex-col md:flex-row md:items-start md:justify-between mb-4">
<div class="mb-4 md:mb-0 md:mr-6">
<div class="flex items-center space-x-3 mb-2">
<h3 class="text-xl font-bold text-gray-900">${this.apiName}</h3>
<span class="px-3 py-1 rounded-full text-xs font-semibold ${categoryColor}">
${this.category}
</span>
</div>
<p class="text-gray-600">${this.description}</p>
</div>
<div class="flex space-x-3">
<a href="${this.docsUrl}" target="_blank" class="inline-flex items-center px-4 py-2 bg-blue-50 hover:bg-blue-100 text-blue-600 font-medium rounded-lg transition duration-300">
<i data-feather="book-open" class="w-4 h-4 mr-2"></i>
Docs
</a>
<a href="/try?api=${encodeURIComponent(this.apiName)}" class="inline-flex items-center px-4 py-2 bg-gradient-to-r from-blue-500 to-purple-500 hover:from-blue-600 hover:to-purple-600 text-white font-medium rounded-lg transition duration-300 shadow-md hover:shadow-lg">
<i data-feather="play" class="w-4 h-4 mr-2"></i>
Try It
</a>
</div>
</div>
<div class="mt-6">
<div class="flex items-center justify-between mb-2">
<span class="text-sm font-medium text-gray-500">Endpoint</span>
<button class="copy-btn flex items-center text-sm text-blue-600 hover:text-blue-800 font-medium" data-copy="${this.endpoint}">
<i data-feather="copy" class="w-4 h-4 mr-1"></i>
Copy
</button>
</div>
<div class="endpoint-box bg-gray-50 border border-gray-200 rounded-lg p-4 overflow-x-auto">
<code class="text-sm text-gray-800">${this.endpoint}</code>
</div>
</div>
<div class="mt-6 flex items-center text-sm text-gray-500">
<div class="flex items-center mr-6">
<i data-feather="zap" class="w-4 h-4 mr-2 text-green-500"></i>
<span>99.9% Uptime</span>
</div>
<div class="flex items-center mr-6">
<i data-feather="clock" class="w-4 h-4 mr-2 text-blue-500"></i>
<span><100ms Response</span>
</div>
<div class="flex items-center">
<i data-feather="shield" class="w-4 h-4 mr-2 text-purple-500"></i>
<span>HTTPS Only</span>
</div>
</div>
</div>
`;
// Add copy functionality
const copyBtn = this.shadowRoot.querySelector('.copy-btn');
if (copyBtn) {
copyBtn.addEventListener('click', async () => {
const textToCopy = copyBtn.getAttribute('data-copy');
try {
await navigator.clipboard.writeText(textToCopy);
const originalHTML = copyBtn.innerHTML;
copyBtn.innerHTML = '<i data-feather="check" class="w-4 h-4 mr-1"></i>Copied!';
feather.replace();
setTimeout(() => {
copyBtn.innerHTML = originalHTML;
feather.replace();
}, 2000);
} catch (err) {
console.error('Failed to copy:', err);
}
});
}
// Initialize icons in shadow DOM
setTimeout(() => {
feather.replace();
}, 100);
}
}
customElements.define('custom-api-showcase', CustomApiShowcase); |