npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@smarterservices/smarter-elements

v1.0.24

Published

Embeddable UI components for SmarterServices

Readme

SmarterElements

Embeddable UI components for SmarterServices that can be integrated into any web application. Built with TypeScript for type safety and better developer experience.

Installation

For Node.js/React Applications

npm install @smarterservices/smarter-elements

or

yarn add @smarterservices/smarter-elements

This will install the package with React as an external dependency, which means it will use your application's React instance.

For Direct Browser Usage

For direct usage in browsers without a build step, include the browser bundle script from unpkg:

<!-- Latest version -->  
<script src="https://unpkg.com/@smarterservices/smarter-elements/dist/browser.js"></script>

<!-- Specific version (recommended for production) -->  
<script src="https://unpkg.com/@smarterservices/[email protected]/dist/browser.js"></script>

<!-- Latest in a major version -->  
<script src="https://unpkg.com/@smarterservices/smarter-elements@1/dist/browser.js"></script>

<!-- Latest in a minor version -->  
<script src="https://unpkg.com/@smarterservices/[email protected]/dist/browser.js"></script>

TypeScript Support

TypeScript type definitions are included in the package. No additional type installations are required.

import SmarterElements from '@smarterservices/smarter-elements';

// Create a new instance with TypeScript type checking
const elements = SmarterElements({
  baseUrl: 'https://your-smarterproctoring-url.com',
});

// Create an element with type checking
export const examCard = elements.create('examCard', {
  exam: {
    id: 'exam123',
    title: 'Biology 101',
    // TypeScript will enforce the correct property types
  },
});

Browser Support

SmarterElements supports all modern browsers.

Usage

TypeScript Support

All components and utilities are fully typed. You'll get autocompletion and type checking when using TypeScript in your project.

TypeScript Configuration

Ensure your tsconfig.json has the following compiler options:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "moduleResolution": "node",
    "target": "es2018"
  }
}

Available Types

import type {
  SmarterElements,
  ElementInstance,
  ElementOptions,
  EventHandler
} from '@smarterservices/smarter-elements';

Examples

Examples of how to use SmarterElements can be found in the UI application at:

http://localhost:4000/elements-examples/elements-integration.html

When running the UI application locally, you can access these examples to see how different components work and how to integrate them into your application.

JavaScript Integration

Using the Browser Bundle

The browser bundle is specifically designed for direct usage in browsers without a build step. It includes React internally, so you don't need to include React separately.

<!-- Using the browser bundle from unpkg CDN -->  
<script src="https://unpkg.com/@smarterservices/smarter-elements/dist/browser.js"></script>

<script>
  // Create a new instance with clean API
  const elements = new SmarterElements({
    baseUrl: 'https://your-smarterproctoring-url.com',
  });

  // Create an exam card
  const examCard = elements.create('examCard', {
    exam: {
      id: 'exam123',
      title: 'Biology 101',
      course: 'BIO 101 - Introduction to Biology',
      date: '2025-06-15',
      startTime: '10:00 AM',
      duration: 90,
    },
  });
</script>

Using a Specific Version

You can specify a particular version of the browser bundle:

<!-- Using a specific major version (1.x.x - latest in 1.x range) -->
<script src="https://unpkg.com/@smarterservices/smarter-elements@1/dist/browser.js"></script>

<!-- Using a specific minor version (1.0.x - latest patch in 1.0 range) -->
<script src="https://unpkg.com/@smarterservices/[email protected]/dist/browser.js"></script>

<!-- Using an exact version (1.0.24) -->
<script src="https://unpkg.com/@smarterservices/[email protected]/dist/browser.js"></script>

<script>
  // Create a new instance
  const elements = new SmarterElements({
    baseUrl: 'https://your-smarterproctoring-url.com',
  });

  // Create an exam card
  const examCard = elements.create('examCard', {
    exam: {
      id: 'exam123',
      title: 'Biology 101',
      course: 'BIO 101 - Introduction to Biology',
      date: '2025-06-15',
      startTime: '10:00 AM',
      duration: 90,
    },
  });

  // Mount the exam card to a container
  examCard.mount('#exam-card-container');

  // Add event listeners
  examCard.on('start-exam', data => {
    console.log('Start exam clicked:', data);
  });

  examCard.on('view-details', data => {
    console.log('View details clicked:', data);
  });
</script>

React Integration

Installing a Specific Version

# Install the latest version
npm install @smarterservices/smarter-elements

# Install a specific major version (latest in 1.x range)
npm install @smarterservices/smarter-elements@1

