Skip to content

Commit 5214878

Browse files
committed
feat(input-otp): add readonly support
1 parent 2d0441c commit 5214878

File tree

10 files changed

+68
-42
lines changed

10 files changed

+68
-42
lines changed

core/src/components.d.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1346,6 +1346,10 @@ export namespace Components {
13461346
* The number of input boxes to display.
13471347
*/
13481348
"length": number;
1349+
/**
1350+
* If `true`, the user cannot modify the value.
1351+
*/
1352+
"readonly": boolean;
13491353
/**
13501354
* Where separators should be shown between input boxes. Can be a comma-separated string or an array of numbers. For example: `"3"` will show a separator after the 3rd input box. `[1,4]` will show a separator after the 1st and 4th input boxes. `"all"` will show a separator between every input box.
13511355
*/
@@ -6282,6 +6286,10 @@ declare namespace LocalJSX {
62826286
* Emitted when the input is complete (all boxes filled)
62836287
*/
62846288
"onIonComplete"?: (event: IonInputOtpCustomEvent<InputOtpCompleteEventDetail>) => void;
6289+
/**
6290+
* If `true`, the user cannot modify the value.
6291+
*/
6292+
"readonly"?: boolean;
62856293
/**
62866294
* Where separators should be shown between input boxes. Can be a comma-separated string or an array of numbers. For example: `"3"` will show a separator after the 3rd input box. `[1,4]` will show a separator after the 1st and 4th input boxes. `"all"` will show a separator between every input box.
62876295
*/

core/src/components/input-otp/input-otp.ios.scss

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,3 @@
1515
border-width: 1px;
1616
}
1717
}
18-
19-
// States
20-
// --------------------------------------------------
21-
22-
:host(.input-otp-disabled) {
23-
opacity: $form-control-ios-disabled-opacity;
24-
}

core/src/components/input-otp/input-otp.md.scss

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,3 @@
1717
}
1818
}
1919

20-
// States
21-
// --------------------------------------------------
22-
23-
:host(.input-otp-disabled) {
24-
opacity: $form-control-md-disabled-opacity;
25-
}

core/src/components/input-otp/input-otp.scss

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -186,13 +186,18 @@
186186
}
187187

188188
:host(.input-otp-fill-solid) {
189-
--border-color: #{$background-color-step-100};
189+
--border-color: #{$background-color-step-50};
190190
--background: var(--border-color);
191191
}
192192

193193
// States
194194
// --------------------------------------------------
195195

196+
:host(.input-otp-fill-outline.input-otp-disabled) {
197+
--background: #{$background-color-step-50};
198+
--border-color: #{$background-color-step-100};
199+
}
200+
196201
:host(.input-otp-disabled),
197202
:host(.input-otp-disabled) .native-input:disabled {
198203
cursor: not-allowed;
@@ -207,10 +212,20 @@
207212
background: var(--background-focused);
208213
}
209214

