Skip to content

Xoboto/stackview.ts

Folders and files

NameName
Last commit message
Last commit date

Latest commit

Β 

History

3 Commits
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

StackView.ts

npm version License: MIT TypeScript

A lightweight TypeScript library for managing DOM history with smooth transitions and view chaining. Build beautiful, animated navigation experiences with zero dependencies.

✨ Features

  • 🎯 Simple API - Intuitive methods for view management
  • 🎨 Smooth Transitions - Built-in fade, slide, and scale effects
  • πŸ”Œ Custom Transitions - Easy registration of custom transition effects
  • πŸ”„ Lifecycle Hooks - Control view behavior with lifecycle methods
  • πŸ“± Web Components - Standard Custom Elements API
  • 🎭 Back Button - Built-in navigation with customizable appearance
  • πŸͺΆ Lightweight - Pure TypeScript with zero dependencies
  • πŸŽͺ View Chaining - Multiple stack views working together
  • πŸŽ›οΈ Configurable - Attributes and properties for easy customization

πŸ“¦ Installation

npm install stackview.ts

πŸš€ Quick Start

HTML

<stack-view id="myStack" effect="slide"></stack-view>

<script type="module">
  import StackView from './dist/stackview.js';
  
  const stackView = document.getElementById('myStack');
  
  // Create a view
  const view = document.createElement('div');
  view.innerHTML = '<h1>Hello World!</h1>';
  
  // Show it with animation
  await stackView.begin(view);
  
  // Go back
  await stackView.complete();
</script>

TypeScript

import StackView from 'stackview.ts';

const stackView = document.getElementById('myStack') as StackView;

// Create and show a view
const view = document.createElement('div');
view.innerHTML = '<h1>Welcome!</h1>';
await stackView.begin(view, 'fade', { duration: 500 });

// Navigate back
await stackView.complete();

πŸ“– API Documentation

Properties

effect

Get or set the default transition effect.

stackView.effect = "slide"; // Set via JavaScript
<stack-view effect="fade"></stack-view> <!-- Set via HTML -->

Available effects: fade, slide, scale (or custom registered effects)

backButton

Show or hide the back/close button.

stackView.backButton = false; // Hide button
<stack-view back-button="false"></stack-view>

backButtonText

Customize the back button text.

stackView.backButtonText = "← Back";
<stack-view back-button-text="β€Ή Back"></stack-view>

closeButtonText

Customize the close button text (shown when no history).

stackView.closeButtonText = "βœ• Close";
<stack-view close-button-text="Γ— Close"></stack-view>

Methods

begin(element, effectKey?, transition?)

Show a new view with optional transition effect.

await stackView.begin(element);
await stackView.begin(element, 'slide');
await stackView.begin(element, 'fade', { duration: 600, easing: 'ease-in-out' });

Parameters:

  • element: HTMLElement - The view element to show
  • effectKey?: string - Transition effect key (optional)
  • transition?: Partial<ViewTransition> - Transition settings (optional)

complete()

Go back to the previous view or close if no history.

await stackView.complete();

canGoBack()

Check if there are previous views in history.

if (stackView.canGoBack()) {
  await stackView.complete();
}

getCurrentView()

Get the currently visible view element.

const currentView = stackView.getCurrentView();

getHistory()

Get the view history array.

const history = stackView.getHistory();
console.log(`${history.length} views in history`);

goBack(steps?)

Go back multiple steps in history.

await stackView.goBack(2); // Go back 2 views

clearHistory()

Clear all view history.

stackView.clearHistory();

terminateView(element)

Remove a specific view from the stack.

await stackView.terminateView(someElement);

setDefaultTransition(transition)

Set default transition settings for all views.

stackView.setDefaultTransition({
  duration: 400,
  easing: 'cubic-bezier(0.4, 0, 0.2, 1)'
});

Static Methods

StackView.registerTransition(key, effect)

Register a custom transition effect.

StackView.registerTransition('flip', {
  enter: (element) => {
    element.style.transform = 'rotateY(90deg)';
    element.style.opacity = '0';
  },
  exit: (element) => {
    element.style.transform = 'rotateY(-90deg)';
    element.style.opacity = '0';
  },
  cleanup: (element) => {
    element.style.transform = '';
    element.style.opacity = '';
  }
});

// Use it
await stackView.begin(view, 'flip');

🎭 Lifecycle Methods

Implement these optional methods on your view elements to hook into the lifecycle:

class MyView extends HTMLElement {
  async stackViewShowing(stackView: StackView): Promise<void> {
    console.log('View is about to be shown');
    // Initialize data, setup listeners, etc.
  }
  
  async stackViewHiding(stackView: StackView): Promise<void> {
    console.log('View is about to be hidden');
    // Validate data, confirm navigation, etc.
  }
  
  async stackViewHidden(stackView: StackView): Promise<void> {
    console.log('View has been hidden');
    // Cleanup resources, save state, etc.
  }
}

🎨 Built-in Transitions

Fade

Smooth opacity transition.

await stackView.begin(view, 'fade');

Slide

Horizontal slide animation.

await stackView.begin(view, 'slide');

Scale

Scale with opacity animation.

await stackView.begin(view, 'scale');

🎯 Examples

Basic Navigation

const view1 = document.createElement('div');
view1.innerHTML = '<h1>First View</h1>';
await stackView.begin(view1);

const view2 = document.createElement('div');
view2.innerHTML = '<h1>Second View</h1>';
await stackView.begin(view2, 'slide');

// Go back
await stackView.complete(); // Returns to view1

Custom Transition with Settings

await stackView.begin(view, 'fade', {
  duration: 800,
  easing: 'ease-in-out'
});

Multi-Step Navigation

// Navigate forward multiple times
await stackView.begin(step1View);
await stackView.begin(step2View);
await stackView.begin(step3View);

// Go back 2 steps
await stackView.goBack(2);

View with Lifecycle Hooks

class ProfileView extends HTMLElement {
  async stackViewShowing(stackView: StackView): Promise<void> {
    // Load user data
    const userData = await fetch('/api/user').then(r => r.json());
    this.innerHTML = `<h1>${userData.name}</h1>`;
  }
  
  async stackViewHidden(stackView: StackView): Promise<void> {
    // Save changes
    await this.saveProfile();
  }
}

customElements.define('profile-view', ProfileView);

const profile = document.createElement('profile-view');
await stackView.begin(profile);

Customized Appearance

<stack-view 
  effect="slide"
  back-button="true"
  back-button-text="β¬… Back"
  close-button-text="βœ•">
</stack-view>
stackView.effect = "scale";
stackView.backButton = false; // Hide button
stackView.backButtonText = "← Previous";

πŸŽͺ Advanced Usage

Custom Transition Effect

// Register a custom bounce effect
StackView.registerTransition('bounce', {
  enter: (element) => {
    element.style.transform = 'scale(0.3)';
    element.style.opacity = '0';
  },
  exit: (element) => {
    element.style.transform = 'scale(1.5)';
    element.style.opacity = '0';
  },
  cleanup: (element) => {
    element.style.transform = '';
    element.style.opacity = '';
  }
});

// Use with custom timing
await stackView.begin(view, 'bounce', {
  duration: 600,
  easing: 'cubic-bezier(0.68, -0.55, 0.265, 1.55)'
});

View Chaining

// Create multiple stack views that work together
const mainStack = document.getElementById('mainStack') as StackView;
const modalStack = document.getElementById('modalStack') as StackView;

// Show main content
await mainStack.begin(homeView);

// Show modal on top
await modalStack.begin(settingsView);

🎨 Styling

The component automatically adds minimal default styles (display: block). You can override with CSS:

stack-view {
  width: 100%;
  height: 100vh;
  background: #f5f5f5;
  border-radius: 8px;
}

.stackview-item {
  padding: 20px;
}

.stackview-back-button {
  background: #3498db;
  color: white;
  font-size: 18px;
}

πŸ“š TypeScript Support

Full TypeScript support with type definitions included:

import StackView, { 
  ViewTransition, 
  TransitionEffect, 
  ViewHistoryItem 
} from 'stackview.ts';

// Type-safe API
const stackView: StackView = document.getElementById('stack') as StackView;

// Custom transition with types
const customEffect: TransitionEffect = {
  enter: (element: HTMLElement) => { /* ... */ },
  exit: (element: HTMLElement) => { /* ... */ },
  cleanup: (element: HTMLElement) => { /* ... */ }
};

StackView.registerTransition('custom', customEffect);

🌐 Browser Support

  • Chrome/Edge 80+
  • Firefox 75+
  • Safari 13+
  • Modern browsers with Custom Elements support

πŸ“„ License

MIT Β© Xoboto

🀝 Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

πŸ“ž Support

⭐ Show Your Support

Give a ⭐️ if this project helped you!


Made with ❀️ by Xoboto