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

@devmayo/lms-sdk-nextjs

v1.3.10

Published

This package provides an SDK for integrating `@devmayo/lms-sdk` functionalities within Next.js applications. It is designed to work seamlessly with Next.js version 14.1.0 and React 18, facilitating the development of learning management systems (LMS) with

Readme

@devmayo/lms-sdk-nextjs

This package provides an SDK for integrating @devmayo/lms-sdk functionalities within Next.js applications. It is designed to work seamlessly with Next.js version 14.1.0 and React 18, facilitating the development of learning management systems (LMS) with modern web technologies.

Installation

To install @devmayo/lms-sdk-nextjs, run the following commands in your project directory:

npm install @devmayo/lms-sdk @devmayo/lms-sdk-nextjs

OR

yarn add @devmayo/lms-sdk @devmayo/lms-sdk-nextjs

Usage

In order to use the register form provided by the SDK you have to do the following:

First create an environment file with the following env variable:

LMS_URL=https://<yourlmsurl.com>/api

Change <yourlmsurl.com> for the url of your LMS.

‼️ Important ‼️

This env variable will be available only in server side, that means that all the methods provided by the SDK that have API logic, have to be called in server side.

Once you have configured the environment, and to start using the RegisterForm component and registerAction provided by the SDK, you have to do the following:

First you'll need to import the styles provided by the sdk in your root layout file

// app/layout.tsx

import '@devmayo/lms-sdk-nextjs/dist/index.css';

Then you have to wrap both, the component and the action, by your own client component and server action respectively. For example:

// your-action-wrapper.ts

'use server';

import { registerAction } from '@devmayo/lms-sdk-nextjs';

export const registerActionWrapper = registerAction;

And then use the action in your component wrapper, you'll need to define your own state and pass it to the component. Like the following:

// your-component-wrapper.tsx

'use client';

import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';

const initialState: Record<string, any> = {
  errors: {},
  message: null
};

export default function Home() {
  const [state, action] = useFormState(registerActionWrapper, initialState);

  return (
    <form action={action}>
      <RegisterForm state={state} />
    </form>
  );
}

This will render the form with the fields defined in the registerFieldsService, if you need to modify, ovewrite, add or remove fields, then you can do it inside of your-component-wrapper.tsx file, like this:

// your-component-wrapper.tsx

'use client';

import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { registerFieldsService } from '@devmayo/lms-sdk';
import { useFormState } from 'react-dom';

const initialState: Record<string, any> = {
  errors: {},
  message: null
};

// here you can modify, ovewrite, add or remove fields using the service provided
// for example, to modify the return_url you can do the following:
registerFieldsService.findOneAndUpdate('return_url', {
  value: 'https://grupomayo.com/'
})

export default function Home() {
  const [state, action] = useFormState(registerActionWrapper, initialState);

  return (
    <form action={action}>
      <RegisterForm state={state} />
    </form>
  );
}

If you need to modify, ovewrite, add or remove specialties, then you can do it inside of your-component-wrapper.tsx file, like this:

// your-component-wrapper.tsx

'use client';

import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { registerFieldsService } from '@devmayo/lms-sdk';
import { useFormState } from 'react-dom';

const initialState: Record<string, any> = {
  errors: {},
  message: null
};

// here you can modify, ovewrite, add or remove specialties using the service provided
// for example, to add a specialty you can do the following:
specialtiesService.add({
  label: 'Specialty',
  value: 'Specialty',
  order: 0,
});
// It's important after adding, modifying or removing specialties, perform a refresh of the form fields.
// This have to be done AFTER all the modifications to the specialties and BEFORE all the modifications to the fields
registerFieldsService.refresh()

// here you can modify, ovewrite, add or remove fields using the service provided
// for example, to modify the return_url you can do the following:
registerFieldsService.findOneAndUpdate('return_url', {
  value: 'https://grupomayo.com/'
})

export default function Home() {
  const [state, action] = useFormState(registerActionWrapper, initialState);

  return (
    <form action={action}>
      <RegisterForm state={state} />
    </form>
  );
}

For executing some actions, like perform a redirect or display a modal, you can pass an onFail and an onSuccess to the component. onSuccess will be executed when the registration is completed and recieve as an argument the values of the fields. onFail will be executed when something fail, like field validation errors or postcode not found, as an argument you'll recieve the state with information about the corresponding error

// your-component-wrapper.tsx

'use client';

import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';

