refs Plugin
The refs plugin is a built-in Coralite helper that provides runtime DOM element access. It allows component scripts to safely access and manipulate DOM elements by their ref attributes. The framework handles automatic unique ID generation by assigning the generated ID to the ref attribute, leaving the standard id attribute intact.
Here's the complete workflow for using refs:
<template id="form-component">
<form>
<input type="text" ref="username" placeholder="Username"></input>
<input type="password" ref="password" placeholder="Password"></input>
<button type="button" ref="submitBtn">Submit</button>
</form>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script ({ state, signal, refs, ...pluginContext }) {
const username = refs('username')
const password = refs('password')
const submitBtn = refs('submitBtn')
submitBtn.addEventListener('click', () => {
if (username.value && password.value) {
console.log('Login:', username.value)
// Handle form submission
} else {
alert('Please fill all fields')
}
}, { signal })
}
})
</script>
<template id="counter">
<div class="counter">
<h2 ref="display">Count: {{ currentCount }}</h2>
<button type="button" ref="increment">+</button>
<button type="button" ref="decrement">-</button>
<button type="button" ref="reset">Reset</button>
</div>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
attributes: {
initial: {
type: Number,
default: 0
}
},
data ({ state }) {
return {
currentCount: state.initial
}
},
script ({ state, signal, refs, ...pluginContext }) {
const increment = refs('increment')
const decrement = refs('decrement')
const reset = refs('reset')
increment.addEventListener('click', () => {
state.currentCount++
}, { signal })
decrement.addEventListener('click', () => {
state.currentCount--
}, { signal })
reset.addEventListener('click', () => {
state.currentCount = state.initial
}, { signal })
}
})
</script>
<template id="signup-form">
<form>
<div>
<input type="email" ref="email" placeholder="Email"></input>
<span ref="emailError" class="error"></span>
</div>
<div>
<input type="password" ref="password" placeholder="Password"></input>
<span ref="passwordError" class="error"></span>
</div>
<button type="button" ref="submitBtn">Sign Up</button>
</form>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script ({ state, signal, refs, ...pluginContext }) {
const email = refs('email')
const password = refs('password')
const emailError = refs('emailError')
const passwordError = refs('passwordError')
const submitBtn = refs('submitBtn')
const validateEmail = (email) => {
return /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email)
}
const validatePassword = (password) => {
return password.length >= 8
}
submitBtn.addEventListener('click', () => {
let valid = true
// Validate email
if (!validateEmail(email.value)) {
emailError.textContent = 'Invalid email format'
valid = false
} else {
emailError.textContent = ''
}
// Validate password
if (!validatePassword(password.value)) {
passwordError.textContent = 'Password must be 8+ characters'
valid = false
} else {
passwordError.textContent = ''
}
if (valid) {
console.log('Form submitted:', email.value)
// Submit form
}
}, { signal })
}
})
</script>
<template id="tabs">
<div class="tabs">
<div class="tab-buttons">
<button type="button" ref="tab1">Tab 1</button>
<button type="button" ref="tab2">Tab 2</button>
<button type="button" ref="tab3">Tab 3</button>
</div>
<div class="tab-content">
<div ref="content1">Content 1</div>
<div ref="content2" style="display:none">Content 2</div>
<div ref="content3" style="display:none">Content 3</div>
</div>
</div>
</template>
<script type="module">
import { defineComponent } from 'coralite'
export default defineComponent({
script ({ state, signal, refs, ...pluginContext }) {
const buttons = [refs('tab1'), refs('tab2'), refs('tab3')]
const contents = [refs('content1'), refs('content2'), refs('content3')]
buttons.forEach((btn, index) => {
btn.addEventListener('click', () => {
// Hide all contents
contents.forEach(content => {
content.style.display = 'none'
})
// Show selected content
contents[index].style.display = 'block'
// Update button states
buttons.forEach(b => b.classList.remove('active'))
btn.classList.add('active')
}, { signal })
})
}
})
</script>
- Runtime Access:
refs('refName')gets DOM elements - Automatic Caching: Elements cached after first access
- Safe Queries: Returns null if element not found
- Under the Hood: Framework assigns the generated unique ID to the
refattribute and queries it viadocument.querySelector('[ref="..."]'). E2E tests should query this compiled ref attribute directly (e.g.,[ref="my-component__btn-0"]).