Feature modules for POL applications
npm install @pol-studios/features> Feature modules for POL applications
Business feature modules that encapsulate common application patterns including comments, ordering, punch-lists, and filter utilities. Built on top of @pol-studios/db and @pol-studios/db/auth.
``bash`
pnpm add @pol-studios/features
`bash`
pnpm add react @pol-studios/db @pol-studios/db/auth @pol-studios/utils
`tsx
import { CommentProvider, useComments } from "@pol-studios/features/comments";
import { useOrderManager } from "@pol-studios/features/ordering";
import { usePunchListPage } from "@pol-studios/features/punch-list";
import { FilterProvider, useFilterContext } from "@pol-studios/features/filter-utils";
// Comments on any entity
function ProjectComments({ projectId }) {
return (
);
}
// Drag-and-drop ordering
function TaskList({ tasks }) {
const { items, moveItem, saveOrder } = useOrderManager(tasks);
// ... render sortable list
}
`
| Path | Description |
|------|-------------|
| @pol-studios/features | All exports combined |@pol-studios/features/comments
| | Comment system for entities |@pol-studios/features/ordering
| | Drag-and-drop ordering utilities |@pol-studios/features/punch-list
| | Punch-list / checklist functionality |@pol-studios/features/filter-utils
| | Filter builder utilities |
Provides a complete comment system with reactions, read tracking, and quotes.
`tsx
import {
CommentProvider,
useComments,
CommentContext,
} from "@pol-studios/features/comments";
import type {
CommentContextType,
CommentWithRelations,
Quote,
ProfileRow,
CoreCommentRow,
CoreCommentReactionRow,
CoreCommentReadRow,
CommentProviderProps,
} from "@pol-studios/features/comments";
// Wrap component with CommentProvider
entityId={projectId}
userId={currentUserId}
>
// Use comments in child components
function CommentSection() {
const {
comments, // All comments with relations
isLoading, // Loading state
addComment, // Add new comment
updateComment, // Edit comment
deleteComment, // Remove comment
addReaction, // React to comment
removeReaction, // Remove reaction
markAsRead, // Mark comment as read
replyTo, // Reply to specific comment
quote, // Quote text from comment
unreadCount, // Number of unread comments
} = useComments();
const handleSubmit = (text: string) => {
addComment({ text, parentId: null });
};
return (
$3
Utilities for managing item order with optimistic updates.
`tsx
import {
useOrderHint,
useOrderManager,
} from "@pol-studios/features/ordering";// Generate order hints for positioning
function useOrderHintExample() {
const { generateHint, getHintBetween } = useOrderHint();
// Get hint for inserting at position
const hint = generateHint(index, items);
// Get hint between two items
const betweenHint = getHintBetween(itemA.order_hint, itemB.order_hint);
}
// Full order management
function SortableList({ initialItems }) {
const {
items, // Ordered items
moveItem, // Move item to new position
reorder, // Reorder by drag-and-drop result
saveOrder, // Persist order to database
isDirty, // Has unsaved changes
isLoading, // Saving in progress
} = useOrderManager(initialItems, {
table: "tasks",
orderColumn: "order_hint",
});
const handleDragEnd = (result) => {
if (!result.destination) return;
reorder(result.source.index, result.destination.index);
};
return (
{(provided) => (
{items.map((item, index) => (
{(provided) => }
))}
{provided.placeholder}
)}
);
}
`$3
Punch-list / checklist page functionality for tracking items.
`tsx
import { usePunchListPage } from "@pol-studios/features/punch-list";function PunchListPage({ projectId }) {
const {
items, // Punch-list items
isLoading, // Loading state
filter, // Current filter
setFilter, // Update filter
stats, // Completion statistics
addItem, // Add new item
updateItem, // Update item
deleteItem, // Remove item
toggleComplete, // Toggle item completion
assignTo, // Assign item to user
groupBy, // Grouped items (by status, assignee, etc.)
} = usePunchListPage({
projectId,
defaultFilter: { status: "open" },
});
return (
items={items}
onToggle={toggleComplete}
onEdit={updateItem}
onDelete={deleteItem}
/>
);
}
`$3
Utilities for building dynamic filter UIs.
`tsx
import {
FilterProvider,
useFilterContext,
useNestedFilterOptions,
hookOnChange,
getDefaultValue,
getComparisonOptions,
getDefaultCondition,
genId,
getPropertyKey,
recurseToProperty,
getProperty,
} from "@pol-studios/features/filter-utils";// Wrap filter UI with provider
function FilterableList({ data, fields }) {
return (
);
}
// Build filter UI
function FilterBar() {
const {
filters, // Current filter conditions
addFilter, // Add new filter condition
removeFilter, // Remove filter condition
updateFilter, // Update filter value
clearFilters, // Clear all filters
applyFilters, // Apply filters to data
fields, // Available fields to filter
} = useFilterContext();
return (
{filters.map((filter) => (
key={filter.id}
filter={filter}
fields={fields}
onUpdate={(updates) => updateFilter(filter.id, updates)}
onRemove={() => removeFilter(filter.id)}
/>
))}
);
}// Nested filter options (for hierarchical data)
function CategoryFilter({ categories }) {
const options = useNestedFilterOptions(categories, {
labelKey: "name",
valueKey: "id",
childrenKey: "subcategories",
});
return ;
}
// Utility functions
const comparisonOptions = getComparisonOptions("string"); // ["equals", "contains", "startsWith", ...]
const defaultValue = getDefaultValue("number"); // 0
const defaultCondition = getDefaultCondition("date"); // { operator: "equals", value: null }
const id = genId(); // Unique filter ID
const key = getPropertyKey(field); // Normalized property key
const value = getProperty(obj, "nested.path"); // Get nested value
`TypeScript Types
`tsx
import type {
// Comments types
CommentContextType,
CommentWithRelations,
Quote,
ProfileRow,
CoreCommentRow,
CoreCommentReactionRow,
CoreCommentReadRow,
CommentProviderProps,
} from "@pol-studios/features/comments";
``- @pol-studios/db - Database layer (required peer dependency)
- @pol-studios/db/auth - Authentication (required peer dependency)
- @pol-studios/utils - Utility functions (required peer dependency)
- @pol-studios/ui - UI components for rendering features
UNLICENSED