npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

mig-schema-table

v5.0.19

Published

This component will render fields dynamically based on openApi schema JSON. Styling can be done using Bootstrap 5 compatible classes

Readme

schema-table-component

This component will render fields dynamically based on openApi schema JSON. Styling can be done using Bootstrap 5 compatible classes

Install

npm install mig-schema-table

Usage

Schema Example:

const userSchema = {
  properties: {
    id: {
      type: "string",
      readOnly: true,
    },
    name: {
      type: "string",
      minLength: 3,
    },
    dob: {
      type: "string",
      format: "date",
    },
    address: {
      type: "string",
      maxLength: 250,
    },
  },
  required: ["name"],
};
import React from "react";
import { SchemaTable, IColumnConfig } from "mig-schema-table";
import "mig-schema-table/dist/mig-schema-table.css";
// Add this for default datepicker styling
import "react-datepicker/dist/react-datepicker.css";
// Optionally add bootstrap5 styles

const config: { [keyName: string]: IColumnConfig } = {
  id: {
    hidden: true,
  },
  dob: {
    title: "Date of Birth",
  },
};

const Table = () => {
  const [users, setUsers] = useState();

  return (
    <SchemaTableComponent
      data={users || []}
      schema={userSchema}
      width={window.innerWidth}
      height={window.innerHeight - 150}
      config={config}
    />
  );
};

Component Props

| Prop | Type | Description | | --------------------------- | ------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------- | | schema | SchemaObject | OpenAPI schema object used to render the columns/fields dynamically. Required. | | data | T[] \| (getDataProps) => Promise<T[]> | Row data array, or an async function that resolves the data based on the current table state. Required. | | config | { [keyName: string]: IColumnConfig } | Per-column UI configuration (see Config). | | width | number | Width of the table. | | maxHeight | number \| "100%" | Maximum height of the table. | | rowHeight | number | Height of a single row (default 36). | | style | React.CSSProperties | Custom inline styles for the table container. | | tableTitle | string | Custom title shown for the table. | | searchPlaceholder | string | Placeholder text for the search input. | | isSearchable | boolean | If true, the search field is shown (default true). | | isSortable | boolean | If true, columns can be sorted (default true). | | isColumnFilterable | boolean | If true, per-column filtering is enabled (default true). | | isResizable | boolean | If true, columns can be resized (default true). | | isExportable | boolean | If true, the export action is available (default true). | | enableAutoFocus | boolean | If true, the search input is auto-focused (default true). | | enableRowCounter | boolean | If true, the row counter is displayed (default true). | | autoRender | boolean | If true, renders automatically without an explicit refresh. | | defaultColumnFilters | IColumnFilterMap | Initial column filter values. | | defaultSortColumn | string | Column that is sorted by default. | | defaultSortAsc | boolean | Default sort direction (default false). | | useFilterStateHash | boolean | If true, the filter/sort state is persisted in the URL hash. | | settingsStorageKey | string | Storage key used to persist column settings (widths/order). | | displayTimezone | "Europe/Amsterdam" \| "Asia/Jakarta" | Timezone used to display date/time values. | | checkedIndexes | number[] | Controlled list of checked row indexes. | | disabledCheckedIndexes | number[] | Row indexes whose checkbox is disabled. | | setCheckedIndexes | Dispatch<SetStateAction<number[]>> | Setter used to update the checked row indexes. | | onRowClick | (rowData, dataIndex, event) => void | Called when a row is clicked. | | onRowDoubleClick | (rowData, dataIndex, event) => void | Called when a row is double-clicked. | | onSearchEnter | (searchQuery: string) => void | Called when Enter is pressed in the search input. | | onTableDataStateChange | (newTableDataState: ITableDataState) => void | Called whenever the table data state (search/filter/sort) changes. | | onFilteredSortedDataChange | (filteredSortedData: IRenderData[] \| undefined) => void | Reactive callback invoked whenever the filtered/sorted data changes. Preferred over the imperative getFilteredSortedData ref handle. | | getRowClassName | (rowData, dataIndex, filteredSortedData) => string | Returns a custom CSS class name for a row. | | getRowSelected | (rowData, dataIndex) => boolean | Returns whether a row should be rendered as selected. | | getSearchQueryFilterResult | (rowData, searchQuery) => boolean | Custom search matcher used instead of the default search behavior. | | translate | (key, ...args) => string | Custom translation function for UI labels. | | Heading | React.ComponentType | Custom heading/list component override. | | CustomSearchInput | React.ComponentType<InputHTMLAttributes<HTMLInputElement>> | Custom component to render the search input. | | CustomElement | React.ComponentType<ICustomElementProps> | Custom element rendered with access to the current renderData. | | customElementProps | { [controlProp: string]: unknown } | Extra props passed to CustomElement. | | infiniteLoaderRef | React.RefObject<InfiniteLoader> | Ref to the underlying react-window-infinite-loader instance. | | loadMoreItems | (startIndex, stopIndex) => void \| Promise<void> | Called to load more items for infinite loading. | | itemCount | number | Total number of items, used together with loadMoreItems. |

Ref handle (ISchemaTable)

Attach a ref to access imperative methods:

| Method | Type | Description | | ---------------------- | --------------------------------------- | --------------------------------------------------------------------------------------------- | | getFilteredSortedData | () => IRenderData[] \| undefined | Returns the current filtered/sorted data. Prefer the reactive onFilteredSortedDataChange prop. | | scrollToIndex | (index: number) => void | Scrolls the table to the row at the given index. |

const tableRef = React.useRef<ISchemaTable>(null);

<SchemaTable ref={tableRef} schema={userSchema} data={users} />;

// Imperative access
tableRef.current?.scrollToIndex(5);

// Reactive access (preferred)
<SchemaTable
  schema={userSchema}
  data={users}
  onFilteredSortedDataChange={setFilteredSortedData}
/>;

Config

You can import the config type (IColumnConfig) and configure each column individually:

const config: { [keyName: string]: IColumnConfig } = {};

| Option | Type | Description | | --------------- | ----------------------------------------------------------- | -------------------------------------------------------------------- | | title | string \| React.ReactElement | Custom column header title. | | hidden | boolean | Hides the column when true. | | order | number | Controls the column order. | | width | number | Fixed column width. | | align | "start" \| "center" \| "end" | Horizontal alignment of the cell content. | | hoverTitle | string | Tooltip text shown on hover of the column header. | | dateFormat | string | Custom date format for date columns. | | timezone | "Asia/Jakarta" \| "Europe/Amsterdam" | Timezone used for this column's date/time values. | | showTimezones | false | Disables timezone display for the column. | | isSortable | boolean | Enables/disables sorting for the column. | | sortByValue | boolean | Sort using the raw value instead of the rendered string. | | defaultSortDesc | boolean | Sort descending by default when this column is first sorted. | | sort | (a, b, sortAsc) => number | Custom sort comparator for the column. | | isFilterable | boolean | Enables/disables filtering for the column. | | filter | (rowData, columnFilterValue) => boolean | Custom filter predicate for the column. | | FilterMenu | React.ComponentType<IFilterMenuComponentProps> | Custom filter menu component for the column. | | renderData | (rowData, dataIndex) => string | Returns the string value used to render the cell. | | TdBody | React.ComponentType<ITdBodyProps<T>> | Custom component used to render the cell body. | | tdBodyProps | Record<string, unknown> | Extra props passed to the TdBody component. |