PageSourceSearch

https://loja.correios.com.br/public-resources/js/lojaweb/input-number-stepper.js

js correios.com.br collected 2026-09-24 07:27:37 UTC 3,926 bytes, 140 lines download raw bytes

1export const MENSAGEM_ESTOQUE_PREFIXO = 'Desculpe. No momento, temos apenas';
2
3export function mensagemEstoqueInsuficiente(estoqueDisponivel) {
4  return `${MENSAGEM_ESTOQUE_PREFIXO} ${estoqueDisponivel} unidades deste item em estoque.`;
5}
6
7export function formatarMoeda(valor) {
8  return `R$ ${Number(valor).toLocaleString('pt-BR', { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;
9}
10
11export function calcularValorOriginal(preco) {
12  if (!preco || !preco.valorDesconto || preco.valorDesconto <= 0 || preco.subtotal == null) {
13    return null;
14  }
15  return Number(preco.subtotal) + Number(preco.valorDesconto);
16}
17
18export function calcularPercentualDesconto(preco) {
19  const valorOriginal = calcularValorOriginal(preco);
20  if (!valorOriginal || valorOriginal <= 0) {
21    return null;
22  }
23  return Math.round((Number(preco.valorDesconto) / valorOriginal) * 100);
24}
25
26export function createNumberStepper({
27  container,
28  value = 1,
29  min = 1,
30  max = 999,
31  onChange = () => {},
32  onInvalid = () => {},
33  enabled = true,
34}) {
35  container.innerHTML = '';
36  container.classList.add('number-stepper');
37
38  let currentValue = Math.max(min, Math.min(max, parseInt(value, 10) || min));
39
40  const btnMenos = document.createElement('button');
41  btnMenos.type = 'button';
42  btnMenos.className = 'btn-stepper btn-txt so-icone btnMenos';
43  btnMenos.title = 'Subtrair';
44  btnMenos.innerHTML = '<i class="ic-diminuir-circulo"></i>';
45
46  const input = document.createElement('input');
47  input.type = 'number';
48  input.className = 'stepper-input';
49  input.min = String(min);
50  input.max = String(max);
51  input.value = String(currentValue);
52  input.setAttribute('aria-label', 'Quantidade');
53
54  const btnMais = document.createElement('button');
55  btnMais.type = 'button';
56  btnMais.className = 'btn-stepper btn-txt so-icone btnMais';
57  btnMais.title = 'Adicionar';
58  btnMais.innerHTML = '<i class="ic-adicionar-circulo"></i>';
59
60  container.appendChild(btnMenos);
61  container.appendChild(input);
62  container.appendChild(btnMais);
63
64  function atualizarBotoes() {
65    btnMenos.disabled = !enabled || currentValue <= min;
66    btnMais.disabled = !enabled || currentValue >= max;
67    input.disabled = !enabled;
68  }
69
70  function aplicarValor(novoValor, validarEstoque = true) {
71    const parsed = parseInt(novoValor, 10);
72    if (Number.isNaN(parsed)) {
73      input.value = String(currentValue);
74      return;
75    }
76    if (parsed < min) {
77      currentValue = min;
78      input.value = String(currentValue);
79      atualizarBotoes();
80      onChange(currentValue);
81      return;
82    }
83    if (parsed > max && validarEstoque) {
84      input.value = String(currentValue);
85      onInvalid(mensagemEstoqueInsuficiente(max));
86      return;
87    }
88    currentValue = Math.min(parsed, max);
89    input.value = String(currentValue);
90    atualizarBotoes();
91    onChange(currentValue);
92  }
93
94  btnMenos.addEventListener('click', () => {
95    if (!enabled || currentValue <= min) {
96      return;
97    }
98    aplicarValor(currentValue - 1, false);
99  });
100
101  btnMais.addEventListener('click', () => {
102    if (!enabled || currentValue >= max) {
103      if (currentValue >= max) {
104        onInvalid(mensagemEstoqueInsuficiente(max));
105      }
106      return;
107    }
108    aplicarValor(currentValue + 1, false);
109  });
110
111  input.addEventListener('change', () => {
112    aplicarValor(input.value, true);
113  });
114
115  input.addEventListener('blur', () => {
116    aplicarValor(input.value, true);
117  });
118
119  atualizarBotoes();
120
121  return {
122    getValue: () => currentValue,
123    setMax: (novoMax) => {
124      max = Math.max(min, parseInt(novoMax, 10) || min);
125      input.max = String(max);
126      if (currentValue > max) {
127        currentValue = max;
128        input.value = String(currentValue);
129      }
130      atualizarBotoes();
131    },
132    setValue: (novoValor) => {
133      aplicarValor(novoValor, false);
134    },
135    setEnabled: (ativo) => {
136      enabled = ativo;
137      atualizarBotoes();
138    },
139  };
140}

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.