Power Helpers
Power helpers are utility functions that extend Olova's functionality. They can be used in templates, directives, and expressions to transform data, format values, or provide reusable logic.
Basic Usage
js
const app = createApp({
data: {
price: 99.99,
items: ['Apple', 'Banana']
}
});
app.power({
// Add your helper functions here
uppercase: (str) => str.toUpperCase(),
currency: (num) => `$${num.toFixed(2)}`
});
html
<!-- Use in templates -->
<div>{uppercase(items[0])}</div> <!-- Output: APPLE -->
<div>{currency(price)}</div> <!-- Output: $99.99 -->
Helper Types
- Value Transformers Transform data into different formats.
js
app.power({
// Number formatting
currency: (value, currency = 'USD') =>
new Intl.NumberFormat('en-US', {
style: 'currency',
currency
}).format(value),
// Date formatting
dateFormat: (date) =>
new Intl.DateTimeFormat('en-US').format(date),
// String manipulation
truncate: (text, length = 20) =>
text.length > length ? `${text.slice(0, length)}...` : text
});
html
<div>{currency(99.99)}</div> <!-- $99.99 -->
<div>{currency(99.99, 'EUR')}</div> <!-- €99.99 -->
<div>{dateFormat(new Date())}</div> <!-- 3/14/2024 -->
<div>{truncate('Long text here', 10)}</div><!-- Long text... -->
- Computed Values Helpers that perform calculations.
js
app.power({
tax: (amount, rate = 0.08) => amount * rate,
total: (price, quantity) => price * quantity,
discount: (price, percent) => price * (1 - percent/100)
});
html
<div>Tax: {tax(price)}</div>
<div>Total: {total(price, quantity)}</div>
<div>Sale Price: {discount(price, 20)}</div>
- Static Values Constants that can be used throughout your app.
js
app.power({
TAX_RATE: 0.08,
SHIPPING_RATES: {
standard: 5.99,
express: 15.99
},
STATUS_CODES: {
active: 'ACTIVE',
pending: 'PENDING',
inactive: 'INACTIVE'
}
});
html
<div>Tax: {price * TAX_RATE}</div>
<div>Shipping: {SHIPPING_RATES.standard}</div>
Advanced Features
Dynamic Expressions Helpers can use expressions in curly braces to access state.
js
app.power({
total: (price) => `{price * quantity}`, // References state.quantity
greeting: (name) => `Hello, {username || name}!` // Uses fallback
});
Chaining Helpers Combine multiple helpers for complex transformations.
js
app.power({
double: x => x * 2,
addTax: x => x * (1 + TAX_RATE),
format: x => `$${x.toFixed(2)}`
});
html
<div>{format(addTax(double(price)))}</div>
Best Practices
js
// Good ✅
app.power({
calculateTotal: (price, quantity) => price * quantity
});
// Bad ❌
app.power({
calculateTotal: (price) => price * globalQuantity
});
- Use Descriptive Names
js
// Good ✅
app.power({
formatCurrency: (value) => `$${value.toFixed(2)}`,
calculateTaxAmount: (price) => price * 0.08
});
// Bad ❌
app.power({
fmt: (v) => `$${v.toFixed(2)}`,
calc: (p) => p * 0.08
});
- Handle Errors Gracefully
js
app.power({
safeDiv: (a, b) => {
try {
if (b === 0) return 'Cannot divide by zero';
return a / b;
} catch (error) {
console.error('Division error:', error);
return 'Error';
}
}
});
Common Use Cases
- Form Validation
js
app.power({
isEmail: (email) => /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(email),
isRequired: (value) => !!value && value.trim() !== '',
minLength: (value, min) => value.length >= min
});
- Data Formatting
js
app.power({
phoneFormat: (phone) => {
const cleaned = phone.replace(/\D/g, '');
return `(${cleaned.slice(0,3)}) ${cleaned.slice(3,6)}-${cleaned.slice(6)}`;
},
fileSize: (bytes) => {
const sizes = ['B', 'KB', 'MB', 'GB'];
let i = 0;
while (bytes >= 1024 && i < sizes.length - 1) {
bytes /= 1024;
i++;
}
return `${bytes.toFixed(1)} ${sizes[i]}`;
}
});
- UI Helpers
js
app.power({
classNames: (...classes) =>
classes.filter(Boolean).join(' '),
pluralize: (count, singular, plural) =>
count === 1 ? singular : (plural || `${singular}s`),
timeAgo: (date) => {
const seconds = Math.floor((new Date() - date) / 1000);
const intervals = {
year: 31536000,
month: 2592000,
week: 604800,
day: 86400,
hour: 3600,
minute: 60
};
for (const [unit, secondsInUnit] of Object.entries(intervals)) {
const interval = Math.floor(seconds / secondsInUnit);
if (interval >= 1) {
return `${interval} ${unit}${interval === 1 ? '' : 's'} ago`;
}
}
return 'just now';
}
});