# Install a specific minor version (latest patch in 1.0 range)
npm install @smarterservices/[email protected]

# Install an exact version
npm install @smarterservices/[email protected]

Basic Integration

When using the package in a React application, the library will use your application's React instance. This avoids duplicate React instances and prevents "Invalid hook call" errors.

import React, { useEffect, useRef } from 'react';
import SmarterElements from '@smarterservices/smarter-elements';

function ExamCardComponent() {
  const containerRef = useRef(null);
  const examCardRef = useRef(null);

  useEffect(() => {
    // Create a new instance
    const elements = SmarterElements({
      baseUrl: 'https://your-smarterproctoring-url.com',
    });

    // Create an exam card
    const examCard = elements.create('examCard', {
      exam: {
        id: 'exam123',
        title: 'Biology 101',
        course: 'BIO 101 - Introduction to Biology',
        date: '2025-06-15',
        startTime: '10:00 AM',
        duration: 90,
      },
    });

    // Mount the exam card to the container
    examCard.mount(containerRef.current);

    // Add event listeners
    examCard.on('start-exam', data => {
      console.log('Start exam clicked:', data);
    });

    examCard.on('view-details', data => {
      console.log('View details clicked:', data);
    });

    // Save the reference for cleanup
    examCardRef.current = examCard;

    // Cleanup
    return () => {
      if (examCardRef.current) {
        examCardRef.current.unmount();
      }
    };
  }, []);

  return <div ref={containerRef} className="exam-card-container"></div>;
}

export default ExamCardComponent;

Available Elements

  • examCard: Displays exam information with actions
  • proctorSchedule: Shows proctor schedule with calendar view
  • examVerification: Handles exam verification process
  • identityCheck: Manages identity verification
  • elementsLayout: Provides a layout container for elements

Events

Each element emits events that you can listen to:

ExamCard Events

  • start-exam: Triggered when the start exam button is clicked
  • view-details: Triggered when the view details button is clicked
  • resize: Triggered when the element's size changes

ProctorSchedule Events

  • date-changed: Triggered when the selected date changes
  • session-selected: Triggered when a session is selected

Modal Support

SmarterElements provides built-in modal support for displaying elements in a centered dialog:

// Create an element instance
const elements = SmarterElements({
  baseUrl: 'https://your-smarterproctoring-url.com',
});

const examCard = elements.create('examCard', {
  exam: {
    id: 'exam456',
    title: 'Physics 202',
    course: 'PHYS 202 - Quantum Mechanics',
    date: '2025-10-15',
    startTime: '2:00 PM',
    duration: 120,
  },
});

// Open the element in a modal
examCard.openModal({
  width: '800px',
  maxWidth: '90vw',
  maxHeight: '90vh'
});

// Close the modal programmatically
examCard.closeModal();

// Listen for modal events
examCard.on('modal:open', (data) => {
  console.log('Modal opened:', data);
});

examCard.on('modal:close', (data) => {
  console.log('Modal closed:', data);
});

Element Constraints & Resizing

SmarterElements includes a unified resizing system with support for min/max constraints and smooth animations.

Setting Constraints

// Create an element
const examCard = elements.create('examCard', { exam: {...} });

// Set constraints after creation
examCard.updateConstraints({
  minHeight: 200,
  maxHeight: 600,
  minWidth: 300,
  maxWidth: 800
});

// Get current constraints
const constraints = examCard.getConstraints();
console.log('Current constraints:', constraints);

// Listen for constraint updates
examCard.on('constraints:update', ({ constraints }) => {
  console.log('Constraints updated:', constraints);
});

Automatic Resizing Setup

In the parent page (hosting the iframe):

import { setupUnifiedParentResize } from '@smarterservices/smarter-elements';

// Set up resize handling
const cleanup = setupUnifiedParentResize(
  iframe,
  ({ height, width }) => {
    iframe.style.height = `${height}px`;
    console.log('New dimensions:', { height, width });
  },
  {
    elementId: 'my-element',
    minHeight: 100,
    maxHeight: 800
  }
);

// Cleanup when done
cleanup();

In the iframe content (React example):

import { setupUnifiedContentResize } from '@smarterservices/smarter-elements';
import { useEffect } from 'react';

function MyComponent() {
  useEffect(() => {
    // Set up automatic resizing with constraints
    const cleanup = setupUnifiedContentResize({
      minHeight: 100,      // Minimum height in pixels
      maxHeight: 600,      // Maximum height in pixels
      elementId: 'my-element',  // Element ID for targeted messages
      debounceMs: 16       // Debounce delay (60fps)
    });
    
    return cleanup;
  }, []);
  
  return (
    <div>
      {/* Your component content */}
    </div>
  );
}

