stenc-input
v0.0.1
Published
A input web component built with Stencil
Maintainers
Readme
stenc-input
A form-associated input web component built with Stencil. Fully integrates with HTML forms, supports validation, and works seamlessly with form submission.
Features
✅ Form-Associated - Works natively with HTML forms using ElementInternals API ✅ Full Validation Support - Built-in HTML5 validation (required, pattern, minlength, etc.) ✅ Custom Validation - Support for custom validation messages ✅ Accessible - ARIA attributes for screen readers ✅ Styled States - Focus, error, disabled, readonly states ✅ Type Support - text, email, password, number, tel, url, search ✅ Size Variants - small, medium, large ✅ Dark Mode - Automatic dark mode support
Installation
npm install stenc-inputUsage
Import the Component
import 'stenc-input';Using with Script Tag
<script type="module" src="https://unpkg.com/stenc-input/dist/stenc-input/stenc-input.esm.js"></script>Examples
Basic Input
<poc-input
label="Username"
name="username"
placeholder="Enter your username"
></poc-input>Required Field with Validation
<poc-input
label="Email"
name="email"
type="email"
required
placeholder="[email protected]"
helper-text="We'll never share your email"
></poc-input>Password Input
<poc-input
label="Password"
name="password"
type="password"
required
minlength="8"
placeholder="At least 8 characters"
></poc-input>With Custom Validation
<poc-input
label="Phone"
name="phone"
type="tel"
pattern="[0-9]{3}-[0-9]{3}-[0-9]{4}"
placeholder="123-456-7890"
></poc-input>Different Sizes
<poc-input size="small" label="Small Input"></poc-input>
<poc-input size="medium" label="Medium Input"></poc-input>
<poc-input size="large" label="Large Input"></poc-input>Disabled and Readonly
<poc-input label="Disabled" value="Cannot edit" disabled></poc-input>
<poc-input label="Readonly" value="Can view only" readonly></poc-input>With Error Message
<poc-input
label="Username"
name="username"
value="ab"
error-message="Username must be at least 3 characters"
></poc-input>In a Form
<form id="signup-form">
<poc-input
label="Username"
name="username"
required
minlength="3"
></poc-input>
<poc-input
label="Email"
name="email"
type="email"
required
></poc-input>
<poc-input
label="Password"
name="password"
type="password"
required
minlength="8"
></poc-input>
<button type="submit">Sign Up</button>
</form>
<script>
document.getElementById('signup-form').addEventListener('submit', (e) => {
e.preventDefault();
const formData = new FormData(e.target);
console.log(Object.fromEntries(formData));
});
</script>Props
| Property | Attribute | Type | Default | Description |
|----------|-----------|------|---------|-------------|
| value | value | string | '' | The input value |
| name | name | string | '' | The input name (for form submission) |
| type | type | 'text' \| 'email' \| 'password' \| 'number' \| 'tel' \| 'url' \| 'search' | 'text' | The input type |
| label | label | string | '' | Input label text |
| placeholder | placeholder | string | '' | Placeholder text |
| required | required | boolean | false | Whether the input is required |
| disabled | disabled | boolean | false | Whether the input is disabled |
| readonly | readonly | boolean | false | Whether the input is readonly |
| minlength | minlength | number | undefined | Minimum length validation |
| maxlength | maxlength | number | undefined | Maximum length validation |
| pattern | pattern | string | undefined | Regex pattern for validation |
| size | size | 'small' \| 'medium' \| 'large' | 'medium' | Input size variant |
| errorMessage | error-message | string | '' | Custom error message to display |
| helperText | helper-text | string | '' | Helper text displayed below input |
| autocomplete | autocomplete | string | 'off' | Autocomplete attribute |
Events
| Event | Description | Detail Type |
|-------|-------------|-------------|
| pocInputChange | Emitted when the value changes | string |
| pocInputFocus | Emitted when input receives focus | FocusEvent |
| pocInputBlur | Emitted when input loses focus | FocusEvent |
| pocInputCommit | Emitted when value is committed (Enter key or blur) | string |
Methods
| Method | Description | Returns |
|--------|-------------|---------|
| setFocus() | Programmatically focus the input | Promise<void> |
| select() | Select the input text | Promise<void> |
| getValidity() | Get the input validity state | Promise<ValidityState \| undefined> |
| checkValidity() | Check if the input is valid | Promise<boolean> |
| setCustomValidity(message: string) | Set a custom validation message | Promise<void> |
Framework Integration
React
import { defineCustomElements } from 'stenc-input/loader';
// Call this once in your app entry point
defineCustomElements();
function SignupForm() {
const [username, setUsername] = useState('');
const handleChange = (e) => {
setUsername(e.detail);
};
const handleSubmit = (e) => {
e.preventDefault();
const formData = new FormData(e.target);
console.log(Object.fromEntries(formData));
};
return (
<form onSubmit={handleSubmit}>
<poc-input
label="Username"
name="username"
value={username}
required
onPocInputChange={handleChange}
/>
<button type="submit">Submit</button>
</form>
);
}Vue
<template>
<form @submit.prevent="handleSubmit">
<poc-input
label="Username"
name="username"
:value="username"
required
@pocInputChange="handleChange"
/>
<button type="submit">Submit</button>
</form>
</template>
<script>
import { defineCustomElements } from 'stenc-input/loader';
defineCustomElements();
export default {
data() {
return {
username: ''
};
},
methods: {
handleChange(event) {
this.username = event.detail;
},
handleSubmit(event) {
const formData = new FormData(event.target);
console.log(Object.fromEntries(formData));
}
}
};
</script>Angular
In your main.ts:
import { defineCustomElements } from 'stenc-input/loader';
defineCustomElements();Add to your module:
import { CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';
@NgModule({
schemas: [CUSTOM_ELEMENTS_SCHEMA]
})In your component:
import { Component } from '@angular/core';
@Component({
selector: 'app-signup',
template: `
<form (submit)="onSubmit($event)">
<poc-input
label="Username"
name="username"
required
(pocInputChange)="onUsernameChange($event)"
></poc-input>
<button type="submit">Submit</button>
</form>
`
})
export class SignupComponent {
username = '';
onUsernameChange(event: CustomEvent) {
this.username = event.detail;
}
onSubmit(event: Event) {
event.preventDefault();
const formData = new FormData(event.target as HTMLFormElement);
console.log(Object.fromEntries(formData));
}
}Form Association
This component uses the ElementInternals API to fully integrate with HTML forms:
<form id="myForm">
<poc-input name="email" type="email" required></poc-input>
<poc-input name="age" type="number" min="18"></poc-input>
<button type="submit">Submit</button>
</form>
<script>
const form = document.getElementById('myForm');
form.addEventListener('submit', (e) => {
e.preventDefault();
// Form validation happens automatically
if (form.checkValidity()) {
const formData = new FormData(form);
console.log('Form data:', Object.fromEntries(formData));
}
});
</script>Validation
The component supports HTML5 validation:
required- Field is requiredtype- Validates email, url, etc.pattern- Custom regex validationminlength/maxlength- Length validation- Custom validation via
setCustomValidity()
const input = document.querySelector('poc-input');
// Set custom validation
await input.setCustomValidity('This username is already taken');
// Check validity
const isValid = await input.checkValidity();
// Get validity state
const validity = await input.getValidity();Styling
The component uses Shadow DOM with default styles. It supports:
- Focus states
- Error states
- Disabled states
- Readonly states
- Dark mode (automatic)
Accessibility
- Proper ARIA attributes (
aria-invalid,aria-describedby) - Keyboard navigation support
- Screen reader friendly
- Focus management
Browser Support
- Chrome (latest)
- Firefox (latest)
- Safari (latest)
- Edge (latest)
Note: Form association requires browsers that support the ElementInternals API (Chrome 77+, Edge 79+, Safari 16.4+, Firefox 93+).
License
MIT
