skelayzr
v0.0.1
Published
Skelayzr dynamically wraps any component or DOM element in responsive skeleton loaders. It auto-generates loaders based on the element's structure and layout, providing a smooth and consistent loading experience with elegant, soft colors that blend seamle
Maintainers
Readme
Skelayzr 🦴
⚠️ Warning: Under Development - This repository is currently under active development. Use at your own risk for production applications.
Skelayzr your UI – load beautifully, by default.
Skelayzr dynamically wraps any component or DOM element in responsive skeleton loaders. It auto-generates loaders based on the element's structure and layout, providing a smooth and consistent loading experience with elegant, soft colors that blend seamlessly with modern UI designs.
✨ Features
- 🎯 Auto-detect dimensions from live DOM elements with intelligent caching
- 🧠 Content-aware placeholders (text, image, avatar, button, etc.)
- 🎨 Beautiful themes: shimmer, solid, pulse with soft, modern colors
- 📦 Lightweight & modular TypeScript-first architecture
- ♿ Accessible by design (
aria-busy, reduced motion, screen reader support) - ⚡ Performance optimized with IntersectionObserver and smart caching
- 🎛️ Layout intelligence (CSS Grid, Flexbox, aspect ratio preservation)
- 🛡️ Graceful degradation and comprehensive error handling
- 🔧 Full TypeScript support with complete type safety
- 🚀 Framework integrations (React hook included, Vue/Angular ready)
🚀 Quick Start
Installation
npm install skelayzr
# or
yarn add skelayzr
# or
pnpm add skelayzr
# or
bun add skelayzrBasic Usage
Vanilla JavaScript/TypeScript
<div id="profile">
<img src="avatar.jpg" alt="Avatar" />
<h2>Jane Doe</h2>
<p>Senior Frontend Developer</p>
</div>import { skelayzr } from 'skelayzr';
import 'skelayzr/styles';
// Wrap element with skeleton (uses soft, modern colors)
skelayzr('#profile', {
theme: 'shimmer',
loading: true
});
// Toggle loading state with options
skelayzr.setLoading('#profile', false);
// Or with custom delay
skelayzr.setLoading('#profile', true, { delay: 0 });React Hook
import { useSkelayzr } from 'skelayzr/react';
function Profile({ loading, user }) {
const { ref } = useSkelayzr({ loading, theme: 'shimmer' });
return (
<div ref={ref}>
<img src={user.avatar} alt="Avatar" />
<h2>{user.name}</h2>
<p>{user.bio}</p>
</div>
);
}📖 API Reference
Core Functions
skelayzr(element, options)
Main function to wrap an element with a skeleton loader.
import { skelayzr, type SkelayzrOptions } from 'skelayzr';
const options: SkelayzrOptions = {
theme: 'shimmer',
loading: true,
delay: 150
};
const instance = skelayzr('#my-element', options);Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| theme | 'shimmer' \| 'solid' \| 'pulse' \| 'custom' | 'shimmer' | Skeleton animation theme |
| loading | boolean | false | Whether to show skeleton immediately |
| delay | number | 150 | Delay before showing skeleton (ms) |
| cacheStrategy | 'lazy' \| 'eager' \| 'manual' | 'lazy' | Skeleton caching strategy |
| resizeDebounce | number | 300 | Resize event debounce time (ms) |
| intersectionThreshold | number | 0.1 | Intersection observer threshold |
| exclude | string[] | [] | CSS selectors to exclude |
| gracefulDegradation | boolean | true | Handle errors gracefully |
| debug | boolean | false | Enable debug mode |
| onError | function | - | Error callback function |
Utility Functions
// Set loading state
skelayzr.setLoading(element, true);
// Remove skeleton
skelayzr.unwrap(element);
// Auto-scan elements
skelayzr.scan('.skelayzr-auto');
// Cache management
skelayzr.cache.clear();
skelayzr.cache.getSize();
// Get statistics
const stats = skelayzr.getStats();
// Clean up everything
skelayzr.destroy();Presets
Pre-configured options for common UI patterns:
// Card layout preset
skelayzr('#card', skelayzr.presets.card());
// List/feed preset
skelayzr('#list', skelayzr.presets.list());
// Form preset
skelayzr('#form', skelayzr.presets.form());🎨 Themes & Colors
Built-in Themes
Skelayzr comes with beautiful, soft themes that blend seamlessly with modern UI:
shimmer– Elegant gradient shimmer animation with soft highlightssolid– Clean static blocks with gentle colors (#f1f3f4)pulse– Smooth breathing animationcustom– Use your own CSS classes
Modern Color Palette
/* Light mode - soft, modern colors */
--skeleton-bg: #f1f3f4;
--skeleton-highlight: rgba(255, 255, 255, 0.6);
/* Dark mode - elegant dark theme */
--skeleton-bg: #e5e7ea;
--skeleton-highlight: rgba(240, 240, 240, 0.15);Custom Themes
.skelayzr.my-custom-theme {
--skeleton-bg: #f8fafc;
--skeleton-highlight: rgba(255, 255, 255, 0.8);
background: var(--skeleton-bg);
}skelayzr('#element', { theme: 'my-custom-theme' });⚛️ React Integration
useSkelayzr Hook
import { useSkelayzr } from 'skelayzr/react';
function MyComponent({ isLoading, data }) {
const { ref, setLoading } = useSkelayzr({
loading: isLoading,
theme: 'shimmer',
delay: 200
});
// Programmatically control loading
const handleRefresh = () => {
setLoading(true);
fetchData().finally(() => setLoading(false));
};
return (
<div ref={ref}>
<h1>{data?.title}</h1>
<p>{data?.description}</p>
<button onClick={handleRefresh}>Refresh</button>
</div>
);
}🎛️ Advanced Configuration
Layout Intelligence
skelayzr('#complex-layout', {
layoutHints: {
preserveGrid: true,
respectFlexGrow: true,
maintainAspectRatio: true,
adaptToContainer: true
}
});Content Type Detection
skelayzr('#content', {
contentTypes: {
avatar: {
selectors: ['.avatar', '[data-avatar]'],
aspectRatio: 1
},
cardTitle: {
selectors: ['h1', 'h2', '.title'],
lineClamp: 1
},
paragraph: {
selectors: ['p', '.description'],
lineClamp: 3
}
}
});🔧 Performance Optimization
Intersection Observer
Skelayzr automatically uses IntersectionObserver to only create skeletons for visible elements:
skelayzr('#list-container', {
intersectionThreshold: 0.1, // Trigger when 10% visible
cacheStrategy: 'lazy' // Cache skeletons for better performance
});Smart Caching
Skelayzr intelligently caches skeleton DOM elements to boost performance:
// Cache similar skeletons automatically
skelayzr('.card', { loading: true }); // Creates and caches
skelayzr('.card2', { loading: true }); // Reuses cached skeleton!
// Manual cache management
skelayzr.cache.clear(); // Clear all cached skeletons
console.log(`Cache size: ${skelayzr.cache.getSize()}`); // Check cache stats
// Cache strategies
const engine = skelayzr.createEngine({
cacheStrategy: 'eager' // 'lazy' | 'eager' | 'manual'
});Cache Benefits:
- ⚡ Faster rendering for similar elements
- 🧠 Smart reuse based on dimensions + content type + theme
- 💾 Memory efficient with automatic cleanup (max 100 items)
- 📊 Performance tracking via
skelayzr.getStats()
♿ Accessibility
Skelayzr follows accessibility best practices:
- Adds
aria-busy="true"to skeleton elements - Provides
aria-label="Loading content" - Respects
prefers-reduced-motion - Maintains focus management
- Supports high contrast mode
🧪 Testing
Skelayzr has a comprehensive test suite with 37 passing tests:
# Run all tests
npm test
# Run tests with UI
npm run test:ui
# Run tests with coverage
npm run test:coverage
# Start demo server
npm run demoTesting with Skelayzr
import { skelayzr } from 'skelayzr';
import { render, screen } from '@testing-library/react';
test('should show skeleton while loading', () => {
const { container } = render(<MyComponent loading={true} />);
expect(container.querySelector('.skelayzr')).toBeInTheDocument();
expect(screen.getByLabelText('Loading content')).toBeInTheDocument();
});
test('should cache skeleton for performance', () => {
const element = document.createElement('div');
skelayzr(element, { loading: true });
const stats = skelayzr.getStats();
expect(stats.cacheSize).toBeGreaterThan(0);
});📊 Browser Support
- Chrome/Edge 88+
- Firefox 87+
- Safari 14+
- React 16.8+ (for React integration)
🤝 Contributing
We welcome contributions! Please see our Contributing Guide for details.
- Fork the repository
- Create your feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
📄 License
MIT © arnonsang
🙏 Acknowledgments
- Inspired by modern loading patterns in React, Vue, and Angular ecosystems
- Built with TypeScript for better developer experience
- Designed with accessibility and performance in mind
🚀 Quick Demo
Try Skelayzr locally:
git clone <repo-url>
cd skelayzr
npm install
npm run build
npm run demoVisit:
http://localhost:8080- Full ES module demohttp://localhost:8080/demo-standalone.html- Standalone demo
Made with ❤️ using TypeScript • 🐛 Issues • 🤝 Contributing
