
Research
Using Trusted Protocols Against You: Gmail as a C2 Mechanism
Socket uncovers malicious packages on PyPI using Gmail's SMTP protocol for command and control (C2) to exfiltrate data and execute commands.
fuzzy-tables
Advanced tools
A simple, flexible, and fast table component for React with built-in sorting, filtering, and customization options.
npm install fuzzy-tables
# or
yarn add fuzzy-tables
After installing the package you just need to add the styles on the root layout of your project:
import 'fuzzy-tables/styles.css';
This library is built around the concept of store-component factories. A function that returns a React component binded to a state store. This allows flexibility and easy access to the internal state of the table.
There are multiple ways to build a table:
The simplest way to create a table is by providing an array of field names:
const Table = buildTable(['name', 'email', 'status'])
For more control, you can define columns with custom headers and rendering:
const Table = buildTable([
{
header: 'Name',
field: 'name',
},
{
header: 'Email',
field: 'email',
render: (row) => <a href={`mailto:${row.email}`}>{row.email}</a>
},
{
header: 'Status',
field: 'status',
render: (row) => <StatusBadge status={row.status} />
}
])
Which can look like this:
You can also build a table from a Zod object. Fuzzy Tables will automatically infer the type of each field and render it accordingly as single line, date, checkbox, multiple select, single select, or object array.
import { z } from 'zod'
const Table = buildTable(z.object({
id: z.string(),
name: z.string(),
email: z.string().email(),
status: z.enum(['active', 'inactive']),
tags: z.array(z.string()),
lastLogin: z.date(),
isVerified: z.boolean(),
metadata: z.object({
role: z.string(),
level: z.number(),
}),
}))
Using the onRowClick
prop, you can give more functionality to your table
Fuzzy Tables provides several custom hooks for advanced table manipulation:
Access and manipulate the table's internal state directly:
const Table = buildTable(['name', 'email', 'status']);
function TableControls() {
const {
rowSelection, // Record of selected row IDs
toggleRowSelection,// Function to toggle row selection
setRowSelection, // Function to set row selection
sortingFields, // Current sorting configuration
toggleSortingField // Function to toggle field sorting
} = Table.useTableStore();
return (
<div>
<button onClick={() => toggleSortingField('name')}>
Sort by Name
</button>
<div>Selected Rows: {Object.keys(rowSelection).length}</div>
</div>
);
}
Get the currently selected rows from your data:
function SelectedRowsDisplay({ data }) {
const selectedRows = Table.useSelected(data);
return (
<div>
<h3>Selected Items ({selectedRows.length})</h3>
<ul>
{selectedRows.map(row => (
<li key={row.id}>{row.name}</li>
))}
</ul>
</div>
);
}
Register event handlers for custom table actions:
const Table = buildTable(['name', 'email'], ['edit', 'delete']);
function TableWithActions({ data }) {
// Register handler for edit action
// Important! The handler must not mutate along renders if not needed!!
const editHandler = useCallback((row) => {
console.log('Editing row:', row);
// Open edit modal, etc.
}, []);
Table.useHandler('edit', editHandler);
// Important! The handler must not mutate along renders if not needed!!
const deleteHandler = useCallback((row) => {
console.log('Deleting row:', row);
// Show confirmation dialog, etc.
}, []);
Table.useHandler('delete', deleteHandler);
return <Table data={data} />;
}
Here's a more complex example showing how to use all the hooks together:
const UserTable = buildTable(['name', 'email', 'status'], ['edit', 'delete']);
function UserManagement() {
const [users, setUsers] = useState([]);
// Get selected rows
const selectedUsers = UserTable.useSelected(users);
// Register handlers
UserTable.useHandler('edit', (user) => {
// Handle edit
});
UserTable.useHandler('delete', (user) => {
// Handle delete
});
// Access table store for custom controls
const { sortingFields, toggleRowSelection } = UserTable.useTableStore();
return (
<div>
<div className="controls">
<button
disabled={selectedUsers.length === 0}
onClick={() => console.log('Selected:', selectedUsers)}
>
Process Selected ({selectedUsers.length})
</button>
</div>
<UserTable data={users} />
<div className="info">
Current Sort: {sortingFields.map(f => `${f.field} ${f.direction}`).join(', ')}
</div>
</div>
);
}
Fuzzy Tables seamlessly integrates table and form functionality, recognizing that applications often need to create and update records with fields that mirror table columns. This unified approach simplifies development by maintaining consistency between your data display and input interfaces.
Fuzzy Tables provides two forms components: CreateForm
and UpdateForm
. These forms will render
each field accordingly based on fields
prop. Currently displaying fields are:
Support for more fields will be released soon.
These are the mappings for each zod object type:
z.string()
-> Text inputz.boolean()
-> Checkboxz.date()
-> Date inputOptional fields are supported. Adding .optional()
to a field will not enforce the field to be filled.
The CreateForm
component is used to create new records. It takes a list of fields and a submit handler.
import { zodFromFields } from 'fuzzy-tables/types';
import { z } from 'zod';
// These same fields can be used to build a table!!!
const tableFields = [
{ field: 'name', header: 'Name', z: z.string() },
{ field: 'email', header: 'Email', z: z.string().email() },
{ field: 'status', header: 'Status', z: z.enum(['active', 'inactive']) },
]
const upsertSchema = zodFromFields(tableFields);
const App = () => {
const createFormRef = useRef<CreateFormRef>(null);
return (
<>
<button onClick={() => createFormRef.current?.open()}>Create</button>
<CreateForm<z.infer<typeof upsertSchema>>
fields={tableFields}
ref={createFormRef}
title='New Record'
description='Create a new record by filling the fields below'
onSubmit={async (id, formData) => {
// Your submit logic here
}}
getErrorMessage={(error) => {
// Your error message logic here
// error could be TRPCClientError, ZodError, NetworkError, etc.
// Individual field errors are already handled by default, this function
// is only used for parsing global errors into a string message
return 'An error occurred';
}}
/>
</>
)
}
Do not loose typings on your forms! formData
will be typed from z.infer<typeof upsertSchema>
TODO'S:
FAQs
A modern React component library for fuzzy tables
The npm package fuzzy-tables receives a total of 10 weekly downloads. As such, fuzzy-tables popularity was classified as not popular.
We found that fuzzy-tables demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 0 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Research
Socket uncovers malicious packages on PyPI using Gmail's SMTP protocol for command and control (C2) to exfiltrate data and execute commands.
Product
We redesigned Socket's first logged-in page to display rich and insightful visualizations about your repositories protected against supply chain threats.
Product
Automatically fix and test dependency updates with socket fix—a new CLI tool that turns CVE alerts into safe, automated upgrades.