2.0.1 • Published 22 days ago

@storysdk/react v2.0.1

Weekly downloads
-
License
ISC
Repository
-
Last release
22 days ago

@storysdk/react

React components and hooks for StorySDK. This package provides a comprehensive set of React components for rendering interactive stories and onboarding experiences with full TypeScript support.

Installation

npm install @storysdk/react

Note: This package automatically includes @storysdk/types as a dependency. If you're using the full SDK, install @storysdk/core instead, which includes this package.

Overview

@storysdk/react offers:

  • React Components for rendering stories and individual widgets
  • TypeScript Support with full type definitions from @storysdk/types
  • Hooks for story state management and interactions
  • Styling with customizable CSS and themes
  • Performance optimized rendering with React best practices

Package Architecture

This package depends on @storysdk/types for TypeScript definitions and provides the React layer for the StorySDK ecosystem:

@storysdk/react
└── @storysdk/types (TypeScript definitions)

Basic Usage

Simple Story Rendering

import { GroupsList } from "@storysdk/react"; 
import "@storysdk/react/dist/bundle.css";

function StoryComponent() {
  const groups = [
    {
      id: 'group-1',
      name: 'Welcome Stories',
      // ... group configuration
    }
  ];

  return (
    <GroupsList 
      groups={groups}
      token="your-app-token"
    />
  );
}

export default StoryComponent;

With TypeScript

import { GroupsList, GroupType } from "@storysdk/react";
import "@storysdk/react/dist/bundle.css";

interface StoryComponentProps {
  groups: GroupType[];
  token: string;
  onStoryComplete?: (groupId: string) => void;
}

function StoryComponent({ groups, token, onStoryComplete }: StoryComponentProps) {
  return (
    <GroupsList 
      groups={groups}
      token={token}
      onStoryComplete={onStoryComplete}
    />
  );
}

export default StoryComponent;

Components

GroupsList

Main component for rendering multiple story groups with comprehensive customization options:

import { GroupsList } from "@storysdk/react";

<GroupsList
  // Required props
  groups={groupsArray}                    // Array of GroupType
  groupView="circle"                      // 'circle' | 'square' | 'bigSquare' | 'rectangle'
  
  // Authentication
  token="your-token"                      // Your StorySDK token
  
  // Appearance customization
  groupImageWidth={68}                    // Width of group images (default: 68)
  groupImageHeight={68}                   // Height of group images (default: 68)
  groupTitleSize={16}                     // Font size for group titles (default: 16)
  activeGroupOutlineColor="#ff6b35"       // Color for active group outline
  groupsOutlineColor="#cccccc"            // Color for inactive group outlines
  backgroundColor="#ffffff"               // Background color for stories
  arrowsColor="#000000"                   // Color for navigation arrows
  
  // CSS customization
  groupClassName="custom-group"           // CSS class for individual groups
  groupsClassName="custom-groups"         // CSS class for groups container
  
  // Story display options
  storyWidth={320}                        // Story modal width
  storyHeight={568}                       // Story modal height
  isShowMockup={true}                     // Show device mockup
  isShowLabel={true}                      // Show story labels
  isStatusBarActive={true}                // Show status bar in stories
  
  // Behavior options
  autoplay={false}                        // Auto-open first story
  startGroupId="group-id"                 // ID of group to start with
  startStoryId="story-id"                 // ID of story to start with
  forbidClose={false}                     // Prevent closing stories
  isForceCloseAvailable={true}            // Show force close button
  preventCloseOnGroupClick={false}        // Prevent closing on group click
  openInExternalModal={false}             // Open in external modal
  isOnlyGroups={false}                    // Show only groups, no stories
  
  // Environment options
  isInReactNativeWebView={false}          // React Native WebView mode
  
  // Loading state
  isLoading={false}                       // Show loading state
  
  // Container reference
  container={elementRef.current}          // Container element reference
  
  // Event handlers
  onOpenGroup={(groupId) => console.log('Group opened:', groupId)}
  onCloseGroup={(groupId) => console.log('Group closed:', groupId)}
  onOpenStory={(groupId, storyId) => console.log('Story opened:', storyId)}
  onCloseStory={(groupId, storyId, duration) => console.log('Story closed:', storyId, 'Duration:', duration)}
  onNextStory={(groupId, storyId) => console.log('Next story:', storyId)}
  onPrevStory={(groupId, storyId) => console.log('Previous story:', storyId)}
  onModalOpen={(groupId, storyId) => console.log('Modal opened:', storyId)}
  onModalClose={(groupId, storyId) => console.log('Modal closed:', storyId)}
  onStartQuiz={(groupId, storyId) => console.log('Quiz started')}
  onFinishQuiz={(groupId, storyId) => console.log('Quiz finished')}
