@valnivo_labs/widgets

Valnivo's financial calculators as components: standalone (no network, keeps working if valnivo.eu is gone) or framed from the site. React, Vue, Angular and plain HTML.
1,232
Install
npm install @valnivo_labs/widgets
Latest Version:0.3.2
Vue:3
License:Custom
Last Updated:Sep 27, 2026
Links: npm
Maintainer: valnivo_labs

@valnivo_labs/widgets

Financial calculators as components: a projection, a mortgage, a loan, rent against buying, a card at its minimum, and seventeen more. Standalone by choice — the calculators run in your own page and make no network request of any kind, so they keep working whatever happens to us.

npm install @valnivo_labs/widgets

Two modes, and the trade between them

render(el, { widget: 'projection' })          // standalone: the calculator, in your page
mount(el,  { widget: 'projection' })          // framed: an iframe on valnivo.eu
Standalone (/standalone) Framed (the default export)
Needs valnivo.eu No — never Yes, at view time
If valnivo.eu goes away Keeps working Shows an empty frame
Fixes to a model When you npm update Immediately, with no update
Weight ~54 kB gzipped, loaded on demand ~1 kB
Isolation Closed shadow root Cross-origin iframe
Server rendering Client-side only Client-side only

No font files are bundled. Inter is what valnivo.eu serves; standalone falls back to system-ui so the package stays 54 kB rather than 500, and so it fetches nothing. Load the face yourself if you want it — the widget will use it.

Pick standalone if the page must not depend on us. That is what it is for: a dependency should outlive the person who published it. Pick framed if you would rather a correction to an arithmetic model reach your visitors the day it ships.

Where it runs

Framed Standalone
React 17, 18, 19 ✓ React-DOM 18+ (createRoot)
Vue 3.0 – 3.5 ✓ ✓
Angular 2 – 21, via <valnivo-widget> + CUSTOM_ELEMENTS_SCHEMA ✓ ✓
Svelte, Solid, Lit, Astro, plain HTML, via the same element ✓ ✓
Next.js, Nuxt, SvelteKit ✓ client-side ✓ client-side
Node / SSR renders on hydration renders on hydration
Browsers anything with <iframe> anything with shadow DOM — Chrome/Edge 53+, Firefox 63+, Safari 10+

React, React-DOM and Vue are optional peer dependencies: install only the one your project already has. The custom element needs none of them.

Nothing about your page or your visitor reaches Valnivo, in either mode. Standalone makes no request at all — no frame, no fetch, no font, no beacon. Framed, the iframe sends no referrer and the widget's own policy is connect-src 'none'. Neither touches storage, and there is one implementation of every calculation behind both, so the two cannot disagree about an answer.

React

import { ValnivoWidget } from '@valnivo_labs/widgets/react'

<ValnivoWidget widget="projection" params={{ currency: 'EUR', locale: 'fr-LU', have: 40000, save: 500 }} />

Vue 3

<script setup>
import { ValnivoWidget } from '@valnivo_labs/widgets/vue'
</script>
<template>
  <ValnivoWidget widget="loan" :params="{ currency: 'EUR', years: 7 }" />
</template>

Angular

Angular's own route for a component from outside its compiler is a custom element, so the Angular entry defines <valnivo-widget> and needs nothing from @angular/core and no compilation — it works in an AOT build as it is.

// main.ts, once
import '@valnivo_labs/widgets/angular'

// a standalone component
@Component({
  selector: 'app-savings',
  standalone: true,
  schemas: [CUSTOM_ELEMENTS_SCHEMA],
  template: `<valnivo-widget widget="projection" [params]="figures"></valnivo-widget>`,
})
export class SavingsComponent {
  figures = { currency: 'EUR', have: 40000, save: 500 }
}

[params] is a property binding: a new object re-points the frame. In an NgModule application, CUSTOM_ELEMENTS_SCHEMA goes in the module's schemas.

Svelte, Solid, Lit, Astro, plain HTML — the custom element

<script type="module">import 'https://cdn.example/@valnivo_labs/widgets/element.js'</script>
<valnivo-widget widget="mortgage" params='{"currency":"EUR","years":25}'></valnivo-widget>

The params attribute takes JSON; the params property takes an object, which is what a framework binding sets. Changing widget, origin, height or title makes a new frame; changing params re-points the existing one.

Standalone, in any framework

import { render } from '@valnivo_labs/widgets/standalone'

const handle = render(document.getElementById('box'), {
  widget: 'projection',
  params: { have: 40000, save: 500 },
  currency: 'EUR',
  locale: 'fr-LU',        // how numbers are written
  lang: 'fr',             // the words: en (default), fr, de, es, it, pt, nl, pl
  theme: 'auto',          // dark (default), light, or auto
})
handle.update({ have: 50000 })
handle.destroy()

The translations ship in the package, one small chunk per language, loaded only when a lang other than English is asked for — from wherever your bundler serves the rest of the package, never from us. The words are page-wide: a page has one language, and the last lang given is the one every standalone calculator on it shows.

In a component, pass standalone:

<ValnivoWidget standalone widget="projection" params={{ have: 40000 }} />
<valnivo-widget standalone widget="mortgage" currency="EUR"></valnivo-widget>

It renders into a closed shadow root: our styles cannot reach your page, yours cannot reach ours, and element.shadowRoot is null. The Valnivo mark and each calculator's "an illustration, not a forecast or advice" line are inside it and are put back if anything removes them — a white-label licence is the one way the mark comes off.

Anything else

import { mount } from '@valnivo_labs/widgets'

const handle = mount(document.getElementById('box'), { widget: 'mortgage', params: { currency: 'EUR' } })
handle.update({ years: 25 })
handle.destroy()

Parameters are the documented ones — currency, locale, lang, theme, accent, and each calculator's own figures — at https://valnivo.eu/developers.html#params. locale decides how numbers are written and lang the language of the words (en, the default, fr, de, es, it, pt, nl or pl); they are separate on purpose, so { locale: 'fr-LU' } alone stays in English. widget="page" with widgets= composes several in one frame, exactly as the loader does.

Conditions of use

The same as the loader's: https://valnivo.eu/developers.html#rules — see LICENSE.md.

Related Packages

@flouviahq/elements

Cord Elements: cotizador embebible con Shadow DOM, Builder headless dirigido por...

2,605
sagegreytechnologies-nkiru-ai-chat-widget-webcomponent

Native Web Component chat widget with complete CSS isolation using Shadow DOM

1,532
@aspect-ui-01/toast

Lightweight framework-agnostic toast notifications (~2KB)

3,926
web-c-theme

功能介绍 这是一个基于 **Web Component** 技术的主题组件库,主要功能是前端 **"主题...

3,688
live-avatar-element

Framework-agnostic Web Component for Azure Voice Live interactive avatar assista...

2,393

Version History

Version Released License
0.3.2 Custom
0.3.1 Custom
0.3.0 Custom
0.2.2 Custom
0.2.1 Custom