intrepidshape/elm-web3-ui/4.0.0

Web3.Ui.Amount

Token amount input and display with SI suffix formatting.

-- Amount input with inline symbol label:
Web3.Ui.Amount.amountInput []
    { value = model.amountStr
    , onInput = AmountChanged
    , decimals = 18
    , symbol = "PLS"
    , valid = True
    , inputAttrs = []
    }


-- Format a Wei value as human-readable (caller appends symbol):
Web3.Ui.Amount.formatWei 18 weiAmount ++ " PLS"
--> "1.23M PLS"
amountInput : List (Attribute msg) -> Config msg -> Html msg

Numeric text input for a token amount. value is a plain decimal string (e.g. "1000.5"). No parsing is done here -- call Web3.Units.parseUnits in your update to convert to Wei.

Adds web3-amount-input--invalid when valid is False.

The first argument lands on the wrapper; inputAttrs lands on the <input />.

CSS classes: web3-amount-wrapper (outer div), web3-amount-input (input), web3-amount-symbol (symbol label)

type alias Config msg =
{ value : String
, onInput : String -> msg
, decimals : Int
, symbol : String
, valid : Bool
, inputAttrs : List (Attribute msg)
}

What the input shows and where its edits go.

inputAttrs reach the inner <input />. The component's root is the wrapper div (it also holds the symbol label), so the first positional argument cannot address the control itself -- and id, aria-describedby, autofocus, disabled and a <label for=...> target all belong on the control, not on a box around it. That is what this field is for.

formatWei : Int -> BigInt -> String

Format a Wei BigInt as a human-readable string with SI suffix.

The symbol is not appended -- concatenate it yourself so the caller controls spacing and placement.

formatWei 18 onePls   --> "1"
formatWei 18 largePls --> "1.23M"
formatWei 6  oneUsdc  --> "1"

SI suffixes: K (10^3), M (10^6), B (10^9), T (10^12). Values below 1000 are shown with up to 2 decimal places, trailing zeros trimmed. A nonzero value under 0.01 (which a flat 2dp would render as "0.00") instead shows its first two significant fractional digits (e.g. "0.0000019") so real sub-cent balances never vanish.

All formatting stays in integer/string space -- the amount is never routed through Float, so neither very small nor very large values lose precision.

presetRow : List (Attribute msg) -> { onPick : Int -> msg } -> Html msg

A row of balance-percentage chips -- 25% / 50% / 75% / MAX -- the companion every amountInput deserves. Emits the chosen percentage (100 = MAX); the app computes the actual amount from the live balance, so the chips never display a stale number.

Web3.Ui.Amount.presetRow [] { onPick = FillPercent }


-- FillPercent 100 -> set input to formatUnits decimals balance

CSS classes: web3-amount-presets, web3-amount-presets__chip, web3-amount-presets__chip--max.

formatWeiDust : Int -> BigInt -> String

Like formatWei, with the dust convention: a nonzero amount that would display as zero (below 0.0001 of the unit) renders as "<0.0001" instead -- "0" must mean zero, never "too small to show".