/>

GroupsList Props Reference

PropTypeDefaultDescription
groupsGroup[]requiredArray of story groups to display
groupView'circle' \| 'square' \| 'bigSquare' \| 'rectangle'requiredVisual style for group items
tokenstringundefinedStorySDK authentication token
groupImageWidthnumber68Width of group thumbnails in pixels
groupImageHeightnumber68Height of group thumbnails in pixels
groupTitleSizenumber16Font size for group titles
activeGroupOutlineColorstringundefinedHex color for active group border
groupsOutlineColorstringundefinedHex color for inactive group borders
backgroundColorstringundefinedBackground color for story modal
arrowsColorstringundefinedColor for navigation arrows
groupClassNamestringundefinedCSS class for individual group items
groupsClassNamestringundefinedCSS class for groups container
storyWidthnumberundefinedWidth of story modal
storyHeightnumberundefinedHeight of story modal
isShowMockupbooleanfalseDisplay device mockup around stories
isShowLabelbooleanfalseShow story title labels
isStatusBarActivebooleanfalseShow status bar in story view
autoplaybooleanfalseAutomatically open first story
startGroupIdstringundefinedID of group to highlight initially
startStoryIdstringundefinedID of story to open initially
forbidClosebooleanfalsePrevent users from closing stories
isForceCloseAvailablebooleantrueShow force close button
preventCloseOnGroupClickbooleanfalseDon't close modal when clicking group
openInExternalModalbooleanfalseOpen stories in external modal
isOnlyGroupsbooleanfalseOnly render groups, no story modal
isInReactNativeWebViewbooleanfalseEnable React Native WebView mode
isLoadingbooleanfalseShow loading state
containerElement \| HTMLDivElement \| nullnullContainer element reference

Individual Widget Components

For custom layouts, you can use individual widget components:

import { 
  TextWidget, 
  ImageWidget, 
  VideoWidget, 
  QuizWidget 
} from "@storysdk/react";

// Custom story layout
function CustomStoryLayout({ story }) {
  return (
    <div className="custom-story">
      {story.widgets.map(widget => {
        switch (widget.type) {
          case 'text':
            return <TextWidget key={widget.id} {...widget.params} />;
          case 'image':
            return <ImageWidget key={widget.id} {...widget.params} />;
          case 'video':
            return <VideoWidget key={widget.id} {...widget.params} />;
          case 'quiz':
            return <QuizWidget key={widget.id} {...widget.params} />;
          default:
            return null;
        }
      })}
    </div>
  );
}

Hooks

The package includes several utility hooks for enhanced React integration:

Available Hooks

  • useInterval - Provides interval functionality with React lifecycle
  • useAdaptiveValue - Adapts values based on screen size or conditions
  • useAnswersCache - Caches user answers for better performance
  • useLocalStorage - Local storage integration with React state
  • useStoryCache - Caches story data for improved loading
  • useGroupCache - Caches group data for better performance
  • useSwipe - Touch/swipe gesture handling
  • useDebounced - Debounced value updates
  • useElementSize - Track element size changes

Example Usage

import { 
  useLocalStorage, 
  useDebounced, 
  useSwipe 
} from "@storysdk/react";

function CustomStoryComponent() {
  const [viewedStories, setViewedStories] = useLocalStorage('viewedStories', []);
  const debouncedSearch = useDebounced(searchTerm, 300);
  
  const swipeHandlers = useSwipe({
    onSwipeLeft: () => console.log('Swiped left'),
    onSwipeRight: () => console.log('Swiped right'),
  });

  return (
    <div {...swipeHandlers}>
      {/* Your story content */}
    </div>
  );
}

Framework Integration

Next.js

For Next.js applications, use dynamic imports to avoid SSR issues:

