Components in Anchor for React
Anchor provides a set of UI components that integrate directly with reactive state, simplifying form handling and ensuring optimal performance. These components automatically bind to state properties, reducing boilerplate and ensuring that only the necessary parts of your UI re-render when state changes.
How Components Work
Anchor's components directly bind to reactive state properties, eliminating the need for explicit state management hooks like useState
and onChange
handlers for each input. When a user interacts with an Anchor component, the bound state property is automatically updated, and any components observing that property will re-render accordingly.
This approach addresses common React pain points:
- Boilerplate Reduction: No need for
useState
andonChange
handlers for every input - Prop Drilling Elimination: Direct binding to state eliminates the need to pass values and setters down component trees
- Optimized Re-renders: Only the input and its direct consumers re-render when the bound value changes
Input Components
These are UI input components that bind directly to reactive state properties.
Input
A versatile React component for text and other input types, binding directly to a reactive state property.
Props
bind
- The Anchor reactive state object to which this input will be boundname
- The key (property name) within thebind
object that this input will control- All standard HTML input attributes - All other standard HTML
<input>
attributes are supported
Usage
Basic Text Input
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Input } from '@anchorlib/react/components';
const UserProfile = observable(() => {
const [user] = useAnchor({
name: '',
email: '',
});
return (
<div>
<h2>User Profile</h2>
<div>
<label htmlFor="userName">Name:</label>
<Input bind={user} name="name" id="userName" placeholder="Enter your name" />
</div>
<div>
<label htmlFor="userEmail">Email:</label>
<Input bind={user} name="email" id="userEmail" type="email" placeholder="Enter your email" />
</div>
<div>
<h3>Current Values:</h3>
<p>Name: {user.name}</p>
<p>Email: {user.email}</p>
</div>
</div>
);
});
export default UserProfile;
Number Input with Automatic Conversion
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Input } from '@anchorlib/react/components';
const ProductForm = observable(() => {
const [product] = useAnchor({
name: '',
price: 0,
quantity: 1,
});
return (
<div>
<h2>Product Form</h2>
<div>
<label htmlFor="productName">Product Name:</label>
<Input bind={product} name="name" id="productName" placeholder="Enter product name" />
</div>
<div>
<label htmlFor="productPrice">Price:</label>
<Input bind={product} name="price" id="productPrice" type="number" step="0.01" placeholder="0.00" />
</div>
<div>
<label htmlFor="productQuantity">Quantity:</label>
<Input bind={product} name="quantity" id="productQuantity" type="number" placeholder="1" />
</div>
<div>
<h3>Product Details:</h3>
<p>Name: {product.name}</p>
<p>Price: ${product.price.toFixed(2)}</p>
<p>Quantity: {product.quantity}</p>
<p>Total Value: ${(product.price * product.quantity).toFixed(2)}</p>
</div>
</div>
);
});
export default ProductForm;
When to use it?
Use the Input
component whenever you need to bind text or numeric input values to reactive state properties. It automatically handles type conversion for number inputs and provides seamless integration with Anchor's reactivity system.
Checkbox
A React component for a checkbox input, binding directly to a reactive boolean state property.
Props
bind
- The Anchor reactive state object to which this checkbox will be boundname
- The key (property name) within thebind
object that this checkbox will controlchecked
(optional) - The initial checked state if the bound property is undefined- All standard HTML checkbox attributes - All other standard HTML checkbox attributes are supported
Usage
Basic Checkbox Binding
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Checkbox } from '@anchorlib/react/components';
const UserPreferences = observable(() => {
const [preferences] = useAnchor({
receiveNewsletter: true,
acceptTerms: false,
});
return (
<div>
<h2>User Preferences</h2>
<div>
<label>
<Checkbox bind={preferences} name="receiveNewsletter" id="newsletterCheckbox" />
Receive Newsletter
</label>
</div>
<div>
<label>
<Checkbox bind={preferences} name="acceptTerms" id="termsCheckbox" />I accept the terms and conditions
</label>
</div>
<h3>Current Preferences:</h3>
<p>Newsletter: {preferences.receiveNewsletter ? 'Subscribed' : 'Not Subscribed'}</p>
<p>Terms Accepted: {preferences.acceptTerms ? 'Yes' : 'No'}</p>
</div>
);
});
export default UserPreferences;
Checkbox with Initial State
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Checkbox } from '@anchorlib/react/components';
const FeatureToggle = observable(() => {
const [featureFlags] = useAnchor({
betaFeatures: undefined, // Initially undefined
});
return (
<div>
<h2>Feature Flags</h2>
<div>
<label>
<Checkbox
bind={featureFlags}
name="betaFeatures"
id="betaFeaturesCheckbox"
checked={false} // Default to unchecked if betaFeatures is undefined
/>
Enable Beta Features
</label>
</div>
<p>Beta Features Status: {featureFlags.betaFeatures ? 'Enabled' : 'Disabled'}</p>
</div>
);
});
export default FeatureToggle;
When to use it?
Use the Checkbox
component when you need to bind boolean values to reactive state properties. It's perfect for toggles, feature flags, and preference settings.
Radio
A React component for a radio button input, binding directly to a reactive state property.
Props
bind
- The Anchor reactive state object to which this radio button will be boundname
- The key (property name) within thebind
object that this radio button will controlvalue
- The value that will be assigned to the bound property when this radio button is selectedchecked
(optional) - Whether this radio button should be initially checked- All standard HTML radio attributes - All other standard HTML radio button attributes are supported
Usage
Radio Group for Single Selection
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Radio } from '@anchorlib/react/components';
const ThemeSelector = observable(() => {
const [settings] = useAnchor({
theme: 'light', // Default theme
});
return (
<div>
<h2>Theme Settings</h2>
<fieldset>
<legend>Select Theme:</legend>
<label>
<Radio bind={settings} name="theme" value="light" />
Light Theme
</label>
<label>
<Radio bind={settings} name="theme" value="dark" />
Dark Theme
</label>
<label>
<Radio bind={settings} name="theme" value="auto" />
Auto (System Default)
</label>
</fieldset>
<p>Current Theme: {settings.theme}</p>
</div>
);
});
export default ThemeSelector;
Radio Buttons with Custom Values
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Radio } from '@anchorlib/react/components';
const PrioritySelector = observable(() => {
const [task] = useAnchor({
priority: 'medium',
});
return (
<div>
<h2>Task Priority</h2>
<fieldset>
<legend>Select Priority:</legend>
<label>
<Radio bind={task} name="priority" value="low" />
Low
</label>
<label>
<Radio bind={task} name="priority" value="medium" />
Medium
</label>
<label>
<Radio bind={task} name="priority" value="high" />
High
</label>
<label>
<Radio bind={task} name="priority" value="critical" />
Critical
</label>
</fieldset>
<p>Selected Priority: {task.priority}</p>
</div>
);
});
export default PrioritySelector;
When to use it?
Use the Radio
component when you need users to make a single selection from a group of options. Each radio button in a group should have the same name
prop but different value
props.
Select
A React component for a select dropdown, binding directly to a reactive state property.
Props
bind
- The Anchor reactive state object to which this select will be boundname
- The key (property name) within thebind
object that this select will controlvalue
(optional) - The initial selected value if the bound property is undefined- All standard HTML select attributes - All other standard HTML
<select>
attributes are supported
Usage
Basic Select Dropdown
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Select } from '@anchorlib/react/components';
const CountrySelector = observable(() => {
const [user] = useAnchor({
country: '',
});
return (
<div>
<h2>Country Selection</h2>
<div>
<label htmlFor="countrySelect">Select your country:</label>
<Select bind={user} name="country" id="countrySelect">
<option value="">-- Please select --</option>
<option value="us">United States</option>
<option value="ca">Canada</option>
<option value="uk">United Kingdom</option>
<option value="au">Australia</option>
<option value="de">Germany</option>
</Select>
</div>
<p>Selected Country: {user.country ? user.country.toUpperCase() : 'None'}</p>
</div>
);
});
export default CountrySelector;
Select with Initial Value
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Select } from '@anchorlib/react/components';
const RoleSelector = observable(() => {
const [employee] = useAnchor({
role: undefined, // No initial role
});
return (
<div>
<h2>Employee Role</h2>
<div>
<label htmlFor="roleSelect">Select role:</label>
<Select
bind={employee}
name="role"
id="roleSelect"
value="employee" // Default value if role is undefined
>
<option value="employee">Employee</option>
<option value="manager">Manager</option>
<option value="director">Director</option>
<option value="vp">Vice President</option>
<option value="ceo">CEO</option>
</Select>
</div>
<p>Current Role: {employee.role || 'Not set'}</p>
</div>
);
});
export default RoleSelector;
When to use it?
Use the Select
component when you need users to choose from a dropdown list of options. It's ideal for categorical data like countries, roles, or status values.
ColorPicker
A React component for a color input, binding directly to a reactive string state property representing a color value.
Props
bind
- The Anchor reactive state object to which this color picker will be boundname
- The key (property name) within thebind
object that this color picker will controlvalue
(optional) - The initial color value if the bound property is undefined- All standard HTML color input attributes - All other standard HTML
<input type="color">
attributes are supported
Usage
Basic Color Picker
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { ColorPicker } from '@anchorlib/react/components';
const ThemeCustomizer = observable(() => {
const [theme] = useAnchor({
primaryColor: '#3498db',
secondaryColor: '#2ecc71',
});
return (
<div>
<h2>Theme Customizer</h2>
<div>
<label htmlFor="primaryColor">Primary Color:</label>
<ColorPicker bind={theme} name="primaryColor" id="primaryColor" />
<span
style={{
display: 'inline-block',
width: '20px',
height: '20px',
backgroundColor: theme.primaryColor,
border: '1px solid #ccc',
marginLeft: '10px',
}}></span>
</div>
<div>
<label htmlFor="secondaryColor">Secondary Color:</label>
<ColorPicker bind={theme} name="secondaryColor" id="secondaryColor" />
<span
style={{
display: 'inline-block',
width: '20px',
height: '20px',
backgroundColor: theme.secondaryColor,
border: '1px solid #ccc',
marginLeft: '10px',
}}></span>
</div>
<div
style={{
padding: '20px',
marginTop: '20px',
backgroundColor: theme.primaryColor,
color: theme.secondaryColor,
}}>
<h3>Preview</h3>
<p>This is a preview of your color scheme</p>
</div>
</div>
);
});
export default ThemeCustomizer;
When to use it?
Use the ColorPicker
component when you need users to select colors. It's perfect for theme customization, design tools, or any application where color selection is important.
Interactive Components
These components provide interactive UI elements that bind to reactive state.
Toggle
A React component for a toggle button, binding directly to a reactive state property.
Props
bind
- The Anchor reactive state object to which this toggle will be boundname
- The key (property name) within thebind
object that this toggle will controlvalue
(optional) - The value that will be assigned to the bound property when toggled- All standard HTML button attributes - All other standard HTML button attributes are supported
Usage
Basic Toggle Button
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Toggle } from '@anchorlib/react/components';
const NotificationToggle = observable(() => {
const [settings] = useAnchor({
notifications: false,
});
return (
<div>
<h2>Notification Settings</h2>
<div>
<Toggle bind={settings} name="notifications" value={true}>
{settings.notifications ? 'Notifications ON' : 'Notifications OFF'}
</Toggle>
</div>
<p>Status: {settings.notifications ? 'Enabled' : 'Disabled'}</p>
</div>
);
});
export default NotificationToggle;
Toggle with Multiple Values
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Toggle } from '@anchorlib/react/components';
const ViewModeToggle = observable(() => {
const [ui] = useAnchor({
viewMode: 'grid', // Default view mode
});
return (
<div>
<h2>View Mode</h2>
<div>
<Toggle bind={ui} name="viewMode" value={ui.viewMode === 'grid' ? 'list' : 'grid'}>
Switch to {ui.viewMode === 'grid' ? 'List' : 'Grid'} View
</Toggle>
</div>
<div style={{ marginTop: '20px' }}>
{ui.viewMode === 'grid' ? (
<div style={{ display: 'grid', gridTemplateColumns: 'repeat(3, 1fr)', gap: '10px' }}>
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={i} style={{ padding: '20px', border: '1px solid #ccc' }}>
Grid Item {i}
</div>
))}
</div>
) : (
<div>
{[1, 2, 3, 4, 5, 6].map((i) => (
<div key={i} style={{ padding: '10px', borderBottom: '1px solid #ccc' }}>
List Item {i}
</div>
))}
</div>
)}
</div>
</div>
);
});
export default ViewModeToggle;
When to use it?
Use the Toggle
component when you need a button that toggles between states or values. It's great for feature toggles, view modes, or any binary state control.
ToggleGroup
A React component for grouping toggle buttons.
Props
- All standard HTML div attributes - All standard HTML div attributes are supported
Usage
Toggle Button Group
import React from 'react';
import { useAnchor } from '@anchorlib/react';
import { observable } from '@anchorlib/react/components';
import { Toggle, ToggleGroup } from '@anchorlib/react/components';
const FilterControls = observable(() => {
const [filters] = useAnchor({
category: 'all',
});
return (
<div>
<h2>Product Filters</h2>
<ToggleGroup style={{ display: 'flex', gap: '10px', marginBottom: '20px' }}>
<Toggle
bind={filters}
name="category"
value="all"
style={{
padding: '8px 16px',
backgroundColor: filters.category === 'all' ? '#007bff' : '#f8f9fa',
color: filters.category === 'all' ? 'white' : 'black',
border: '1px solid #ccc',
borderRadius: '4px',
cursor: 'pointer',
}}>
All Products
</Toggle>
<Toggle
bind={filters}
name="category"
value="electronics"
style={{
padding: '8px 16px',
backgroundColor: filters.category === 'electronics' ? '#007bff' : '#f8f9fa',
color: filters.category === 'electronics' ? 'white' : 'black',
border: '1px solid #ccc',
borderRadius: '4px',
cursor: 'pointer',
}}>
Electronics
</Toggle>
<Toggle
bind={filters}
name="category"
value="clothing"
style={{
padding: '8px 16px',
backgroundColor: filters.category === 'clothing' ? '#007bff' : '#f8f9fa',
color: filters.category === 'clothing' ? 'white' : 'black',
border: '1px solid #ccc',
borderRadius: '4px',
cursor: 'pointer',
}}>
Clothing
</Toggle>
</ToggleGroup>
<p>Selected Category: {filters.category}</p>
</div>
);
});
export default FilterControls;
When to use it?
Use the ToggleGroup
component to group related toggle buttons together. It provides a semantic wrapper that helps with styling and accessibility.
Best Practices
When working with Anchor's components, keep these best practices in mind:
- Use Appropriate Components: Choose the right component for your use case:
Input
for text and numeric inputsCheckbox
for boolean togglesRadio
for single selection from a groupSelect
for dropdown selectionsColorPicker
for color selectionToggle
for toggle buttonsToggleGroup
for grouping toggles
- Leverage Direct Binding: Take advantage of direct state binding to reduce boilerplate code and simplify your components.
- Combine with Other APIs: Use Anchor's components in conjunction with other APIs like
useDerived
,useValue
, and observation patterns for more complex UI logic. - Handle Edge Cases: Use the
value
andchecked
props to handle initial states when the bound property might be undefined. - Style Consistently: Since these components accept all standard HTML attributes, you can style them just like regular HTML elements.