export default function Home() {
  const [state, action] = useFormState(registerActionWrapper, initialState);

  function onSuccess(values: any) {
    console.log('values on success', values);
  }

  function onFail(state: any) {
    console.log('state on fail', state);
  }

  return (
    <form action={action}>
      <RegisterForm state={state} onFail={onFail} onSuccess={onSuccess} />
    </form>
  );
}

If you want to change the styling of the inputs, you have 2 options:

First one, you can pass a prop to the form component with a dictionary defining the new components for each field type you want to overwrite

// your-component-wrapper.tsx

'use client';

import { RegisterForm } from '@devmayo/lms-sdk-nextjs';
import { registerActionWrapper } from './action';
import { useFormState } from 'react-dom';
import { FieldTypes, RegisterField } from '@devmayo/lms-sdk';

export default function Home() {
  const [state, action] = useFormState(registerActionWrapper, initialState);

  function onSuccess(values: any) {
    console.log('values on success', values);
  }

  function onFail(state: any) {
    console.log('state on fail', state);
  }

  const componentsMap: Record<string, React.ComponentType<RegisterField>> = {
    [FieldTypes.TEXT]: (props: TextInputProps) => /* Your component here */,
    // ...more field types to overwrite
  }

  return (
    <form action={action}>
      <RegisterForm state={state} onFail={onFail} onSuccess={onSuccess} customComponents={componentsMap} />
    </form>
  );
}

The custom components will recieve as props everything you need to handle the logic and errors of that field, for example, the default TextInput component will look like this:

// text-input.tsx

import { ErrorMessage } from '../atoms/error-message';
import { Input, InputProps } from '../atoms/input';
import { Label } from '../atoms/label';

export type TextInputProps = Omit<InputProps, 'id' | 'type'> & {
  label: string;
  id?: string;
  errorMessage?: string | null;
  type?: string;
};

export function TextInput({ type = 'text', name = '', placeholder, label, id = '', required = false, errorMessage, value, onChange, disabled }: TextInputProps) {
  return (
    <div className={`flex flex-col p-2 gap-2 min-w-max`}>
      <Label label={label} htmlFor={name} />
      <Input type={type} name={name} placeholder={placeholder} id={id} value={value} required={required} hasError={errorMessage != null} onChange={onChange} disabled={disabled} />
      {errorMessage && <ErrorMessage message={errorMessage} />}
    </div>
  );
}

// input.tsx

export interface InputProps {
  id: string;
  type: string;
  name: string;
  placeholder?: string;
  required?: boolean;
  hasError?: boolean;
  value?: string;
  stateValue?: string;
  disabled?: boolean;
  checked?: boolean;
  onChange?: (event: React.ChangeEvent<HTMLInputElement>) => void;
  onKeyUp?: (event: React.KeyboardEvent<HTMLInputElement>) => void;
}

export function Input({ disabled, type, stateValue, name, placeholder, id, required = false, hasError = false, value, onChange, onKeyUp, checked }: InputProps) {
  return (
    <input
      id={id}
      disabled={disabled}
      type={type}
      required={required}
      className={`py-1 px-3 text-xs rounded-md ${hasError ? 'border-2 border-red-500' : 'border border-black'}`}
      name={name}
      defaultChecked={checked}
      placeholder={placeholder}
      defaultValue={value}
      value={stateValue}
      onChange={onChange}
      onKeyDown={onKeyUp}
    />
  );
}

Second, you can use the stylesService like the following:

import { StylesEnum, stylesService } from '@devmayo/lms-sdk';

stylesService.set(StylesEnum.LABEL, 'text-yellow-900 font-bold text-3xl');
stylesService.set(StylesEnum.ERROR_MESSAGE, 'text-green-500 text-2xl');
stylesService.set(StylesEnum.BORDDER_ON_ERROR, 'border-2 border-blue-500');

you have all of these options in StylesEnum available for modification:

  • LABEL
  • INPUT
  • SELECT
  • RADIO
  • CHECKBOX
  • ERROR_MESSAGE
  • BORDER_ON_ERROR

Change Log

Version 1.1.4

  • Disable tailwind preflight

Version 1.1.3

  • Fix tailwind classes not created

Version 1.1.2

  • Add prefix to all tailwind's classes

Version 1.1.0

  • Integrate with the new styles service
  • Remove the default submit button in form component

Version 1.0.1

  • Fix no css file on build result

Version 1.0.0

  • Add the RegisterForm component.
  • Add the registerAction server action.
  • Integrate with the @devmayo/lms-sdk