aboutsummaryrefslogtreecommitdiff
path: root/packages/merchant-backoffice-ui/src/components/Amount.tsx
blob: 09f65473c73d9aadae11e303a938d12ad133d727 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
/*
 This file is part of GNU Taler
 (C) 2022 Taler Systems S.A.

 GNU Taler is free software; you can redistribute it and/or modify it under the
 terms of the GNU General Public License as published by the Free Software
 Foundation; either version 3, or (at your option) any later version.

 GNU Taler is distributed in the hope that it will be useful, but WITHOUT ANY
 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
 A PARTICULAR PURPOSE.  See the GNU General Public License for more details.

 You should have received a copy of the GNU General Public License along with
 GNU Taler; see the file COPYING.  If not, see <http://www.gnu.org/licenses/>
 */
import {
  amountFractionalBase,
  amountFractionalLength,
  AmountJson,
  Amounts,
  AmountString,
} from "@gnu-taler/taler-util";
import { Fragment, h, VNode } from "preact";

export function Amount({
  value,
  maxFracSize,
  negative,
  hideCurrency,
  signType = "standard",
  signDisplay = "auto",
}: {
  negative?: boolean;
  value: AmountJson | AmountString;
  maxFracSize?: number;
  hideCurrency?: boolean;
  signType?: "accounting" | "standard";
  signDisplay?: "auto" | "always" | "never" | "exceptZero";
}): VNode {
  const aj = Amounts.jsonifyAmount(value);
  const minFractional =
    maxFracSize !== undefined && maxFracSize < 2 ? maxFracSize : 2;
  const af = aj.fraction % amountFractionalBase;
  let s = "";
  if ((af && maxFracSize) || minFractional > 0) {
    s += ".";
    let n = af;
    for (
      let i = 0;
      (maxFracSize === undefined || i < maxFracSize) &&
      i < amountFractionalLength;
      i++
    ) {
      if (!n && i >= minFractional) {
        break;
      }
      s = s + Math.floor((n / amountFractionalBase) * 10).toString();
      n = (n * 10) % amountFractionalBase;
    }
  }
  const fontSize = 18;
  const letterSpacing = 0;
  const mult = 0.7;
  return (
    <span style={{ textAlign: "right", whiteSpace: "nowrap" }}>
      <span
        style={{
          display: "inline-block",
          fontFamily: "monospace",
          fontSize,
        }}
      >
        {negative ? (signType === "accounting" ? "(" : "-") : ""}
        <span
          style={{
            display: "inline-block",
            textAlign: "right",
            fontFamily: "monospace",
            fontSize,
            letterSpacing,
          }}
        >
          {aj.value}
        </span>
        <span
          style={{
            display: "inline-block",
            width: !maxFracSize ? undefined : `${(maxFracSize + 1) * mult}em`,
            textAlign: "left",
            fontFamily: "monospace",
            fontSize,
            letterSpacing,
          }}
        >
          {s}
          {negative && signType === "accounting" ? ")" : ""}
        </span>
      </span>
      {hideCurrency ? undefined : (
        <Fragment>
          &nbsp;
          <span>{aj.currency}</span>
        </Fragment>
      )}
    </span>
  );
}