@kneelinghorse/semantic-protocol-web-components
v2.0.0
Published
Web Components for Semantic Protocol - Framework-agnostic custom elements
Maintainers
Readme
@semantic-protocol/web-components
Framework-agnostic Web Components for the Semantic Protocol with Shadow DOM encapsulation.
Features
- 🎯 Native Web Components - Works with any framework or vanilla JavaScript
- 🔒 Shadow DOM - Encapsulated styles and DOM structure
- 🌐 Cross-Framework - React, Vue, Angular, Svelte adapters included
- 📦 CDN Ready - Use via CDN or npm package
- 🎨 Customizable - Override styles and extend functionality
- ♿ Accessible - ARIA compliant with keyboard navigation
- 📱 Responsive - Mobile-first responsive design
- 🚀 Lightweight - ~15KB gzipped with zero dependencies
Installation
NPM
npm install @semantic-protocol/web-componentsCDN
<!-- Auto-initializing version -->
<script src="https://unpkg.com/@semantic-protocol/web-components/dist/semantic-components.auto.js"></script>
<!-- Manual initialization -->
<script src="https://unpkg.com/@semantic-protocol/web-components/dist/semantic-components.umd.js"></script>
<script>
SemanticComponents.defineElements();
</script>Quick Start
Vanilla JavaScript
<semantic-provider debug="true">
<semantic-field
type="email"
name="email"
label="Email Address"
required
></semantic-field>
<semantic-discovery
type="input"
display-mode="grid"
></semantic-discovery>
</semantic-provider>
<script type="module">
import '@semantic-protocol/web-components';
const field = document.querySelector('semantic-field');
field.addEventListener('semantic-change', (e) => {
console.log('Value:', e.detail.value);
});
</script>React
import '@semantic-protocol/web-components';
function App() {
return (
<semantic-provider>
<semantic-field
type="email"
name="email"
label="Email"
required
onSemanticChange={(e) => console.log(e.detail.value)}
/>
</semantic-provider>
);
}Vue 3
<template>
<semantic-provider>
<semantic-field
v-model="email"
type="email"
name="email"
label="Email"
:required="true"
@semantic-change="handleChange"
/>
</semantic-provider>
</template>
<script setup>
import '@semantic-protocol/web-components';
import { ref } from 'vue';
const email = ref('');
const handleChange = (e) => console.log(e.detail.value);
</script>Components
<semantic-provider>
Root component that provides semantic context and registry.
<semantic-provider
debug="true"
auto-discover="true"
validation-mode="strict"
>
<!-- Child components -->
</semantic-provider>Attributes:
debug- Show debug panel with registry infoauto-discover- Auto-discover existing semantic elementsvalidation-mode- Validation strictness:strict,loose,none
Methods:
discover(query)- Find components by semantic querygetRegistry()- Get all registered componentsgetRelationships()- Get component relationships
<semantic-field>
Form field with built-in validation and semantic awareness.
<semantic-field
type="email"
name="email"
label="Email Address"
value="[email protected]"
required
disabled
readonly
error="Invalid email"
hint="Enter your email"
minlength="5"
maxlength="100"
pattern=".*@.*"
></semantic-field>Attributes:
type- Field type:text,email,password,number,tel,url,date,textarea,selectname- Field name for form submissionlabel- Field label textvalue- Field valuerequired- Required field flagdisabled- Disabled statereadonly- Read-only stateerror- Error message to displayhint- Helper text- Validation:
minlength,maxlength,min,max,pattern
Methods:
validate()- Validate field and return booleangetValue()- Get current valuesetValue(value)- Set field valuereset()- Reset field to initial state
Properties:
value- Current valuevalid- Validation stateerrors- Array of validation errors
Events:
semantic-input- Fired on inputsemantic-change- Fired on changesemantic-blur- Fired on blursemantic-focus- Fired on focussemantic-validate- Fired after validation
<semantic-discovery>
Component discovery and visualization.
<semantic-discovery
query='{"type": "input"}'
type="input"
intent="collect-data"
tags="form,registration"
display-mode="grid"
auto-refresh="5000"
></semantic-discovery>Attributes:
query- JSON query string or selectortype- Filter by element typeintent- Filter by element intenttags- Comma-separated tags to filterdisplay-mode- Display mode:list,gridauto-refresh- Auto-refresh interval in milliseconds
Methods:
refresh()- Refresh discovery resultsclear()- Clear resultsgetResults()- Get current results array
Events:
semantic-discovery-complete- Fired when discovery completessemantic-inspect- Fired when inspecting a componentsemantic-highlight- Fired when highlighting a component
Framework Adapters
React Wrapper
import { createFrameworkWrapper } from '@semantic-protocol/web-components';
import { SemanticField } from '@semantic-protocol/web-components';
const SemanticFieldReact = createFrameworkWrapper(SemanticField, 'react');
function Form() {
const [value, setValue] = useState('');
return (
<SemanticFieldReact
type="email"
value={value}
onChange={(e) => setValue(e.detail.value)}
/>
);
}Vue Wrapper
import { createFrameworkWrapper } from '@semantic-protocol/web-components';
import { SemanticField } from '@semantic-protocol/web-components';
export default {
components: {
SemanticField: createFrameworkWrapper(SemanticField, 'vue')
}
};Styling
CSS Custom Properties
semantic-field {
--field-border-color: #ddd;
--field-focus-color: #2196F3;
--field-error-color: #e53935;
--field-border-radius: 4px;
--field-padding: 0.75rem;
}Override Shadow DOM Styles
class CustomField extends SemanticField {
defaultStyles() {
return `
${super.defaultStyles()}
.field-input {
background: #f0f0f0;
}
`;
}
}TypeScript Support
import {
SemanticProvider,
SemanticField,
SemanticDiscovery,
SemanticElement
} from '@semantic-protocol/web-components';
// Type-safe element queries
const field = document.querySelector<SemanticField>('semantic-field');
if (field) {
const value: string = field.value;
const valid: boolean = field.valid;
const errors: string[] = field.errors;
}
// Extend for custom elements
class CustomElement extends SemanticElement {
getManifest(): SemanticManifest {
return {
protocol: 'semantic-ui/v2',
element: { type: 'custom' }
};
}
render(): string {
return '<div>Custom content</div>';
}
}Browser Support
- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+
Polyfills available for older browsers via @webcomponents/webcomponentsjs.
License
MIT
Contributing
See CONTRIBUTING.md
