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 🙏

© 2026 – Pkg Stats / Ryan Hefner

@xinosolutions/editor

v1.1.2

Published

Professional rich text editor component for React with customizable toolbar, theming, and access validation.

Readme

@xinosolutions/editor

Production-ready rich text editor component for React applications.


About XinoSolutions

XinoSolutions is a software development company dedicated to creating high-quality, developer-friendly solutions. We specialize in building modern React components and tools that help developers build better applications faster. Our commitment to excellence, clean code, and user experience drives everything we create.

This package is part of our open-source initiative to contribute valuable tools to the React ecosystem.


@xinosolutions/editor provides a WYSIWYG editing experience with customizable toolbar/navbar layouts, theme configuration, image upload hooks, and optional access validation through Xino API keys.

Why use this package

  • Fast integration into existing React apps
  • Rich formatting controls out of the box
  • Extensible toolbar and navbar configuration
  • Browser-safe access validation using apiKey
  • Suitable for product forms, CMS flows, support tools, and admin panels

Installation

npm install @xinosolutions/editor
yarn add @xinosolutions/editor

Peer Dependencies

  • react ^18.2.0
  • react-dom ^18.2.0

Quick Start

import { useState } from "react";
import ReactEditor from "@xinosolutions/editor";

export default function App() {
  const [value, setValue] = useState("");

  return (
    <ReactEditor
      value={value}
      onChange={setValue}
      placeholder="Write your content..."
      height="420px"
    />
  );
}

Access Validation

For client-side applications, pass your API key as apiKey (xs_editor_...).

Get your API key here: https://editor.xinosolutions.com/

  • Create an editor site and domain allow-list in SX Editor
  • No customer backend is required — the API key is safe in browser env vars
  • Validation calls https://api.editor.xinosolutions.com/api/text_editor/validate (no host env setup required)
  • Validation help links/messages are handled internally by the package

Environment Variables

Vite:

VITE_TEXT_EDITOR_API_KEY=xs_editor_your_id_here

Next.js:

NEXT_PUBLIC_TEXT_EDITOR_API_KEY=xs_editor_your_id_here

Usage:

const apiKey =
  import.meta?.env?.VITE_TEXT_EDITOR_API_KEY ??
  process.env.NEXT_PUBLIC_TEXT_EDITOR_API_KEY ??
  "";

<ReactEditor value={value} onChange={setValue} apiKey={apiKey} />;

API Reference (Props)

| Prop | Type | Default | Description | |---|---|---|---| | value | string | "" | Current editor HTML/text content. | | onChange | (nextValue: string) => void | undefined | Change callback for editor content. | | placeholder | string | internal | Placeholder text when editor is empty. | | height | string \| number | internal | Editor height (for example "400px" or 500). | | mainProps | object | {} | Props passed to the editor root wrapper. | | apiKey | string | "" | API key for access validation (xs_editor_...). | | onAccessChange | ({ status, access }) => void | undefined | Access-state callback (checking, allowed, denied, etc). | | toolbarDensity | "comfortable" \| "compact" | "comfortable" | Toolbar spacing density. | | navbar | Array | internal | Override navbar groups/options. | | toolbar | Array | internal | Override toolbar controls. | | remove_from_navbar | Array | [] | Remove selected navbar items. | | remove_from_toolbar | Array | [] | Remove selected toolbar items. | | theme_config | object | {} | CSS variable-based editor theme overrides. | | image_handler | (payload) => Promise<string> | undefined | Async image uploader returning a final URL string. | | getEditorRef | (ref) => void | undefined | Access editor ref for advanced integrations. |

Access-State Example

<ReactEditor
  value={value}
  onChange={setValue}
  apiKey={apiKey}
  onAccessChange={({ status }) => setCanSave(status === "allowed")}
/>

Custom Toolbar and Navbar

const navbar = [
  { name: "file", options: ["new_document", "preview", "print"] },
  { name: "view", options: ["source_code", "full_screen"] },
  { name: "insert", options: ["image", "link", "video", "hr_line", "special_char"] },
  { name: "format", options: ["bold", "italic", "underline", "font", "font_size", "alignment"] },
  "|",
  "select_all",
];

const toolbar = [
  "undo", "redo", "|", "bold", "italic", "underline", "|", "alignment", "|", "orderedList", "unorderedList",
];

<ReactEditor value={value} onChange={setValue} navbar={navbar} toolbar={toolbar} />;

Remove actions:

<ReactEditor
  value={value}
  onChange={setValue}
  remove_from_toolbar={["bold", { name: "format", options: ["h1"] }]}
  remove_from_navbar={["select_all", { name: "view", options: ["source_code"] }]}
/>

Theme Customization

const theme_config = {
  "background-color": "#ffffff",
  "border-color": "#d0d5dd",
  "text-color": "#101828",
  "toolbar-button-background": "#ffffff",
  "toolbar-text-color": "#101828",
  "toolbar-button-hover-background": "#f2f4f7",
  "toolbar-button-selected-background": "#eaecf0",
  "svg-color": "#101828",
};

<ReactEditor value={value} onChange={setValue} theme_config={theme_config} />;

Image Upload Integration

import axios from "axios";

async function image_handler(payload) {
  const formData = new FormData();
  formData.append("image", payload.image);
  const response = await axios.post("/api/upload", formData);
  return response.data?.url ?? "";
}

<ReactEditor value={value} onChange={setValue} image_handler={image_handler} />;

Security Recommendations

  • Register every production hostname in your editor site’s allowed domains.
  • Use apiKey from environment variables — do not hard-code in source.
  • Enforce authorization again on your own save/upload endpoints if you add a backend later.

Troubleshooting

  • Editor remains locked: verify domain allow-list and key type in the portal.
  • Validation endpoint errors: verify your API key and domain allow-list in the portal.
  • Visual issues: confirm package styles are loaded and not overridden by aggressive global CSS resets.
  • Image upload fails: ensure image_handler resolves to a valid absolute URL.

License

MIT

Support

For product or integration support, contact Xino Solutions.