import dynamic from 'next/dynamic';
import '@storysdk/react/dist/bundle.css';

// Component file (components/StoryComponent.tsx)
const StoryComponent = dynamic(
  () => import('../components/StoryComponent'),
  { 
    ssr: false,
    loading: () => <div>Loading stories...</div>
  }
);

// Page file
export default function HomePage() {
  return (
    <div>
      <h1>My Next.js App</h1>
      <StoryComponent />
    </div>
  );
}

Gatsby

// gatsby-ssr.js and gatsby-browser.js
import '@storysdk/react/dist/bundle.css';

// Component
import React from 'react';

const StoryComponent = React.lazy(() => import('../components/StoryComponent'));

function MyPage() {
  return (
    <React.Suspense fallback={<div>Loading...</div>}>
      <StoryComponent />
    </React.Suspense>
  );
}

Styling and Customization

CSS Custom Properties

Override default styling with CSS variables:

:root {
  --storysdk-primary-color: #your-brand-color;
  --storysdk-secondary-color: #your-secondary-color;
  --storysdk-border-radius: 12px;
  --storysdk-font-family: 'Your Font', sans-serif;
}

Theme Configuration

import { GroupsList, ThemeProvider } from "@storysdk/react";

const customTheme = {
  colors: {
    primary: '#ff6b35',
    secondary: '#004e64',
    background: '#ffffff',
    text: '#333333'
  },
  typography: {
    fontFamily: 'Inter, sans-serif',
    fontSize: {
      small: '14px',
      medium: '16px',
      large: '18px'
    }
  },
  spacing: {
    small: '8px',
    medium: '16px',
    large: '24px'
  }
};

function ThemedStories() {
  return (
    <ThemeProvider theme={customTheme}>
      <GroupsList groups={groups} token={token} />
    </ThemeProvider>
  );
}

Performance

Code Splitting

import { lazy, Suspense } from 'react';

// Lazy load story components
const StoryComponent = lazy(() => 
  import('@storysdk/react').then(module => ({ 
    default: module.GroupsList 
  }))
);

function App() {
  return (
    <Suspense fallback={<div>Loading stories...</div>}>
      <StoryComponent groups={groups} token={token} />
    </Suspense>
  );
}

Memory Management

import { useEffect, useRef } from 'react';
import { GroupsList } from '@storysdk/react';

function OptimizedStoryComponent({ groups, token }) {
  const storyRef = useRef(null);

  useEffect(() => {
    // Cleanup on unmount
    return () => {
      if (storyRef.current) {
        storyRef.current.destroy();
      }
    };
  }, []);

  return (
    <GroupsList
      ref={storyRef}
      groups={groups}
      token={token}
      preloadNextStory={false} // Disable preloading for memory optimization
      maxCacheSize={5}         // Limit cached stories
    />
  );
}

TypeScript Support

Full TypeScript support with types from @storysdk/types:

import { 
  GroupType, 
  WidgetType, 
  GroupsListProps,
  StoryEventHandler 
} from '@storysdk/react';

// All props are fully typed
const storyProps: GroupsListProps = {
  groups: groupsArray,  // GroupType[]
  token: 'your-token',  // string
  onStoryStart: (groupId: string) => void,
  onStoryComplete: (groupId: string) => void
};

Migration from @storysdk/core

If you're using the high-level Story class from @storysdk/core, you can optionally migrate to React components for better React integration:

// Current approach (with @storysdk/core)
import { Story } from '@storysdk/core';
import { useRef, useEffect } from 'react';

function StoryComponent({ token }) {
  const ref = useRef(null);

  useEffect(() => {
    const story = new Story(token);
    story.renderGroups(ref.current);
    
    return () => story.destroy();
  }, [token]);

  return <div ref={ref} />;
}

// Alternative approach (with @storysdk/react)
import { GroupsList } from '@storysdk/react';

function StoryComponent({ groups, token }) {
  return <GroupsList groups={groups} token={token} />;
}

Note: The @storysdk/core approach is still the recommended method for most use cases. Use @storysdk/react components directly only when you need custom layouts or fine-grained control over individual story elements.

Related Packages

Resources

1.6.4

3 months ago

1.6.3

3 months ago

