Integration Guide

This document shows how to integrate the <vn-resize-box> web component into a host application, including script loading, attribute configuration, event handling, and styling.


1. Script Loading

Include the component script before your application code:

<script src="path/to/vanilla-resize-box/vanilla-resize-box.js"></script>

The component automatically injects its stylesheet (vanilla-resize-box.css) into <head>. No manual <link> tag is needed.

Note: The script resolves CSS paths relative to its own location. Do not move the .js file without also moving the .css file.


2. Basic HTML Integration

2.1 Wrapping Any Content

<vn-resize-box width="600" height="400" min-width="200" min-height="150">
    <div id="myContent">
        <p>Drag the bottom-right corner to resize this container.</p>
    </div>
</vn-resize-box>

2.2 Wrapping a Vanilla-Grid

<vn-resize-box id="gridContainer" min-width="360" min-height="220">
    <vn-grid id="myGrid" theme="carbon">
        <vn-grid-column field="Name" header="Name" type="string"></vn-grid-column>
        <vn-grid-column field="Email" header="Email" type="string"></vn-grid-column>
    </vn-grid>
</vn-resize-box>

The <vn-grid> component uses an internal ResizeObserver to react to size changes, so it automatically relays content when the resize box dimensions change.


3. Attribute Configuration

All attributes are optional. When not set, the component falls back to sensible defaults.

Attribute Default Description
width parent width Initial width — any CSS length (600, 600px, 100%, 60vw); a bare number means px
height parent height Initial height — same syntax as width
min-width 100 Minimum width in px — bare number or explicit px only
min-height 100 Minimum height in px — bare number or explicit px only
max-width parent-relative Maximum width — same syntax as width
max-height parent-relative Maximum height — same syntax as width

The min-* attributes are px-only because they feed the drag clamp, which is arithmetic on pixels; a relative value such as 50% is rejected and the default (100) applies. Removing any of these attributes drops the inline style it wrote, handing that dimension back to CSS.

Example with full constraints:

<vn-resize-box
    width="800"
    height="500"
    min-width="300"
    min-height="200"
    max-width="1200"
    max-height="800">
    ...
</vn-resize-box>

4. Listening to Resize Events

const box = document.getElementById('gridContainer');

box.addEventListener('vn-resize-start', () => {
    console.log('Resize started');
});

box.addEventListener('vn-resize-move', (e) => {
    console.log('Resizing:', e.detail.width, 'x', e.detail.height);
});

box.addEventListener('vn-resize-end', (e) => {
    console.log('Final size:', e.detail.width, 'x', e.detail.height);
    // e.g., save size to localStorage
});

5. Programmatic Resize

const box = document.getElementById('gridContainer');

// Set specific dimensions (clamped to the min-*/max-* attributes)
box.resize(700, 450);

// Read current size
console.log(box.currentWidth, box.currentHeight);

// Read back the configuration, verbatim from the attributes
console.log(box.width, box.maxWidth);   // e.g. "600", null
console.log(box.minWidth);              // the px minimum actually enforced

resize() fires vn-resize-end (and only that one). If your vn-resize-end listener calls resize(), break the loop yourself — the component does not suppress the event for programmatic calls, because hosts that persist size on vn-resize-end would otherwise silently miss every programmatic change.

resize() also does not apply the parent-relative ceiling that a drag enforces. It is your explicit instruction, and it may run before your own layout has settled, so a resize() can produce a size larger than a drag could reach.


6. Adding Visual Chrome (CSS)

The component's base CSS provides only structural rules. To add borders, shadows, or backgrounds, add rules in your host stylesheet targeting .vn-resize-box:

#gridContainer .vn-resize-box {
    border: 1px solid rgba(0, 0, 0, 0.08);
    border-radius: 8px;
    padding: 6px;
    background: var(--vn-grid-bg, transparent);
}

Tip: Scope overrides by container ID to avoid affecting other <vn-resize-box> instances on the page.


7. Right-to-Left Layouts

<vn-resize-box> follows the inline direction. Under dir="rtl" the handle sits in the bottom-left corner, dragging left grows the box, and the parent-relative ceiling is measured from the parent's right edge. No attribute or option turns this on — set dir="rtl" as you would anywhere else:

<html dir="rtl">
    ...
    <vn-resize-box id="gridContainer" min-width="360" min-height="220">
        <vn-grid id="myGrid"></vn-grid>
    </vn-resize-box>

Two things to know:


8. Accessibility

Resizing is pointer-driven — there is no keyboard resize path. The drag handle carries role="separator" and an accessible name, so assistive technology announces the resizable boundary, but it is deliberately not focusable: it holds no tabindex, and no key does anything to it. It therefore adds no tab stop to a page — in particular, none between the page and the content the box wraps.

Hosts that need a keyboard-operable size can drive resize() from their own control.

8.1 Labelling

Put an aria-label on the <vn-resize-box>; the component copies it onto the handle with a suffix:

<vn-resize-box id="gridContainer" aria-label="Resizable orders grid">…</vn-resize-box>
<!-- handle gets aria-label="Resizable orders grid — resize handle" -->

With no host label the handle falls back to "Resize".

Two limits:

8.2 Overriding the label or adding a tooltip

const box = document.getElementById('gridContainer');
const handle = box.querySelector('.vn-resize-handle');
if (handle) {
    handle.setAttribute('aria-label', 'Ridimensiona la griglia ordini');
    handle.setAttribute('title', 'Trascina l\'angolo per ridimensionare');
}

9. Migration from Inline Resize Code

If you previously had a custom resize implementation (like the one formerly in people-cities-js), the migration steps are:

  1. Remove the old HTML markup (.resizable-container, .resize-visual-handle).
  2. Remove the old JavaScript function (initResizableContainer()).
  3. Remove the old CSS rules (.resizable-container, .resize-visual-handle, etc.).
  4. Add the script tag: <script src="../vanilla-resize-box/vanilla-resize-box.js"></script>.
  5. Wrap your content in <vn-resize-box> with the desired attributes.
  6. Add app-specific CSS targeting #yourId .vn-resize-box for borders, padding, etc.
  7. Update any tooltip/i18n code to query .vn-resize-handle instead of .resize-visual-handle.

10. Script Loading Order

When using both Vanilla-Grid and Vanilla-Resize-Box:

<!-- Resize box (no dependencies) -->
<script src="../vanilla-resize-box/vanilla-resize-box.js"></script>

<!-- Grid engine + web component -->
<script src="../vanilla-grid/vanilla-grid.js"></script>
<script src="../vanilla-grid/vanilla-grid-element.js"></script>

<!-- App code -->
<script type="module" src="app.js"></script>

<vn-resize-box> has no dependency on <vn-grid> and can be used independently.