Skip to content

Commit 6c1ac03

Browse files
committed
chore: add base input on ts-inputs
1 parent b34418b commit 6c1ac03

File tree

10 files changed

+1448
-423
lines changed

10 files changed

+1448
-423
lines changed

README.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,10 +69,6 @@ yarn add ts-inputs
6969

7070
Contributions are welcome! Please feel free to submit a Pull Request.
7171

72-
## License
73-
74-
[Add your license information here]
75-
7672
## Testing
7773

7874
```bash

docs/.vitepress/config.ts

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,11 +62,11 @@ const sidebar = [
6262
{
6363
text: 'Features',
6464
items: [
65-
{ text: 'Phone Formatting', link: '/features/phone' },
66-
{ text: 'Credit Card Formatting', link: '/features/credit-card' },
67-
{ text: 'Date Formatting', link: '/features/date' },
68-
{ text: 'Time Formatting', link: '/features/time' },
69-
{ text: 'Numerical Formatting', link: '/features/numeral' },
65+
{ text: 'Phone Input', link: '/features/phone' },
66+
{ text: 'Credit Card Input', link: '/features/credit-card' },
67+
{ text: 'Date Input', link: '/features/date' },
68+
{ text: 'Time Input', link: '/features/time' },
69+
{ text: 'Numerical Input', link: '/features/numeral' },
7070
],
7171
},
7272
{

docs/features/base-input.md

Lines changed: 321 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,321 @@
1+
# Base Input
2+
3+
The BaseInput class serves as the foundation for all input formatting and validation in ts-inputs. It provides a unified interface for handling various types of inputs including credit cards, phone numbers, numerals, and general formatted inputs.
4+
5+
## Installation
6+
7+
```bash
8+
npm install ts-inputs
9+
# or
10+
yarn add ts-inputs
11+
# or
12+
pnpm add ts-inputs
13+
# or
14+
bun add ts-inputs
15+
```
16+
17+
## Basic Usage
18+
19+
```typescript
20+
import { BaseInput } from 'ts-inputs'
21+
22+
// Create a new input instance
23+
const input = new BaseInput('#my-input', {
24+
// Choose one input type
25+
creditCard: true,
26+
// Optional configuration
27+
creditCardOptions: {
28+
delimiter: ' ',
29+
},
30+
// Event handlers
31+
onValueChanged: (formatted, unformatted) => {
32+
console.log('Formatted:', formatted)
33+
console.log('Raw value:', unformatted)
34+
}
35+
})
36+
```
37+
38+
## Input Types
39+
40+
### Credit Card Input
41+
42+
```typescript
43+
const creditCardInput = new BaseInput('#card-input', {
44+
creditCard: true,
45+
creditCardOptions: {
46+
delimiter: ' ',
47+
delimiterLazyShow: true,
48+
},
49+
onCreditCardTypeChanged: (type) => {
50+
// type can be: 'visa', 'mastercard', 'amex', etc.
51+
updateCardIcon(type)
52+
}
53+
})
54+
```
55+
56+
### Phone Input
57+
58+
```typescript
59+
const phoneInput = new BaseInput('#phone-input', {
60+
phone: true,
61+
phoneOptions: {
62+
format: 'international',
63+
defaultCountry: 'US',
64+
},
65+
onPhoneFormatChanged: (formatted) => {
66+
validatePhoneNumber(formatted)
67+
}
68+
})
69+
```
70+
71+
### Numeral Input
72+
73+
```typescript
74+
const numeralInput = new BaseInput('#amount-input', {
75+
numeral: true,
76+
numeralOptions: {
77+
thousandsSeparator: ',',
78+
decimalSeparator: '.',
79+
precision: 2,
80+
},
81+
onNumeralFormatChanged: (formatted) => {
82+
updateTotal(formatted)
83+
}
84+
})
85+
```
86+
87+
### General Input
88+
89+
```typescript
90+
const generalInput = new BaseInput('#custom-input', {
91+
general: true,
92+
generalOptions: {
93+
blocks: [3, 3, 3], // Format as XXX-XXX-XXX
94+
delimiter: '-',
95+
uppercase: true,
96+
},
97+
onGeneralFormatChanged: (formatted) => {
98+
console.log('Formatted:', formatted)
99+
}
100+
})
101+
```
102+
103+
## Event Handling
104+
105+
The BaseInput class provides comprehensive event handling:
106+
107+
```typescript
108+
const input = new BaseInput('#my-input', {
109+
creditCard: true,
110+
111+
// Value change events
112+
onValueChanged: (formatted, unformatted) => {
113+
console.log(`Value changed from ${unformatted} to ${formatted}`)
114+
},
115+
116+
// Focus events
117+
onFocus: (event) => {
118+
highlightInputContainer(event.target)
119+
},
120+
121+
// Blur events
122+
onBlur: (event) => {
123+
validateInput(event.target)
124+
},
125+
126+
// Type-specific events
127+
onCreditCardTypeChanged: (type) => {
128+
updateCardIcon(type)
129+
}
130+
})
131+
```
132+
133+
## Public Methods
134+
135+
### getValue()
136+
137+
Returns the current formatted value
138+
139+
```typescript
140+
const formatted = input.getValue()
141+
```
142+
143+
### getUnformattedValue()
144+
145+
Returns the raw, unformatted value
146+
147+
```typescript
148+
const raw = input.getUnformattedValue()
149+
```
150+
151+
### setValue(value: string)
152+
153+
Sets a new value and applies formatting
154+
155+
```typescript
156+
input.setValue('4242424242424242')
157+
```
158+
159+
### destroy()
160+
161+
Cleans up the instance and removes event listeners
162+
163+
```typescript
164+
input.destroy()
165+
```
166+
167+
## Real-world Examples
168+
169+
### Payment Form Integration
170+
171+
```typescript
172+
class PaymentForm {
173+
private cardInput: BaseInput
174+
private phoneInput: BaseInput
175+
176+
constructor() {
177+
this.cardInput = new BaseInput('#card-number', {
178+
creditCard: true,
179+
creditCardOptions: {
180+
delimiter: ' ',
181+
delimiterLazyShow: true,
182+
},
183+
onCreditCardTypeChanged: this.updateCardIcon.bind(this)
184+
})
185+
186+
this.phoneInput = new BaseInput('#phone', {
187+
phone: true,
188+
phoneOptions: {
189+
format: 'international',
190+
}
191+
})
192+
}
193+
194+
private updateCardIcon(type: CreditCardType) {
195+
const iconElement = document.querySelector('.card-icon')
196+
iconElement.className = `card-icon ${type}`
197+
}
198+
199+
public async submit() {
200+
const cardNumber = this.cardInput.getUnformattedValue()
201+
const phone = this.phoneInput.getValue()
202+
203+
try {
204+
await processPayment({
205+
card: cardNumber,
206+
phone,
207+
})
208+
}
209+
catch (error) {
210+
this.handleError(error)
211+
}
212+
}
213+
214+
public destroy() {
215+
this.cardInput.destroy()
216+
this.phoneInput.destroy()
217+
}
218+
}
219+
```
220+
221+
### Dynamic Currency Input
222+
223+
```typescript
224+
class CurrencyInput {
225+
private input: BaseInput
226+
227+
constructor(selector: string, initialCurrency: string) {
228+
this.input = new BaseInput(selector, {
229+
numeral: true,
230+
numeralOptions: {
231+
thousandsSeparator: ',',
232+
decimalSeparator: '.',
233+
precision: 2,
234+
},
235+
onNumeralFormatChanged: (value) => {
236+
this.updateDisplay(value)
237+
}
238+
})
239+
240+
this.setCurrency(initialCurrency)
241+
}
242+
243+
public setCurrency(currency: string) {
244+
const value = this.input.getUnformattedValue()
245+
// Reconfigure for new currency format
246+
this.input.destroy()
247+
248+
this.input = new BaseInput(selector, {
249+
numeral: true,
250+
numeralOptions: {
251+
// Adjust format based on currency
252+
thousandsSeparator: currency === 'EUR' ? '.' : ',',
253+
decimalSeparator: currency === 'EUR' ? ',' : '.',
254+
precision: currency === 'JPY' ? 0 : 2,
255+
}
256+
})
257+
258+
this.input.setValue(value)
259+
}
260+
}
261+
```
262+
263+
## TypeScript Support
264+
265+
The library is written in TypeScript and provides comprehensive type definitions:
266+
267+
```typescript
268+
interface BaseInputOptions {
269+
// Input type flags
270+
creditCard?: boolean
271+
phone?: boolean
272+
numeral?: boolean
273+
general?: boolean
274+
275+
// Type-specific options
276+
creditCardOptions?: FormatCreditCardOptions
277+
phoneOptions?: FormatPhoneOptions
278+
numeralOptions?: FormatNumeralOptions
279+
generalOptions?: FormatGeneralOptions
280+
281+
// Event callbacks
282+
onValueChanged?: (formatted: string, unformatted: string) => void
283+
onFocus?: (event: FocusEvent) => void
284+
onBlur?: (event: FocusEvent) => void
285+
onCreditCardTypeChanged?: (type: CreditCardType) => void
286+
onPhoneFormatChanged?: (formatted: string) => void
287+
onNumeralFormatChanged?: (formatted: string) => void
288+
onGeneralFormatChanged?: (formatted: string) => void
289+
}
290+
```
291+
292+
## Best Practices
293+
294+
1. **Single Responsibility**
295+
- Use one input type per instance
296+
- Don't mix different formatting types
297+
298+
2. **Memory Management**
299+
- Always call `destroy()` when removing inputs
300+
- Clean up references in single-page applications
301+
302+
3. **Error Handling**
303+
- Wrap initialization in try-catch blocks
304+
- Validate input values before submission
305+
306+
4. **Performance**
307+
- Don't create multiple instances for the same input
308+
- Use lazy loading for large forms
309+
310+
5. **Accessibility**
311+
- Maintain proper ARIA attributes
312+
- Ensure keyboard navigation works
313+
- Provide clear error messages
314+
315+
## Browser Support
316+
317+
- Chrome (latest)
318+
- Firefox (latest)
319+
- Safari (latest)
320+
- Edge (latest)
321+
- IE11 (with appropriate polyfills)

0 commit comments

Comments
 (0)