HTML/JS Usage (No Build Step)

For iframe content without a build step, you can use the auto-initialization feature:

<script src="https://unpkg.com/@smarterservices/smarter-elements/dist/browser.js" 
        data-auto-resize 
        data-min-height="100"
        data-max-height="600"
        data-element-id="your-element-id">
</script>

Or initialize manually after loading the script:

<script src="https://unpkg.com/@smarterservices/smarter-elements/dist/browser.js"></script>
<script>
  // Initialize resize handling
  const cleanup = SmarterElements.setupUnifiedContentResize({
    minHeight: 100,
    maxHeight: 600,
    elementId: 'my-element'
  });
  
  // Cleanup when page unloads
  window.addEventListener('beforeunload', cleanup);
</script>

Observing Specific Elements

To ensure specific elements trigger a resize when they change, add the data-observe-resize attribute:

<div data-observe-resize>
  <!-- Content that might change size -->
</div>

Resize Events

You can listen for resize events on the element instance:

// Listen for resize events (includes both dimensions)
element.on('resize', ({ height, width, elementId }) => {
  console.log('Element resized:', { height, width, elementId });
});

// Listen for constraint updates
element.on('constraints:update', ({ constraints, elementId }) => {
  console.log('Constraints updated:', constraints);
});

Best Practices

  1. Use a minimum height to prevent the iframe from collapsing when content is loading
  2. Add padding/margin to the offset if your content has space that isn't captured by the height calculation
  3. Use element IDs when embedding multiple iframes to ensure messages don't get mixed up
  4. Clean up event listeners when unmounting components to prevent memory leaks

Troubleshooting

Iframe Not Resizing

  1. Check the console for any error messages
  2. Verify the iframe URL - The parent and iframe must be on the same domain or have proper CORS headers
  3. Check content security policy - Ensure your CSP allows postMessage communication
  4. Verify the iframe is loaded - Wait for the iframe's load event before setting up resizing

Common Issues

  • Content jumps on load: Set a reasonable minHeight to prevent layout shifts
  • Resize not working with dynamic content: Ensure you've added data-observe-resize to dynamic content containers
  • Messages not received: Check that the elementId matches between parent and iframe if using targeted messages

Build System

SmarterElements uses a dual build approach to support different usage scenarios:

NPM Package Builds (ESM and CommonJS)

When installed via npm, the package provides:

  • ESM build (dist/index.mjs): For modern bundlers and environments that support ES modules
  • CommonJS build (dist/index.js): For Node.js and older bundlers

Both of these builds externalize React, meaning they expect React to be provided by your application. This prevents duplicate React instances and avoids "Invalid hook call" errors.

Browser Bundle (IIFE)

For direct browser usage without a build step, the package includes:

  • Browser bundle (dist/browser.js): An IIFE build that includes React internally

This bundle exposes SmarterElements as a global constructor and can be used directly in a browser without any build tools or separate React installation.

Versioning

This package follows Semantic Versioning:

  • MAJOR version changes indicate incompatible API changes
  • MINOR version changes add functionality in a backward-compatible manner
  • PATCH version changes include backward-compatible bug fixes

Version Compatibility

To ensure your integration remains stable, we recommend the following versioning strategies:

For Production Applications

  • Lock to an exact version in your package.json: "@smarterservices/smarter-elements": "1.2.3"
  • Update versions manually after testing with your application

For Development/Staging

  • Lock to a minor version using the caret syntax: "@smarterservices/smarter-elements": "^1.2.0"
  • This allows automatic updates for patch releases (bug fixes) but prevents potentially breaking changes

Version Compatibility Matrix

| SmarterElements Version | React Compatibility | Browser Support | Notes | | ----------------------- | ------------------- | --------------- | ------------------------------------- | | 1.x.x | React 18+ | Modern browsers | Initial stable release series | | 2.x.x (future) | React 18+ | Modern browsers | May contain breaking changes from 1.x |

Choosing the Right Version

When selecting a version for your application:

  1. For new projects: Use the latest version available
  2. For existing projects:
    • Check the CHANGELOG.md for breaking changes before upgrading major versions
    • Test thoroughly in a staging environment before deploying to production
  3. For critical applications: Pin to an exact version and only upgrade after thorough testing

Browser Support

SmarterElements supports all modern browsers:

  • Chrome (latest)
  • Firefox (latest)
  • Safari (latest)
  • Edge (latest)

License

MIT