1.7.9

2 months ago

1.7.8

2 months ago

1.7.7

2 months ago

1.7.5

2 months ago

1.7.4

2 months ago

1.6.8

3 months ago

1.6.6

3 months ago

1.6.5

3 months ago

2.0.1

22 days ago

2.0.0

22 days ago

1.9.1

1 month ago

1.9.0

1 month ago

1.8.2

2 months ago

1.8.1

2 months ago

1.8.0

2 months ago

1.9.3

1 month ago

1.7.0

3 months ago

1.8.7

2 months ago

1.8.6

2 months ago

1.8.5

2 months ago

1.8.4

2 months ago

1.8.3

2 months ago

1.6.2

4 months ago

1.6.1

4 months ago

1.6.0

4 months ago

1.5.5

5 months ago

1.5.4

5 months ago

1.5.3

5 months ago

1.5.2

5 months ago

1.5.1

5 months ago

1.5.0

5 months ago

1.4.6

5 months ago

1.4.5

5 months ago

1.4.4

5 months ago

1.4.2

5 months ago

1.4.1

5 months ago

1.4.0

5 months ago

1.5.9

4 months ago

1.5.8

4 months ago

1.5.7

5 months ago

1.5.6

5 months ago

1.3.7

5 months ago

1.3.6

5 months ago

1.3.5

5 months ago

1.3.4

5 months ago

1.3.3

6 months ago

1.3.2

7 months ago

1.3.1

7 months ago

1.3.0

7 months ago

1.4.8

5 months ago

1.4.7

5 months ago

1.2.0

8 months ago

1.2.8

7 months ago

1.2.6

8 months ago

1.2.2

8 months ago

1.2.1

8 months ago

1.3.8

5 months ago

1.2.9

7 months ago

1.1.9

8 months ago

1.1.8

8 months ago

1.1.7

8 months ago

1.1.6

8 months ago

1.1.5

8 months ago

1.1.4

8 months ago

1.1.3

8 months ago

1.1.2

9 months ago

1.1.1

9 months ago

1.1.0

9 months ago

1.0.2

9 months ago

1.0.9

9 months ago

1.0.8

9 months ago

1.0.7

9 months ago

1.0.6

9 months ago

1.0.5

9 months ago

1.0.4

9 months ago

1.0.3

9 months ago

1.0.1

9 months ago

1.0.0

9 months ago

0.20.1

11 months ago

0.20.0

11 months ago

0.21.8

11 months ago

0.21.7

11 months ago

0.21.6

11 months ago

0.21.5

11 months ago

0.21.4

11 months ago

0.21.3

11 months ago

0.21.2

11 months ago

0.21.1

11 months ago

0.21.9

11 months ago

0.21.0

11 months ago

0.22.7

10 months ago

0.22.6

10 months ago

0.22.5

10 months ago

0.22.4

10 months ago

0.22.3

11 months ago

0.22.2

11 months ago

0.22.1

11 months ago

0.22.0

11 months ago

0.22.9

10 months ago

0.22.8

10 months ago

0.20.9

11 months ago

0.20.8

11 months ago

0.20.7

11 months ago

0.20.6

11 months ago

0.20.4

11 months ago

0.20.2

11 months ago

0.19.8

12 months ago

0.19.9

11 months ago

0.19.4

1 year ago

0.19.5

12 months ago

0.19.6

12 months ago

0.19.7

12 months ago

0.23.0

10 months ago

0.19.3

1 year ago

0.19.2

1 year ago

0.19.0

1 year ago

0.19.1

1 year ago

0.18.9

1 year ago

0.18.11

1 year ago

0.18.10

1 year ago

0.18.12

1 year ago

0.18.7

1 year ago

0.18.8

1 year ago

0.18.6

1 year ago

0.18.4

1 year ago

0.18.3

1 year ago

0.18.2

1 year ago

0.18.1

1 year ago

0.18.0

1 year ago

0.17.6

1 year ago

0.17.2

1 year ago

0.17.3

1 year ago

0.17.4

1 year ago

0.17.5

1 year ago

0.17.0

1 year ago

0.17.1

1 year ago

0.16.9

1 year ago

0.16.8

2 years ago

0.13.6

2 years ago

0.13.7

