@erplora/outfitkit 0.1.8 → 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -13,13 +13,33 @@ export declare class OkPinpad extends LitElement {
13
13
  length?: number;
14
14
  /** Enmascara la pantalla con •. */
15
15
  masked: boolean;
16
+ /**
17
+ * Pantalla como N círculos grandes (estilo PIN clásico) en vez de la barra con
18
+ * puntitos. Requiere `length` (cuántos círculos). Implica enmascarado.
19
+ */
20
+ dots: boolean;
21
+ /** Tiñe la pantalla de error (rojo). Útil para «PIN incorrecto». */
22
+ error: boolean;
23
+ /**
24
+ * Tecla de acción secundaria opcional (esquina inferior IZQUIERDA, junto al 0).
25
+ * Si se define, ocupa el hueco de la izquierda con el icono indicado (p.ej.
26
+ * `arrow-back-outline` para «cambiar usuario») y el borrado se queda en su sitio
27
+ * de siempre (derecha). Al pulsarla emite `ok-secondary`. Si NO se define, el
28
+ * layout es el de siempre: `[hueco] [0] [borrar]` (compatible hacia atrás).
29
+ */
30
+ secondaryIcon?: string;
31
+ /** aria-label de la tecla de acción secundaria. */
32
+ secondaryLabel?: string;
16
33
  /** Textos traducibles (merge sobre los defaults en inglés). */
17
34
  labels: Partial<OkPinpadLabels>;
18
35
  private get t();
19
36
  private press;
20
37
  private backspace;
21
38
  private emitInput;
39
+ private secondary;
40
+ private renderBackspace;
22
41
  private renderDisplay;
42
+ private renderCircles;
23
43
  render(): unknown;
24
44
  }
25
45
  declare global {
package/dist/ok-pinpad.js CHANGED
@@ -19,6 +19,8 @@ class OkPinpad extends LitElement {
19
19
  super(...arguments);
20
20
  this.value = "";
21
21
  this.masked = false;
22
+ this.dots = false;
23
+ this.error = false;
22
24
  this.labels = {};
23
25
  }
24
26
  static {
@@ -67,6 +69,33 @@ class OkPinpad extends LitElement {
67
69
  font-weight: 400;
68
70
  font-size: 1rem;
69
71
  }
72
+ /* Variante dots: N círculos grandes (estilo PIN clásico), sin barra de fondo. */
73
+ .circles {
74
+ min-height: 2.25rem;
75
+ display: flex;
76
+ align-items: center;
77
+ justify-content: center;
78
+ gap: var(--ok-pinpad-circle-gap, 0.9rem);
79
+ }
80
+ .circle {
81
+ width: var(--ok-pinpad-circle-size, 1rem);
82
+ height: var(--ok-pinpad-circle-size, 1rem);
83
+ border-radius: 50%;
84
+ border: 2px solid var(--ok-pinpad-circle-border, var(--ion-color-medium, #92949c));
85
+ background: transparent;
86
+ box-sizing: border-box;
87
+ transition: background 0.15s, border-color 0.15s;
88
+ }
89
+ .circle.filled {
90
+ background: var(--dot-color);
91
+ border-color: var(--dot-color);
92
+ }
93
+ .circles.error .circle {
94
+ border-color: var(--ion-color-danger, #eb445a);
95
+ }
96
+ .circles.error .circle.filled {
97
+ background: var(--ion-color-danger, #eb445a);
98
+ }
70
99
  /* Rejilla de teclas 3×4. */
71
100
  .grid {
72
101
  display: grid;
@@ -122,6 +151,18 @@ class OkPinpad extends LitElement {
122
151
  })
123
152
  );
124
153
  }
154
+ // Emite `ok-secondary` (pulsación de la tecla de acción secundaria).
155
+ secondary() {
156
+ this.dispatchEvent(
157
+ new CustomEvent("ok-secondary", { bubbles: true, composed: true })
158
+ );
159
+ }
160
+ // Botón de borrado (reutilizado en ambos layouts).
161
+ renderBackspace() {
162
+ return html`<ion-button fill="clear" aria-label=${this.t.backspace} @click=${() => this.backspace()}>
163
+ <ion-icon slot="icon-only" name="backspace-outline"></ion-icon>
164
+ </ion-button>`;
165
+ }
125
166
  // Pinta la pantalla: dots si `masked`, dígitos si no, placeholder si vacío.
126
167
  renderDisplay() {
127
168
  if (!this.value) {
@@ -132,10 +173,24 @@ class OkPinpad extends LitElement {
132
173
  }
133
174
  return html`<span>${this.value}</span>`;
134
175
  }
176
+ // Variante `dots`: N círculos grandes (estilo PIN clásico). Requiere `length`.
177
+ renderCircles() {
178
+ const n = this.length ?? 0;
179
+ return html`<div
180
+ class="circles ${this.error ? "error" : ""}"
181
+ role="status"
182
+ aria-live="polite"
183
+ >
184
+ ${Array.from(
185
+ { length: n },
186
+ (_, i) => html`<span class="circle ${i < this.value.length ? "filled" : ""}"></span>`
187
+ )}
188
+ </div>`;
189
+ }
135
190
  render() {
136
191
  const digits = ["1", "2", "3", "4", "5", "6", "7", "8", "9"];
137
192
  return html`
138
- <div class="display" role="status" aria-live="polite">${this.renderDisplay()}</div>
193
+ ${this.dots && this.length != null ? this.renderCircles() : html`<div class="display" role="status" aria-live="polite">${this.renderDisplay()}</div>`}
139
194
  <div class="grid" role="group" aria-label=${this.t.keypad}>
140
195
  ${digits.map(
141
196
  (d) => html`<ion-button
@@ -144,11 +199,13 @@ class OkPinpad extends LitElement {
144
199
  @click=${() => this.press(d)}
145
200
  >${d}</ion-button>`
146
201
  )}
147
- <span class="spacer" aria-hidden="true"></span>
202
+ ${this.secondaryIcon ? html`<ion-button
203
+ fill="clear"
204
+ aria-label=${this.secondaryLabel ?? this.secondaryIcon}
205
+ @click=${() => this.secondary()}
206
+ ><ion-icon slot="icon-only" name=${this.secondaryIcon}></ion-icon></ion-button>` : html`<span class="spacer" aria-hidden="true"></span>`}
148
207
  <ion-button fill="outline" aria-label="0" @click=${() => this.press("0")}>0</ion-button>
149
- <ion-button fill="clear" aria-label=${this.t.backspace} @click=${() => this.backspace()}>
150
- <ion-icon slot="icon-only" name="backspace-outline"></ion-icon>
151
- </ion-button>
208
+ ${this.renderBackspace()}
152
209
  </div>
153
210
  `;
154
211
  }
@@ -162,6 +219,18 @@ __decorateClass([
162
219
  __decorateClass([
163
220
  property({ type: Boolean })
164
221
  ], OkPinpad.prototype, "masked");
222
+ __decorateClass([
223
+ property({ type: Boolean })
224
+ ], OkPinpad.prototype, "dots");
225
+ __decorateClass([
226
+ property({ type: Boolean })
227
+ ], OkPinpad.prototype, "error");
228
+ __decorateClass([
229
+ property({ type: String, attribute: "secondary-icon" })
230
+ ], OkPinpad.prototype, "secondaryIcon");
231
+ __decorateClass([
232
+ property({ type: String, attribute: "secondary-label" })
233
+ ], OkPinpad.prototype, "secondaryLabel");
165
234
  __decorateClass([
166
235
  property({ attribute: false })
167
236
  ], OkPinpad.prototype, "labels");