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

reneco-advanced-input-module

v0.0.21

Published

Component to input data into forms by voice

Readme

Built With Stencil

Stencil Component Starter

This is a starter project for building a standalone Web Components using Stencil.

Stencil is a compiler for building fast web apps using Web Components.

Stencil combines the best concepts of the most popular frontend frameworks into a compile-time rather than runtime tool. Stencil takes TypeScript, JSX, a tiny virtual DOM layer, efficient one-way data binding, an asynchronous rendering pipeline (similar to React Fiber), and lazy-loading out of the box, and generates 100% standards-based Web Components that run in any browser supporting the Custom Elements specification.

Stencil components are just Web Components, so they work in any major framework or with no framework at all.

Getting Started

To start building a new web component using Stencil, clone this repo to a new directory:

git clone https://github.com/stenciljs/component-starter.git my-component
cd my-component
git remote rm origin

and run:

npm install
npm start

Configuration Setup

Option 1: Using API Proxy (Recommended)

By default, the component uses a proxy API to handle OpenAI calls server-side. This is the recommended approach for production as it keeps your API keys secure.

  1. Start the proxy API server (see api-proxy/README.md)
  2. Use the component without providing an api-key:
    <voice-input-module
      form-json='{...}'
      context="ng"
      api-proxy-url="http://localhost:8492"
    >
    </voice-input-module>

Option 2: Direct API Calls (Client-side)

For development or specific use cases, you can make direct calls to OpenAI from the browser:

  1. Copy the template configuration file:

    cp config.template.js config.js
  2. Edit config.js and add your OpenAI API key:

    export const config = {
      OPENAI_API_KEY: 'your-actual-api-key-here'
    };
  3. Pass the API key to the component:

    <voice-input-module
      form-json='{...}'
      context="ng"
      api-key="sk-..."
    >
    </voice-input-module>
  4. The config.js file is gitignored and will not be committed to the repository

