npm package: @sasha_gurys/clampert
Description: Generates CSS clamp() expressions for linear scaling between two viewport widths based on target sizes at each point.
Author: Sasha Gurys
Latest version: 1.0.0


# Clampert

Clampert is a small utility function that generates a CSS size which scales linearly between two screen widths. It produces a `clamp()` value combining a minimum size, a preferred scaling formula, and a maximum size.

It solves the problem of writing repetitive media queries for responsive sizing. Instead of defining separate size rules at different breakpoints, Clampert allows defining two sizes — one at the minimum viewport width and one at the maximum — and automatically handles the scaling between them.

### Linear Scaling Explained

Clampert calculates a size that grows or shrinks at a constant rate between two defined viewport widths. It uses four inputs — the size at the minimum viewport, the size at the maximum, the minimum viewport width, and the maximum viewport width — to generate the scaling formula.

Between the minimum and maximum viewport widths, the size scales linearly. Below the minimum viewport width, the size remains fixed at its minimum value. Above the maximum viewport width, the size remains fixed at its maximum value. This behavior is enforced by the CSS `clamp()` function.

---

# Installation

```bash
npm install @sasha_gurys/clampert
```

or

```bash
yarn add @sasha_gurys/clampert
```

---

# Usage

```ts
import createClamp from '@sasha_gurys/clampert';

const clampValue = createClamp({
  sizeAtMin: '14px',
  sizeAtMax: '18px',
  minViewport: 320,
  maxViewport: 1440,
  rootFontSize: 32, // Optional
});

// Example usage in a style object:

const styles = {
  fontSize: clampValue,
};

// Example usage in styled-components or CSS template literals:

const Title = styled.h1`
  font-size: ${clampValue};
`;
```

**Notes:**
- `sizeAtMin` and `sizeAtMax` can be specified in `px` or `rem`.
- `minViewport` and `maxViewport` must be pixel values.
- `minViewport` must be smaller than `maxViewport`.
- `rootFontSize` is optional and only affects `rem` calculations. If not provided, it defaults to `16`.
- When using `rem` units, Clampert uses `rootFontSize` to convert `rem` values into pixel equivalents for correct formula generation.

---

# API

### `createClamp(options: Params): string`

**Params:**

| Param         | Type                  | Required | Description                                                                                                  | Example       |
|:--------------|:----------------------|:---------|:-------------------------------------------------------------------------------------------------------------|:--------------|
| `sizeAtMin`   | `number` or `string`  | ✅       | The size at the minimum viewport width. Accepts `px` or `rem` as strings, or numbers (treated as `px`).     | `'14px'`, `'0.875rem'`, `14` |
| `sizeAtMax`   | `number` or `string`  | ✅       | The size at the maximum viewport width. Accepts `px` or `rem` as strings, or numbers (treated as `px`).     | `'18px'`, `'1.125rem'`, `18` |
| `minViewport` | `number` or `string`  | ✅       | The minimum viewport width (must be in `px`). Must be smaller than `maxViewport`.                           | `'320px'`, `320` |
| `maxViewport` | `number` or `string`  | ✅       | The maximum viewport width (must be in `px`). Must be larger than `minViewport`.                            | `'1440px'`, `1440` |
| `rootFontSize`| `number`              | ❌       | The root font size (in `px`) used for converting `rem` to `px`. Defaults to `16`. Only needed if using `rem`. | `16`          |

**Note**: When passed as a number, all values are treated as `px`. To use `rem`, pass values as strings (e.g., `'1.25rem'`).


---

# Future Plans

- **Reverse scaling support**: allow sizes to shrink instead of grow as viewport width increases.
- **Currying support**: allow partial function application for easier reuse across multiple components.

Future features are considered stretch goals and may be implemented depending on usage needs and available time.

---

# License

MIT License