Skip to content

Add optional width and height props to skeleton components #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
/node_modules
/dist
/distdemo.html
23 changes: 17 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,29 @@ npm i react-iskelet
```tsx
import Skeleton from "react-iskelet";

<Skeleton type={option} />;
<Skeleton type="text" count={5} />;
// Basic usage
<Skeleton type="text" />
<Skeleton type="text" count={5} />

// Custom dimensions
<Skeleton type="avatar" width={80} height={80} />
<Skeleton type="thumbnail" width="10rem" height="8rem" />
<Skeleton type="text" width="50%" height="1rem" />

// Multiple items with custom size
<Skeleton type="text" count={3} width="90%" height="0.8rem" />
```

Skeleton component extended with **div** element, allows manipulating **div** attributes like `className.`

## Props

| Props | Type | Required |
| ------ | ------ | -------- |
| type | Type | ✓ |
| count? | number | ✖ |
| Props | Type | Required | Description |
| ------- | ---------------- | -------- | ----------- |
| type | Type | ✓ | Skeleton type (text, title, thumbnail, avatar) |
| count? | number | ✖ | Number of skeleton items to render |
| width? | string \| number | ✖ | Custom width (px as number or any CSS value as string) |
| height? | string \| number | ✖ | Custom height (px as number or any CSS value as string) |

## Available Types

Expand Down
345 changes: 345 additions & 0 deletions demo.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,345 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>React Iskelet - Skeleton Components Demo</title>
<style>
body {
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif;
margin: 0;
padding: 20px;
background: #f8fafc;
line-height: 1.6;
}
.demo-container {
max-width: 1200px;
margin: 0 auto;
background: white;
border-radius: 8px;
padding: 24px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, 0.1);
}
.demo-title {
font-size: 2rem;
font-weight: bold;
margin-bottom: 8px;
color: #1f2937;
text-align: center;
}
.demo-subtitle {
color: #6b7280;
margin-bottom: 32px;
font-size: 1.1rem;
text-align: center;
}
.demo-section {
margin-bottom: 48px;
border-bottom: 1px solid #e5e7eb;
padding-bottom: 32px;
}
.demo-section:last-child {
border-bottom: none;
}
.section-title {
font-size: 1.5rem;
font-weight: 600;
margin-bottom: 16px;
color: #374151;
}
.section-description {
color: #6b7280;
margin-bottom: 24px;
font-size: 0.95rem;
}
.demo-grid {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
gap: 24px;
}
.demo-item {
padding: 20px;
border: 1px solid #e5e7eb;
border-radius: 6px;
background: #fafafa;
}
.demo-item-title {
font-weight: 600;
margin-bottom: 12px;
color: #374151;
font-size: 0.9rem;
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
background: #f3f4f6;
padding: 8px;
border-radius: 4px;
border-left: 3px solid #3b82f6;
}
.comparison-grid {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 24px;
}
.before-after {
padding: 16px;
border: 1px solid #e5e7eb;
border-radius: 6px;
}
.before-after h4 {
margin: 0 0 12px 0;
color: #374151;
font-size: 1rem;
font-weight: 600;
}
.code-example {
background: #f3f4f6;
padding: 12px;
border-radius: 4px;
font-family: 'SF Mono', 'Monaco', 'Inconsolata', 'Roboto Mono', monospace;
font-size: 0.8rem;
color: #374151;
margin-bottom: 12px;
border-left: 3px solid #3b82f6;
}

/* Skeleton styles - directly embedded */
@keyframes pulse {
50% {
opacity: 0.5;
}
}

.skeleton__thumbnail {
border-radius: 0.5rem;
height: 6rem;
width: 6rem;
background-color: #d1d5db;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
margin-bottom: 1rem;
}

.skeleton__text {
height: 0.75rem;
width: 100%;
border-radius: 0.375rem;
background-color: #d1d5db;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
margin-bottom: 0.5rem;
}

.skeleton__title {
width: 50%;
height: 1.25rem;
margin-bottom: 1rem;
border-radius: 0.375rem;
background-color: #d1d5db;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
}

.skeleton__avatar {
border-radius: 9999px;
background-color: #d1d5db;
animation: pulse 2s cubic-bezier(0.4, 0, 0.6, 1) infinite;
margin-bottom: 1rem;
height: 6rem;
width: 6rem;
}

.multiple-container {
display: flex;
flex-direction: column;
gap: 8px;
}

.multiple-avatars {
display: flex;
gap: 12px;
}
</style>
</head>
<body>
<div class="demo-container">
<h1 class="demo-title">React Iskelet - Skeleton Components</h1>
<p class="demo-subtitle">Demonstration of skeleton components with customizable width and height props</p>