2 years ago

0.13.8

2 years ago

0.13.9

2 years ago

0.13.0

2 years ago

0.13.1

2 years ago

0.13.2

2 years ago

0.13.3

2 years ago

0.13.4

2 years ago

0.13.5

2 years ago

0.9.8

2 years ago

0.9.7

2 years ago

0.9.9

2 years ago

0.9.4

2 years ago

0.9.6

2 years ago

0.9.5

2 years ago

0.10.9

2 years ago

0.10.1

2 years ago

0.10.2

2 years ago

0.10.3

2 years ago

0.14.0

2 years ago

0.10.4

2 years ago

0.14.1

2 years ago

0.10.5

2 years ago

0.10.6

2 years ago

0.10.7

2 years ago

0.10.8

2 years ago

0.10.0

2 years ago

0.9.10

2 years ago

0.9.11

2 years ago

0.11.8

2 years ago

0.11.9

2 years ago

0.11.0

2 years ago

0.11.1

2 years ago

0.11.2

2 years ago

0.11.3

2 years ago

0.15.0

2 years ago

0.11.4

2 years ago

0.10.10

2 years ago

0.15.1

2 years ago

0.11.5

2 years ago

0.11.6

2 years ago

0.11.7

2 years ago

0.16.3

2 years ago

0.16.4

2 years ago

0.16.5

2 years ago

0.16.6

2 years ago

0.16.7

2 years ago

0.12.0

2 years ago

0.12.1

2 years ago

0.12.2

2 years ago

0.12.3

2 years ago

0.16.0

2 years ago

0.12.4

2 years ago

0.16.1

2 years ago

0.12.5

2 years ago

0.16.2

2 years ago

0.12.6

2 years ago

0.9.3

2 years ago

0.9.0

2 years ago

0.9.2

2 years ago

0.9.1

2 years ago

0.8.9

2 years ago

0.8.8

2 years ago

0.8.5

2 years ago

0.8.4

2 years ago

0.8.7

2 years ago

0.8.6

2 years ago

0.7.7

2 years ago

0.8.10

2 years ago

0.8.1

2 years ago

0.8.0

2 years ago

0.8.3

2 years ago

0.8.2

2 years ago

0.7.6

2 years ago

0.7.4

2 years ago

0.7.3

2 years ago

0.7.5

2 years ago

0.7.2

2 years ago

0.7.1

2 years ago

0.6.7

2 years ago

0.6.6

2 years ago

0.6.9

2 years ago

0.6.8

2 years ago

0.6.10

2 years ago

0.6.12

2 years ago

0.6.11

2 years ago

0.7.0

2 years ago

0.6.3

2 years ago

0.6.5

2 years ago

0.6.4

2 years ago

0.6.2

2 years ago

0.6.1

2 years ago

0.6.0

2 years ago

0.4.9

2 years ago

0.4.8

3 years ago

0.4.10

2 years ago

0.5.4

2 years ago

0.5.3

2 years ago

0.4.7

3 years ago

0.5.5

2 years ago

0.4.6

3 years ago

0.5.0

2 years ago

0.5.2

2 years ago

0.5.1

2 years ago

0.4.5

3 years ago

0.4.4

3 years ago

0.4.3

3 years ago

0.4.1

3 years ago

0.4.0

3 years ago

0.4.2

3 years ago

0.3.6

3 years ago

0.3.5

3 years ago

0.3.2

3 years ago

0.3.1

3 years ago

0.3.4

3 years ago

0.3.0

3 years ago

0.2.8

3 years ago

0.2.7

3 years ago

0.2.6

3 years ago

0.2.5

3 years ago

0.2.4

3 years ago

0.2.3

3 years ago

0.2.2

3 years ago

0.1.9

3 years ago

0.1.8

3 years ago

0.1.7

3 years ago

0.1.6

3 years ago

0.1.5

3 years ago

0.1.5-alpha.0

3 years ago

0.1.4

3 years ago

0.1.3

3 years ago

0.1.1

3 years ago

0.1.0

3 years ago

0.0.1

3 years ago

0.1.2

3 years ago

0.2.2-alpha.0

3 years ago

0.2.1

3 years ago

0.2.0

3 years ago

0.1.1-alpha.0

3 years ago