Note: When api-key is provided, the component will use direct API calls. When api-key is not provided, it will use the proxy API at api-proxy-url (default: http://localhost:8492).

To build the component for production, run:

npm run build

To run the unit tests for the components, run:

npm test

Need help? Check out our docs here.

Naming Components

When creating new component tags, we recommend not using stencil in the component name (ex: <stencil-datepicker>). This is because the generated component has little to nothing to do with Stencil; it's just a web component!

Instead, use a prefix that fits your company or any name for a group of related components. For example, all of the Ionic-generated web components use the prefix ion.

Using this component

There are two strategies we recommend for using web components built with Stencil.

The first step for all two of these strategies is to publish to NPM.

You can read more about these different approaches in the Stencil docs.

Lazy Loading

If your Stencil project is built with the dist output target, you can import a small bootstrap script that registers all components and allows you to load individual component scripts lazily.

For example, given your Stencil project namespace is called my-design-system, to use my-component on any website, inject this into your HTML:

<script type="module" src="https://unpkg.com/my-design-system"></script>
<!--
To avoid unpkg.com redirects to the actual file, you can also directly import:
https://unpkg.com/[email protected]/dist/foobar-design-system/foobar-design-system.esm.js
-->
<my-component first="Stencil" middle="'Don't call me a framework'" last="JS"></my-component>

This will only load the necessary scripts needed to render <my-component />. Once more components of this package are used, they will automatically be loaded lazily.

You can also import the script as part of your node_modules in your applications entry file:

import 'foobar-design-system/dist/foobar-design-system/foobar-design-system.esm.js';

Check out this Live Demo.

Standalone

If you are using a Stencil component library with dist-custom-elements, we recommend importing Stencil components individually in those files where they are needed.

To export Stencil components as standalone components make sure you have the dist-custom-elements output target defined in your stencil.config.ts.

For example, given you'd like to use <my-component /> as part of a React component, you can import the component directly via:

import 'foobar-design-system/my-component';

function App() {
  return (
    <>
      <div>
        <my-component
          first="Stencil"
          middle="'Don't call me a framework'"
          last="JS"
        ></my-component>
      </div>
    </>
  );
}

export default App;

Theme System

Overview

The voice-input-module component supports a complete theme system allowing visual customization via the theme prop (JSON string).

Theme Structure

{
  texts: {
    idle: string,        // Text displayed at rest
    recording: string,   // Text displayed during voice recording
    processing: string   // Text displayed during processing (transcription/LLM)
  },
  container: {
    width: string,           // Container width (e.g., "auto", "500px", "100%")
    height: string,          // Container height (e.g., "auto", "200px")
    backgroundColor: string, // Background color (e.g., "#ffffff", "rgb(255,255,255)")
    borderColor: string,     // Border color
    borderRadius: string,    // Corner radius (e.g., "8px", "0px", "20px")
    padding: string,         // Internal spacing (e.g., "20px", "12px", "24px")
    gap: string             // Spacing between elements (buttons and status) (e.g., "8px", "4px", "12px")
  },
  buttons: {
    voice: {
      backgroundColor: string, // Voice button background color
      textColor: string,       // Text/icon color (currently unused for SVG icon)
      hoverColor: string,      // Hover color
      size: string            // Button size (e.g., "50px", "40px", "65px")
    },
    audio: {
      backgroundColor: string, // Audio upload button background color
      textColor: string,       // Text/icon color
      hoverColor: string,      // Hover color
      size: string            // Button size
    },
    ocr: {
      backgroundColor: string, // OCR button background color
      textColor: string,       // Text/icon color
      hoverColor: string,      // Hover color
      size: string            // Button size
    }
  },
  statusText: {
    color: string,    // Status text color
    fontSize: string  // Font size (e.g., "14px", "12px", "16px")
  }
}

Default Values

{
  "texts": {
    "idle": "Select an input method",
    "recording": "Recording... Click to stop",
    "processing": "Processing..."
  },
  "container": {
    "width": "auto",
    "height": "auto",
    "backgroundColor": "#ffffff",
    "borderColor": "#e2e8f0",
    "borderRadius": "8px",
    "padding": "20px",
    "gap": "8px"
  },
  "buttons": {
    "voice": {
      "backgroundColor": "#ee4444",
      "textColor": "#ffffff",
      "hoverColor": "#dd3333",
      "size": "50px"
    },
    "audio": {
      "backgroundColor": "#3b82f6",
      "textColor": "#ffffff",
      "hoverColor": "#2563eb",
      "size": "50px"
    },
    "ocr": {
      "backgroundColor": "#10b981",
      "textColor": "#ffffff",
      "hoverColor": "#059669",
      "size": "50px"
    }
  },
  "statusText": {
    "color": "#1e293b",
    "fontSize": "14px"
  }
}

Visual Impact

texts

  • idle: Message displayed when no action is in progress
  • recording: Message displayed during live voice recording
  • processing: Message displayed during audio transcription and form filling by LLM

container

  • width: Controls main container width. Use "auto" to adapt to content, or a fixed value
  • height: Controls main container height
  • backgroundColor: Container background color
  • borderColor: Container border color (1px border)
  • borderRadius: Corner radius (0px = square, high values = very rounded)
  • padding: Space between content and container edges
  • gap: Vertical space between button row and status text

buttons.voice (Live voice recording button)

  • backgroundColor: Circular button color
  • textColor: Icon color (currently not applied for SVG)
  • hoverColor: Mouse hover color
  • size: Circular button diameter (e.g., "40px" = small, "65px" = large)

buttons.audio (Audio file upload button)

  • backgroundColor: SVG icon color
  • textColor: Text color (currently unused)
  • hoverColor: Hover color
  • size: Icon size (width and height)

buttons.ocr (OCR button - document upload)

  • backgroundColor: OCR button color
  • textColor: Text/icon color
  • hoverColor: Hover color
  • size: Button size

statusText

  • color: Status text color
  • fontSize: Status text font size

OCR Component Theme

The ocr-file-uploader component receives a subset of the theme via its theme prop:

{
  "button": {
    "size": "50px",
    "backgroundColor": "#10b981",
    "hoverColor": "#059669",
    "textColor": "#ffffff"
  }
}

These values are extracted from theme.buttons.ocr of the parent component.

To implement in ocr-file-uploader component:

  • Apply button.size to button size
  • Apply button.backgroundColor to button background color
  • Apply button.hoverColor to hover color
  • Apply button.textColor to icon/text color

Theme Examples

See the demo page (src/index.html) for 5 complete theme examples:

  • Medical: Compact & Professional (red, small buttons)
  • Nature: Large & Organic (green, large buttons, rounded)
  • Tech Dark: Minimal & Terminal (dark background, square corners)
  • Corporate: Standard & Professional (gray tones)
  • Playful: Fun & Colorful (yellow, emojis, large padding)

Usage

Using Proxy API (Recommended)

<voice-input-module
  id="my-component"
  form-json='{...}'
  context="ng"
  api-proxy-url="http://localhost:8492"
  input-types="['voice', 'audio', 'ocr']"
  theme='{"texts":{"idle":"Start recording"},"container":{"backgroundColor":"#f0f9ff"},"buttons":{"voice":{"backgroundColor":"#0ea5e9","size":"60px"}}}'
>
</voice-input-module>

Using Direct API Calls

<voice-input-module
  id="my-component"
  form-json='{...}'
  api-key="sk-..."
  context="ng"
  input-types="['voice', 'audio', 'ocr']"
  theme='{"texts":{"idle":"Start recording"},"container":{"backgroundColor":"#f0f9ff"},"buttons":{"voice":{"backgroundColor":"#0ea5e9","size":"60px"}}}'
>
</voice-input-module>

Or in JavaScript:

const component = document.createElement('voice-input-module');
const theme = {
  texts: { idle: "Start recording" },
  container: { backgroundColor: "#f0f9ff" },
  buttons: { voice: { backgroundColor: "#0ea5e9", size: "60px" } }
};
component.setAttribute('theme', JSON.stringify(theme));

Important Notes

  1. All properties are optional: If a property is not provided, the default value is used
  2. Theme is reactive: Changing the theme attribute updates the component in real-time
  3. Colors: Accept all CSS formats (hex, rgb, rgba, color names)
  4. Sizes: Must include unit (px, rem, em, %)
  5. Width "auto": Recommended for container to adapt to button sizes
  6. Gap: Controls vertical spacing between buttons and status text

API Proxy Configuration

Overview

The voice-input-module component supports two operating modes for OpenAI API calls:

  1. Proxy Mode (Recommended): API calls go through a proxy server that securely manages API keys
  2. Direct Mode: API calls are made directly from the browser (for development only)

Proxy Mode (Default)

Advantages

  • ✅ Security: API keys remain server-side
  • ✅ Control: Ability to log, limit, or modify requests
  • ✅ Production-ready: Recommended for production environments

Configuration

  1. Start the proxy API server (see api-proxy/README.md)
  2. Use the component without providing an api-key:
<voice-input-module
  form-json='{"fields": {...}}'
  context="ng"
  api-proxy-url="http://localhost:8492"
>
</voice-input-module>

Parameters

  • api-proxy-url: Proxy server URL (default: http://localhost:8492)
  • api-key: Do not provide to use proxy mode

Endpoints Used

The component will automatically call:

  • POST {api-proxy-url}/transcribe for audio transcription
  • POST {api-proxy-url}/complete for LLM form filling

Direct Mode

Advantages

  • ✅ Simple: No proxy server needed
  • ✅ Development: Ideal for quick testing

Disadvantages

  • ❌ Security: API key is exposed client-side
  • ❌ Not recommended for production

Configuration

  1. Provide an OpenAI API key to the component:
<voice-input-module
  form-json='{"fields": {...}}'
  context="ng"
  api-key="sk-proj-..."
>
</voice-input-module>

Parameters

  • api-key: OpenAI API key (starts with sk-)
  • api-proxy-url: Ignored when api-key is provided

Endpoints Used

The component will directly call:

  • POST https://api.openai.com/v1/audio/transcriptions for transcription
  • POST https://api.openai.com/v1/chat/completions for LLM

Selection Logic

if (apiKey) {
  // Direct Mode: Direct calls to OpenAI
  useProxy = false;
  baseUrl = 'https://api.openai.com/v1';
} else {
  // Proxy Mode: Calls via proxy server
  useProxy = true;
  baseUrl = apiProxyUrl || 'http://localhost:8492';
}

Migration

From Direct to Proxy

  <voice-input-module
    form-json='...'
    context="ng"
-   api-key="sk-proj-..."
+   api-proxy-url="http://localhost:8492"
  >
  </voice-input-module>

From Proxy to Direct

  <voice-input-module
    form-json='...'
    context="ng"
-   api-proxy-url="http://localhost:8492"
+   api-key="sk-proj-..."
  >
  </voice-input-module>

Complete Examples

Example 1: Production with Proxy

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="./build/voice-input-module.esm.js"></script>
</head>
<body>
  <voice-input-module
    form-json='{"fields": {"name": {"type": "string", "title": "Name"}}}'
    context="track"
    api-proxy-url="https://api.mycompany.com/openai-proxy"
    language="en"
    input-types='["voice", "audio"]'
  >
  </voice-input-module>
</body>
</html>

Example 2: Development with Direct

<!DOCTYPE html>
<html>
<head>
  <script type="module" src="./build/voice-input-module.esm.js"></script>
</head>
<body>
  <voice-input-module
    form-json='{"fields": {"name": {"type": "string", "title": "Name"}}}'
    context="track"
    api-key="sk-proj-xxxxxxxxxxxxx"
    language="en"
    input-types='["voice", "audio"]'
  >
  </voice-input-module>
</body>
</html>

Troubleshooting

Component is not making API calls

Check:

  1. If api-key is not provided, is the proxy server running?
  2. Is the proxy URL correct?
  3. Does the proxy server have a valid OpenAI API key in its .env?

CORS Error

Proxy Mode: Check the CORS configuration of the proxy server (api-proxy/main.py)

Direct Mode: Direct calls to OpenAI from the browser may be blocked by CORS in some cases

Authentication Error

Proxy Mode: Verify that the proxy server has a valid API key in api-proxy/.env

Direct Mode: Verify that the provided API key is valid and active

License

MIT License - See LICENSE at the root of the project