<div class="demo-section">
<h2 class="section-title">Default Skeleton Components</h2>
<p class="section-description">Standard skeleton components using default CSS dimensions</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="text" /&gt;</div>
<div class="skeleton__text"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="title" /&gt;</div>
<div class="skeleton__title"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="avatar" /&gt;</div>
<div class="skeleton__avatar"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="thumbnail" /&gt;</div>
<div class="skeleton__thumbnail"></div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Custom Dimensions with Numbers (px)</h2>
<p class="section-description">Skeleton components with custom pixel dimensions using number values</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="text" width={400} height={20} /&gt;</div>
<div class="skeleton__text" style="width: 400px; height: 20px;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="title" width={250} height={30} /&gt;</div>
<div class="skeleton__title" style="width: 250px; height: 30px;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="avatar" width={80} height={80} /&gt;</div>
<div class="skeleton__avatar" style="width: 80px; height: 80px;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="thumbnail" width={120} height={150} /&gt;</div>
<div class="skeleton__thumbnail" style="width: 120px; height: 150px;"></div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Custom Dimensions with CSS Values</h2>
<p class="section-description">Skeleton components with custom CSS string dimensions</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="text" width="75%" height="1rem" /&gt;</div>
<div class="skeleton__text" style="width: 75%; height: 1rem;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="title" width="50%" height="1.5rem" /&gt;</div>
<div class="skeleton__title" style="width: 50%; height: 1.5rem;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="avatar" width="5rem" height="5rem" /&gt;</div>
<div class="skeleton__avatar" style="width: 5rem; height: 5rem;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="thumbnail" width="8rem" height="10rem" /&gt;</div>
<div class="skeleton__thumbnail" style="width: 8rem; height: 10rem;"></div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Multiple Items with Custom Dimensions</h2>
<p class="section-description">Using the count prop with custom dimensions</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="text" count={3} width="90%" height="0.8rem" /&gt;</div>
<div class="multiple-container">
<div class="skeleton__text" style="width: 90%; height: 0.8rem;"></div>
<div class="skeleton__text" style="width: 90%; height: 0.8rem;"></div>
<div class="skeleton__text" style="width: 90%; height: 0.8rem;"></div>
</div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="avatar" count={2} width={60} height={60} /&gt;</div>
<div class="multiple-avatars">
<div class="skeleton__avatar" style="width: 60px; height: 60px;"></div>
<div class="skeleton__avatar" style="width: 60px; height: 60px;"></div>
</div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Partial Customization</h2>
<p class="section-description">Customizing only width or height while keeping the other dimension default</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="title" width="75%" /&gt;</div>
<div class="skeleton__title" style="width: 75%;"></div>
</div>
<div class="demo-item">
<div class="demo-item-title">&lt;Skeleton type="avatar" height={100} /&gt;</div>
<div class="skeleton__avatar" style="height: 100px;"></div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Before/After Comparison</h2>
<p class="section-description">Side-by-side comparison showing backward compatibility</p>
<div class="comparison-grid">
<div class="before-after">
<h4>Before (Default)</h4>
<div class="code-example">&lt;Skeleton type="avatar" /&gt;</div>
<div class="skeleton__avatar"></div>
</div>
<div class="before-after">
<h4>After (Custom)</h4>
<div class="code-example">&lt;Skeleton type="avatar" width={100} height={100} /&gt;</div>
<div class="skeleton__avatar" style="width: 100px; height: 100px;"></div>
</div>
</div>
</div>

<div class="demo-section">
<h2 class="section-title">Real-world Usage Examples</h2>
<p class="section-description">Common use cases showing how the width and height props work in practice</p>
<div class="demo-grid">
<div class="demo-item">
<div class="demo-item-title">User Profile Card</div>
<div style="display: flex; gap: 16px; align-items: center;">
<div class="skeleton__avatar" style="width: 64px; height: 64px;"></div>
<div style="flex: 1;">
<div class="skeleton__title" style="width: 80%; height: 1.2rem; margin-bottom: 8px;"></div>
<div class="skeleton__text" style="width: 60%; height: 0.9rem;"></div>
</div>
</div>
</div>

<div class="demo-item">
<div class="demo-item-title">Article Card</div>
<div>
<div class="skeleton__thumbnail" style="width: 100%; height: 140px; margin-bottom: 12px;"></div>
<div class="skeleton__title" style="width: 90%; height: 1.4rem; margin-bottom: 8px;"></div>
<div class="skeleton__text" style="width: 100%; height: 0.8rem; margin-bottom: 4px;"></div>
<div class="skeleton__text" style="width: 75%; height: 0.8rem;"></div>
</div>
</div>

<div class="demo-item">
<div class="demo-item-title">Navigation Items</div>
<div style="display: flex; flex-direction: column; gap: 12px;">
<div class="skeleton__text" style="width: 100%; height: 2.5rem; border-radius: 6px;"></div>
<div class="skeleton__text" style="width: 100%; height: 2.5rem; border-radius: 6px;"></div>
<div class="skeleton__text" style="width: 100%; height: 2.5rem; border-radius: 6px;"></div>
</div>
</div>

<div class="demo-item">
<div class="demo-item-title">Table Rows</div>
<div style="display: flex; flex-direction: column; gap: 8px;">
<div style="display: flex; gap: 12px;">
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 40%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
</div>
<div style="display: flex; gap: 12px;">
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 40%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
</div>
<div style="display: flex; gap: 12px;">
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 40%; height: 1.5rem;"></div>
<div class="skeleton__text" style="width: 30%; height: 1.5rem;"></div>
</div>
</div>
</div>
</div>
</div>
</div>
</body>
</html>
Loading