210-
:host(.ion-invalid) .native-input {
215+
:host(.ion-invalid) .native-input,
216+
:host(.ion-invalid.has-focus) .native-input {
211217
border-color: var(--highlight-color-invalid);
212218
}
213219

220+
:host(.input-otp-fill-outline.input-otp-readonly) {
221+
--background: #{$background-color-step-50};
222+
}
223+
224+
:host(.input-otp-fill-solid.input-otp-disabled),
225+
:host(.input-otp-fill-solid.input-otp-readonly) {
226+
--border-color: #{$background-color-step-100};
227+
}
228+
214229
// Colors
215230
// --------------------------------------------------
216231

core/src/components/input-otp/input-otp.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ export class InputOTP implements ComponentInterface {
6565
*/
6666
@Prop() allowedKeys?: string;
6767

68+
/**
69+
* If `true`, the user cannot modify the value.
70+
*/
71+
@Prop({ reflect: true }) readonly = false;
72+
6873
/**
6974
* The size of the input boxes.
7075
*/
@@ -351,6 +356,7 @@ export class InputOTP implements ComponentInterface {
351356
[`input-otp-shape-${this.shape}`]: true,
352357
[`input-otp-fill-${this.fill}`]: true,
353358
'input-otp-disabled': this.disabled,
359+
'input-otp-readonly': this.readonly,
354360
})}
355361
>
356362
<div role="group" aria-label="One-time password input" class="input-otp-group">
@@ -365,6 +371,7 @@ export class InputOTP implements ComponentInterface {
365371
maxLength={1}
366372
pattern={this.type === 'number' ? '[0-9]' : undefined}
367373
disabled={this.disabled}
374+
readOnly={this.readonly}
368375
tabIndex={index === tabbableIndex ? 0 : -1}
369376
value={this.inputValues[index] || ''}
370377
autocomplete={index === 0 ? 'one-time-code' : 'off'}

core/src/components/input-otp/test/basic/index.html

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,20 +41,28 @@
4141
<h2>Default</h2>
4242
<ion-input-otp> Didn't get a code? <a href="#">Resend the code</a> </ion-input-otp>
4343
<ion-input-otp length="2"> Didn't get a code? <a href="#">Resend the code</a> </ion-input-otp>
44-
<ion-input-otp id="numberValue" length="6"> Didn't get a code? <a href="#">Resend the code</a> </ion-input-otp>
44+
<ion-input-otp id="numberValue" length="6">
45+
Didn't get a code? <a href="#">Resend the code</a>
46+
</ion-input-otp>
4547
<ion-input-otp value="5893" length="8"> Didn't get a code? <a href="#">Resend the code</a> </ion-input-otp>
4648
</div>
4749

4850
<div class="grid-item">
4951
<h2>Disabled</h2>
50-
<ion-input-otp disabled></ion-input-otp>
51-
<ion-input-otp fill="solid" disabled></ion-input-otp>
52+
<ion-input-otp value="1234" disabled>Description</ion-input-otp>
53+
<ion-input-otp value="1234" fill="solid" disabled>Description</ion-input-otp>
54+
</div>
55+
56+
<div class="grid-item">
57+
<h2>Readonly</h2>
58+
<ion-input-otp value="1234" readonly>Description</ion-input-otp>
59+
<ion-input-otp value="1234" fill="solid" readonly>Description</ion-input-otp>
5260
</div>
5361

5462
<div class="grid-item">
5563
<h2>Invalid</h2>
56-
<ion-input-otp class="ion-invalid"></ion-input-otp>
57-
<ion-input-otp fill="solid" class="ion-invalid"></ion-input-otp>
64+
<ion-input-otp class="ion-invalid">Description</ion-input-otp>
65+
<ion-input-otp fill="solid" class="ion-invalid">Description</ion-input-otp>
5866
</div>
5967

6068
<div class="grid-item">

core/src/components/input-otp/test/color/index.html

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,28 @@
3939
<div class="grid">
4040
<div class="grid-item">
4141
<h2>Outline Colors</h2>
42-
<ion-input-otp color="primary"></ion-input-otp>
43-
<ion-input-otp color="secondary"></ion-input-otp>
44-
<ion-input-otp color="tertiary"></ion-input-otp>
45-
<ion-input-otp color="success"></ion-input-otp>
46-
<ion-input-otp color="warning"></ion-input-otp>
47-
<ion-input-otp color="danger"></ion-input-otp>
48-
<ion-input-otp color="light"></ion-input-otp>
49-
<ion-input-otp color="medium"></ion-input-otp>
50-
<ion-input-otp color="dark"></ion-input-otp>
42+
<ion-input-otp value="12" color="primary"></ion-input-otp>
43+
<ion-input-otp value="12" color="secondary"></ion-input-otp>
44+
<ion-input-otp value="12" color="tertiary"></ion-input-otp>
45+
<ion-input-otp value="12" color="success"></ion-input-otp>
46+
<ion-input-otp value="12" color="warning"></ion-input-otp>
47+
<ion-input-otp value="12" color="danger"></ion-input-otp>
48+
<ion-input-otp value="12" color="light"></ion-input-otp>
49+
<ion-input-otp value="12" color="medium"></ion-input-otp>
50+
<ion-input-otp value="12" color="dark"></ion-input-otp>
5151
</div>
5252

5353
<div class="grid-item">
5454
<h2>Solid Colors</h2>
55-
<ion-input-otp fill="solid" color="primary"></ion-input-otp>
56-
<ion-input-otp fill="solid" color="secondary"></ion-input-otp>
57-
<ion-input-otp fill="solid" color="tertiary"></ion-input-otp>
58-
<ion-input-otp fill="solid" color="success"></ion-input-otp>
59-
<ion-input-otp fill="solid" color="warning"></ion-input-otp>
60-
<ion-input-otp fill="solid" color="danger"></ion-input-otp>
61-
<ion-input-otp fill="solid" color="light"></ion-input-otp>
62-
<ion-input-otp fill="solid" color="medium"></ion-input-otp>
63-
<ion-input-otp fill="solid" color="dark"></ion-input-otp>
55+
<ion-input-otp value="12" fill="solid" color="primary"></ion-input-otp>
56+
<ion-input-otp value="12" fill="solid" color="secondary"></ion-input-otp>
57+
<ion-input-otp value="12" fill="solid" color="tertiary"></ion-input-otp>
58+
<ion-input-otp value="12" fill="solid" color="success"></ion-input-otp>
59+
<ion-input-otp value="12" fill="solid" color="warning"></ion-input-otp>
60+
<ion-input-otp value="12" fill="solid" color="danger"></ion-input-otp>
61+
<ion-input-otp value="12" fill="solid" color="light"></ion-input-otp>
62+
<ion-input-otp value="12" fill="solid" color="medium"></ion-input-otp>
63+
<ion-input-otp value="12" fill="solid" color="dark"></ion-input-otp>
6464
</div>
6565
</div>
6666
</ion-content>

packages/angular/src/directives/proxies.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,14 +1018,14 @@ This event will not emit when programmatically setting the `value` property.
10181018

10191019

10201020
@ProxyCmp({
1021-
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'separators', 'shape', 'size', 'type', 'value']
1021+
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'readonly', 'separators', 'shape', 'size', 'type', 'value']
10221022
})
10231023
@Component({
10241024
selector: 'ion-input-otp',
10251025
changeDetection: ChangeDetectionStrategy.OnPush,
10261026
template: '<ng-content></ng-content>',
10271027
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
1028-
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'separators', 'shape', 'size', 'type', 'value'],
1028+
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'readonly', 'separators', 'shape', 'size', 'type', 'value'],
10291029
})
10301030
export class IonInputOtp {
10311031
protected el: HTMLIonInputOtpElement;

packages/angular/standalone/src/directives/proxies.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -984,14 +984,14 @@ export declare interface IonInfiniteScrollContent extends Components.IonInfinite
984984

985985
@ProxyCmp({
986986
defineCustomElementFn: defineIonInputOtp,
987-
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'separators', 'shape', 'size', 'type', 'value']
987+
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'readonly', 'separators', 'shape', 'size', 'type', 'value']
988988
})
989989
@Component({
990990
selector: 'ion-input-otp',
991991
changeDetection: ChangeDetectionStrategy.OnPush,
992992
template: '<ng-content></ng-content>',
993993
// eslint-disable-next-line @angular-eslint/no-inputs-metadata-property
994-
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'separators', 'shape', 'size', 'type', 'value'],
994+
inputs: ['allowedKeys', 'color', 'disabled', 'fill', 'inputmode', 'length', 'readonly', 'separators', 'shape', 'size', 'type', 'value'],
995995
standalone: true
996996
})
997997
export class IonInputOtp {

packages/vue/src/proxies.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ export const IonInputOtp: StencilVueComponent<JSX.IonInputOtp> = /*@__PURE__*/ d
499499
'inputmode',
500500
'length',
501501
'allowedKeys',
502+
'readonly',
502503
'size',
503504
'separators',
504505
'shape',

0 commit comments

Comments
 (0)