@simple-table/react 3.7.4 → 3.7.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.js +1 -1
- package/dist/index.es.js +1 -1
- package/dist/types/core/src/utils/columnEditor/columnEditorUtils.d.ts +13 -0
- package/dist/types/core/src/utils/columnEditor/createColumnEditorRow.d.ts +4 -4
- package/dist/types/react/src/PortalBridge.d.ts +62 -0
- package/dist/types/react/src/__tests__/contextAndSlots.test.d.ts +1 -0
- package/dist/types/react/src/buildVanillaConfig.d.ts +2 -1
- package/dist/types/react/src/index.d.ts +2 -2
- package/dist/types/react/src/types.d.ts +7 -1
- package/dist/types/react/src/utils/ImperativeDomSlot.d.ts +23 -1
- package/dist/types/react/src/utils/wrapReactRenderer.d.ts +35 -19
- package/package.json +2 -2
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),
|
|
1
|
+
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e=require("react/jsx-runtime"),t=require("react"),n=require("simple-table-core"),r=require("react-dom/server"),s=require("react-dom");function o(e){return e&&"object"==typeof e&&"default"in e?e:{default:e}}var i=o(t);function c(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var s=0;for(r=Object.getOwnPropertySymbols(e);s<r.length;s++)t.indexOf(r[s])<0&&Object.prototype.propertyIsEnumerable.call(e,r[s])&&(n[r[s]]=e[r[s]])}return n}function u({node:n}){const r=t.useRef(null);return t.useLayoutEffect(()=>{const e=r.current;if(e)return e.appendChild(n),()=>{n.parentNode===e&&e.removeChild(n)}},[n]),e.jsx("span",{ref:r,style:{display:"contents"}})}function a(t){if(null!=t)return"string"==typeof t?t:t instanceof Node?e.jsx(u,{node:t}):void 0}function d(e){return{sortIcon:a(null==e?void 0:e.sortIcon),filterIcon:a(null==e?void 0:e.filterIcon),collapseIcon:a(null==e?void 0:e.collapseIcon),labelContent:a(null==e?void 0:e.labelContent)}}function l(t){if(null!=t){if("string"==typeof t){if(""===t)return;return e.jsx("span",{style:{display:"contents"},dangerouslySetInnerHTML:{__html:t}})}return t instanceof Node?e.jsx(u,{node:t}):void 0}}function f(t,n){return r=>{const s=document.createElement("div");return t.register(e.jsx(n,Object.assign({},r)),s),s}}function h(t,n){return r=>{const s=document.createElement("div"),o=Object.assign(Object.assign({},r),{components:(i=r.components,{expandIcon:a(i.expandIcon),checkbox:a(i.checkbox),dragIcon:a(i.dragIcon),labelContent:a(i.labelContent),pinIcon:a(i.pinIcon)})});var i;return t.register(e.jsx(n,Object.assign({},o)),s),s}}function p(t,n){return r=>{const s=document.createElement("div"),o=Object.assign(Object.assign({},r),{searchSection:r.searchSection?a(r.searchSection):null,listSection:a(r.listSection),resetSection:r.resetSection?a(r.resetSection):null});return t.register(e.jsx(n,Object.assign({},o)),s),s}}function m(t){const n=document.createElement("div");return n.innerHTML=r.renderToStaticMarkup(e.jsx(e.Fragment,{children:t})),function(e){const t=Array.from(e.childNodes).filter(e=>e.nodeType!==Node.TEXT_NODE||null!=e.textContent&&""!==e.textContent.trim());return 1===t.length&&t[0]instanceof HTMLElement?(e.removeChild(t[0]),t[0]):e}(n)}function g(t){return r.renderToStaticMarkup(e.jsx(e.Fragment,{children:t}))}function b(e){return"function"==typeof e}function j(t,n){const{cellRenderer:r,headerRenderer:s,children:o,nestedTable:i}=t,u=c(t,["cellRenderer","headerRenderer","children","nestedTable"]),a=Object.assign({},u);if(r&&(a.cellRenderer=function(t,n){return r=>{const s=document.createElement("div");return s.style.display="contents",t.register(e.jsx(n,Object.assign({},r)),s),s}}(n,r)),s&&(a.headerRenderer=function(t,n){return r=>{const s=document.createElement("div"),o=Object.assign(Object.assign({},r),{components:d(r.components)});return t.register(e.jsx(n,Object.assign({},o)),s),s}}(n,s)),o&&(a.children=o.map(e=>j(e,n))),i){const e=Object.assign(Object.assign({},i),{rows:[]});a.nestedTable=S(e,n)}return a}function S(t,n){const{defaultHeaders:r,rows:s,footerRenderer:o,emptyStateRenderer:i,errorStateRenderer:u,loadingStateRenderer:a,tableEmptyStateRenderer:S,headerDropdown:y,columnEditorConfig:O,icons:v,onColumnOrderChange:R,onColumnWidthChange:x,onHeaderEdit:E,onColumnSelect:C}=t,I=c(t,["defaultHeaders","rows","footerRenderer","emptyStateRenderer","errorStateRenderer","loadingStateRenderer","tableEmptyStateRenderer","headerDropdown","columnEditorConfig","icons","onColumnOrderChange","onColumnWidthChange","onHeaderEdit","onColumnSelect"]),w=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},I),{rows:s,defaultHeaders:r.map(e=>j(e,n))}),R?{onColumnOrderChange:e=>R(e)}:{}),x?{onColumnWidthChange:e=>x(e)}:{}),E?{onHeaderEdit:(e,t)=>E(e,t)}:{}),C?{onColumnSelect:e=>C(e)}:{});if(void 0!==o&&(w.footerRenderer=function(t,n){return r=>{const s=document.createElement("div"),o=Object.assign(Object.assign({},r),{nextIcon:l((i={nextIcon:r.nextIcon,prevIcon:r.prevIcon}).nextIcon),prevIcon:l(i.prevIcon)});var i;return t.register(e.jsx(n,Object.assign({},o)),s),s}}(n,o)),void 0!==i)if(b(i))w.emptyStateRenderer=f(n,i);else{const e=i;w.emptyStateRenderer=()=>m(e)}if(void 0!==u)if(b(u))w.errorStateRenderer=f(n,u);else{const e=u;w.errorStateRenderer=()=>m(e)}if(void 0!==a)if(b(a))w.loadingStateRenderer=f(n,a);else{const e=a;w.loadingStateRenderer=()=>m(e)}return void 0!==S&&(w.tableEmptyStateRenderer=null===S?null:m(S)),void 0!==y&&(w.headerDropdown=function(t,n){return r=>{const s=document.createElement("div"),o=Object.assign(Object.assign({},r),{components:d(r.components)});return t.register(e.jsx(n,Object.assign({},o)),s),s}}(n,y)),void 0!==O&&(w.columnEditorConfig=function(e,t){const{rowRenderer:n,customRenderer:r}=e,s=c(e,["rowRenderer","customRenderer"]);return Object.assign(Object.assign(Object.assign({},s),n?{rowRenderer:h(t,n)}:{}),r?{customRenderer:p(t,r)}:{})}(O,n)),void 0!==v&&(w.icons=function(e){const t={};for(const[n,r]of Object.entries(e))null!=r&&(t[n]="string"==typeof r||r instanceof HTMLElement||r instanceof SVGElement?r:g(r));return t}(v)),w}"function"==typeof SuppressedError&&SuppressedError;class y{constructor(){this.entries=new Map,this.listeners=new Set,this.nextId=0,this.cachedSnapshot=[],this.snapshotDirty=!0,this.emitScheduled=!1,this.pruneScheduled=!1,this.subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}),this.getSnapshot=()=>(this.snapshotDirty&&(this.cachedSnapshot=Array.from(this.entries.values()),this.snapshotDirty=!1),this.cachedSnapshot)}register(e,t){const n="st-portal-"+this.nextId++;return this.entries.set(n,{id:n,container:t,node:e}),this.scheduleEmit(),{id:n,unregister:()=>this.unregister(n)}}unregister(e){this.entries.delete(e)&&this.scheduleEmit()}attach(e){const t=new MutationObserver(()=>this.schedulePrune());return t.observe(e,{childList:!0,subtree:!0}),()=>t.disconnect()}clear(){0!==this.entries.size&&(this.entries.clear(),this.emit())}emit(){this.snapshotDirty=!0;for(const e of this.listeners)e()}scheduleEmit(){this.emitScheduled||(this.emitScheduled=!0,queueMicrotask(()=>{this.emitScheduled=!1,this.emit()}))}schedulePrune(){this.pruneScheduled||(this.pruneScheduled=!0,queueMicrotask(()=>{this.pruneScheduled=!1;let e=!1;for(const[t,n]of this.entries)n.container.isConnected||(this.entries.delete(t),e=!0);e&&this.emit()}))}}class O extends i.default.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e){console.error("[simple-table] A custom renderer threw while rendering:",e)}render(){return this.state.hasError?null:this.props.children}}const v=i.default.forwardRef(function(r,o){const i=t.useRef(null),u=t.useRef(null);null===u.current&&(u.current=new y);const a=u.current,d=t.useRef(null),l=t.useRef(void 0),f=t.useRef(null),h=r;t.useLayoutEffect(()=>{const e=i.current;if(!e)return;const t=new n.SimpleTableVanilla(e,S(h,a));t.mount(),d.current=t,f.current=h,l.current=h.defaultHeaders;const r=a.attach(e);if(o){const e=t.getAPI();"function"==typeof o?o(e):o.current=e}return()=>{r(),t.destroy(),d.current=null,l.current=void 0,f.current=null,a.clear(),o&&"function"!=typeof o&&(o.current=null)}},[]),t.useLayoutEffect(()=>{const e=d.current;if(!e)return;if(null!==f.current&&!function(e,t){const n=new Set([...Object.keys(e),...Object.keys(t)]);for(const r of n)if(e[r]!==t[r])return!0;return!1}(f.current,h))return;f.current=h;const t=S(h,a);if(l.current!==h.defaultHeaders)return l.current=h.defaultHeaders,void e.update(t);const n=c(t,["defaultHeaders"]);e.update(n)},[h]);const p=function(n){return t.useSyncExternalStore(n.subscribe,n.getSnapshot,n.getSnapshot).map(t=>s.createPortal(e.jsx(O,{children:t.node}),t.container,t.id))}(a);return e.jsxs(e.Fragment,{children:[e.jsx("div",{ref:i}),p]})});v.displayName="SimpleTable",Object.defineProperty(exports,"asRows",{enumerable:!0,get:function(){return n.asRows}}),exports.SimpleTable=v;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/index.es.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{jsx as e,Fragment as n}from"react/jsx-runtime";import r,{useRef as
|
|
1
|
+
import{jsx as e,Fragment as t,jsxs as n}from"react/jsx-runtime";import r,{useRef as o,useLayoutEffect as s,useSyncExternalStore as i}from"react";import{SimpleTableVanilla as c}from"simple-table-core";export{asRows}from"simple-table-core";import{renderToStaticMarkup as d}from"react-dom/server";import{createPortal as u}from"react-dom";function l(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n}function a({node:t}){const n=o(null);return s(()=>{const e=n.current;if(e)return e.appendChild(t),()=>{t.parentNode===e&&e.removeChild(t)}},[t]),e("span",{ref:n,style:{display:"contents"}})}function h(t){if(null!=t)return"string"==typeof t?t:t instanceof Node?e(a,{node:t}):void 0}function f(e){return{sortIcon:h(null==e?void 0:e.sortIcon),filterIcon:h(null==e?void 0:e.filterIcon),collapseIcon:h(null==e?void 0:e.collapseIcon),labelContent:h(null==e?void 0:e.labelContent)}}function m(t){if(null!=t){if("string"==typeof t){if(""===t)return;return e("span",{style:{display:"contents"},dangerouslySetInnerHTML:{__html:t}})}return t instanceof Node?e(a,{node:t}):void 0}}function p(t,n){return r=>{const o=document.createElement("div");return t.register(e(n,Object.assign({},r)),o),o}}function g(t,n){return r=>{const o=document.createElement("div"),s=Object.assign(Object.assign({},r),{components:(i=r.components,{expandIcon:h(i.expandIcon),checkbox:h(i.checkbox),dragIcon:h(i.dragIcon),labelContent:h(i.labelContent),pinIcon:h(i.pinIcon)})});var i;return t.register(e(n,Object.assign({},s)),o),o}}function b(t,n){return r=>{const o=document.createElement("div"),s=Object.assign(Object.assign({},r),{searchSection:r.searchSection?h(r.searchSection):null,listSection:h(r.listSection),resetSection:r.resetSection?h(r.resetSection):null});return t.register(e(n,Object.assign({},s)),o),o}}function S(n){const r=document.createElement("div");return r.innerHTML=d(e(t,{children:n})),function(e){const t=Array.from(e.childNodes).filter(e=>e.nodeType!==Node.TEXT_NODE||null!=e.textContent&&""!==e.textContent.trim());return 1===t.length&&t[0]instanceof HTMLElement?(e.removeChild(t[0]),t[0]):e}(r)}function O(n){return d(e(t,{children:n}))}function v(e){return"function"==typeof e}function y(t,n){const{cellRenderer:r,headerRenderer:o,children:s,nestedTable:i}=t,c=l(t,["cellRenderer","headerRenderer","children","nestedTable"]),d=Object.assign({},c);if(r&&(d.cellRenderer=function(t,n){return r=>{const o=document.createElement("div");return o.style.display="contents",t.register(e(n,Object.assign({},r)),o),o}}(n,r)),o&&(d.headerRenderer=function(t,n){return r=>{const o=document.createElement("div"),s=Object.assign(Object.assign({},r),{components:f(r.components)});return t.register(e(n,Object.assign({},s)),o),o}}(n,o)),s&&(d.children=s.map(e=>y(e,n))),i){const e=Object.assign(Object.assign({},i),{rows:[]});d.nestedTable=j(e,n)}return d}function j(t,n){const{defaultHeaders:r,rows:o,footerRenderer:s,emptyStateRenderer:i,errorStateRenderer:c,loadingStateRenderer:d,tableEmptyStateRenderer:u,headerDropdown:a,columnEditorConfig:h,icons:j,onColumnOrderChange:E,onColumnWidthChange:R,onHeaderEdit:C,onColumnSelect:I}=t,w=l(t,["defaultHeaders","rows","footerRenderer","emptyStateRenderer","errorStateRenderer","loadingStateRenderer","tableEmptyStateRenderer","headerDropdown","columnEditorConfig","icons","onColumnOrderChange","onColumnWidthChange","onHeaderEdit","onColumnSelect"]),x=Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({},w),{rows:o,defaultHeaders:r.map(e=>y(e,n))}),E?{onColumnOrderChange:e=>E(e)}:{}),R?{onColumnWidthChange:e=>R(e)}:{}),C?{onHeaderEdit:(e,t)=>C(e,t)}:{}),I?{onColumnSelect:e=>I(e)}:{});if(void 0!==s&&(x.footerRenderer=function(t,n){return r=>{const o=document.createElement("div"),s=Object.assign(Object.assign({},r),{nextIcon:m((i={nextIcon:r.nextIcon,prevIcon:r.prevIcon}).nextIcon),prevIcon:m(i.prevIcon)});var i;return t.register(e(n,Object.assign({},s)),o),o}}(n,s)),void 0!==i)if(v(i))x.emptyStateRenderer=p(n,i);else{const e=i;x.emptyStateRenderer=()=>S(e)}if(void 0!==c)if(v(c))x.errorStateRenderer=p(n,c);else{const e=c;x.errorStateRenderer=()=>S(e)}if(void 0!==d)if(v(d))x.loadingStateRenderer=p(n,d);else{const e=d;x.loadingStateRenderer=()=>S(e)}return void 0!==u&&(x.tableEmptyStateRenderer=null===u?null:S(u)),void 0!==a&&(x.headerDropdown=function(t,n){return r=>{const o=document.createElement("div"),s=Object.assign(Object.assign({},r),{components:f(r.components)});return t.register(e(n,Object.assign({},s)),o),o}}(n,a)),void 0!==h&&(x.columnEditorConfig=function(e,t){const{rowRenderer:n,customRenderer:r}=e,o=l(e,["rowRenderer","customRenderer"]);return Object.assign(Object.assign(Object.assign({},o),n?{rowRenderer:g(t,n)}:{}),r?{customRenderer:b(t,r)}:{})}(h,n)),void 0!==j&&(x.icons=function(e){const t={};for(const[n,r]of Object.entries(e))null!=r&&(t[n]="string"==typeof r||r instanceof HTMLElement||r instanceof SVGElement?r:O(r));return t}(j)),x}"function"==typeof SuppressedError&&SuppressedError;class E{constructor(){this.entries=new Map,this.listeners=new Set,this.nextId=0,this.cachedSnapshot=[],this.snapshotDirty=!0,this.emitScheduled=!1,this.pruneScheduled=!1,this.subscribe=e=>(this.listeners.add(e),()=>{this.listeners.delete(e)}),this.getSnapshot=()=>(this.snapshotDirty&&(this.cachedSnapshot=Array.from(this.entries.values()),this.snapshotDirty=!1),this.cachedSnapshot)}register(e,t){const n="st-portal-"+this.nextId++;return this.entries.set(n,{id:n,container:t,node:e}),this.scheduleEmit(),{id:n,unregister:()=>this.unregister(n)}}unregister(e){this.entries.delete(e)&&this.scheduleEmit()}attach(e){const t=new MutationObserver(()=>this.schedulePrune());return t.observe(e,{childList:!0,subtree:!0}),()=>t.disconnect()}clear(){0!==this.entries.size&&(this.entries.clear(),this.emit())}emit(){this.snapshotDirty=!0;for(const e of this.listeners)e()}scheduleEmit(){this.emitScheduled||(this.emitScheduled=!0,queueMicrotask(()=>{this.emitScheduled=!1,this.emit()}))}schedulePrune(){this.pruneScheduled||(this.pruneScheduled=!0,queueMicrotask(()=>{this.pruneScheduled=!1;let e=!1;for(const[t,n]of this.entries)n.container.isConnected||(this.entries.delete(t),e=!0);e&&this.emit()}))}}class R extends r.Component{constructor(){super(...arguments),this.state={hasError:!1}}static getDerivedStateFromError(){return{hasError:!0}}componentDidCatch(e){console.error("[simple-table] A custom renderer threw while rendering:",e)}render(){return this.state.hasError?null:this.props.children}}const C=r.forwardRef(function(r,d){const a=o(null),h=o(null);null===h.current&&(h.current=new E);const f=h.current,m=o(null),p=o(void 0),g=o(null),b=r;s(()=>{const e=a.current;if(!e)return;const t=new c(e,j(b,f));t.mount(),m.current=t,g.current=b,p.current=b.defaultHeaders;const n=f.attach(e);if(d){const e=t.getAPI();"function"==typeof d?d(e):d.current=e}return()=>{n(),t.destroy(),m.current=null,p.current=void 0,g.current=null,f.clear(),d&&"function"!=typeof d&&(d.current=null)}},[]),s(()=>{const e=m.current;if(!e)return;if(null!==g.current&&!function(e,t){const n=new Set([...Object.keys(e),...Object.keys(t)]);for(const r of n)if(e[r]!==t[r])return!0;return!1}(g.current,b))return;g.current=b;const t=j(b,f);if(p.current!==b.defaultHeaders)return p.current=b.defaultHeaders,void e.update(t);const n=l(t,["defaultHeaders"]);e.update(n)},[b]);const S=function(t){return i(t.subscribe,t.getSnapshot,t.getSnapshot).map(t=>u(e(R,{children:t.node}),t.container,t.id))}(f);return n(t,{children:[e("div",{ref:a}),S]})});C.displayName="SimpleTable";export{C as SimpleTable};
|
|
2
2
|
//# sourceMappingURL=index.es.js.map
|
|
@@ -1,7 +1,20 @@
|
|
|
1
1
|
import HeaderObject, { Accessor } from "../../types/HeaderObject";
|
|
2
2
|
import { ColumnVisibilityState } from "../../types/ColumnVisibilityTypes";
|
|
3
3
|
import { FlattenedHeader } from "../../types/FlattenedHeader";
|
|
4
|
+
import { PanelSection } from "../../types/PanelSection";
|
|
4
5
|
export type { FlattenedHeader };
|
|
6
|
+
/**
|
|
7
|
+
* Tracks which drop separator is currently highlighted during a column-editor
|
|
8
|
+
* drag. The `index` is **section-relative** (matches the per-section
|
|
9
|
+
* `visualIndex`, or `-1` for the separator above the first row), so it must be
|
|
10
|
+
* paired with the `panelSection` it belongs to. Without the section, the same
|
|
11
|
+
* index is ambiguous across the pinned-left / main / pinned-right lists and the
|
|
12
|
+
* divider renders in the wrong section.
|
|
13
|
+
*/
|
|
14
|
+
export type HoveredSeparator = {
|
|
15
|
+
panelSection: PanelSection;
|
|
16
|
+
index: number;
|
|
17
|
+
} | null;
|
|
5
18
|
export declare const findAndMarkParentsVisible: (headers: HeaderObject[], childAccessor: Accessor, visited?: Set<string>) => void;
|
|
6
19
|
export declare const areAllChildrenHidden: (children: HeaderObject[]) => boolean;
|
|
7
20
|
export declare const updateParentHeaders: (headers: HeaderObject[]) => void;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import HeaderObject from "../../types/HeaderObject";
|
|
2
2
|
import { ColumnEditorConfig } from "../../types/ColumnEditorConfig";
|
|
3
3
|
import { IconsConfig } from "../../types/IconsConfig";
|
|
4
|
-
import { FlattenedHeader } from "./columnEditorUtils";
|
|
4
|
+
import { FlattenedHeader, HoveredSeparator } from "./columnEditorUtils";
|
|
5
5
|
import { ColumnVisibilityState } from "../../types/ColumnVisibilityTypes";
|
|
6
6
|
import { PanelSection } from "../pinnedColumnUtils";
|
|
7
7
|
export interface CreateColumnEditorRowOptions {
|
|
@@ -11,17 +11,17 @@ export interface CreateColumnEditorRowOptions {
|
|
|
11
11
|
doesAnyHeaderHaveChildren: boolean;
|
|
12
12
|
draggingRow: FlattenedHeader | null;
|
|
13
13
|
getDraggingRow?: () => FlattenedHeader | null;
|
|
14
|
-
|
|
14
|
+
getHoveredSeparator?: () => HoveredSeparator;
|
|
15
15
|
expandedHeaders: Set<string>;
|
|
16
16
|
flattenedHeaders: FlattenedHeader[];
|
|
17
17
|
forceExpanded: boolean;
|
|
18
18
|
header: HeaderObject;
|
|
19
|
-
|
|
19
|
+
hoveredSeparator: HoveredSeparator;
|
|
20
20
|
panelSection?: PanelSection;
|
|
21
21
|
rowIndex: number;
|
|
22
22
|
setDraggingRow: (row: FlattenedHeader | null) => void;
|
|
23
23
|
setExpandedHeaders: (headers: Set<string>) => void;
|
|
24
|
-
|
|
24
|
+
setHoveredSeparator: (value: HoveredSeparator) => void;
|
|
25
25
|
columnEditorConfig: ColumnEditorConfig;
|
|
26
26
|
/** Resolved table icons; `icons.drag` overrides the default column-editor drag handle. */
|
|
27
27
|
icons?: IconsConfig;
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { ReactNode } from "react";
|
|
2
|
+
/**
|
|
3
|
+
* A single React subtree to render into a DOM node owned by simple-table-core.
|
|
4
|
+
*/
|
|
5
|
+
interface PortalEntry {
|
|
6
|
+
id: string;
|
|
7
|
+
container: HTMLElement;
|
|
8
|
+
node: ReactNode;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Bridges simple-table-core's imperative DOM rendering with React so that custom
|
|
12
|
+
* cell / header / footer renderers stay part of the host React tree.
|
|
13
|
+
*
|
|
14
|
+
* Instead of mounting each renderer in its own isolated `createRoot` (which can
|
|
15
|
+
* never see the host app's context providers and leaks because it is never
|
|
16
|
+
* unmounted), each renderer registers a {@link PortalEntry}. The owning
|
|
17
|
+
* `<SimpleTable>` renders one `createPortal` per entry via {@link useTablePortals},
|
|
18
|
+
* so the consumer's components are children of the host tree and inherit context,
|
|
19
|
+
* Suspense, error boundaries, etc.
|
|
20
|
+
*
|
|
21
|
+
* Cleanup is driven by the DOM: core recycles cells by clearing/replacing their
|
|
22
|
+
* content (`innerHTML = ""`), which detaches the registered container. A
|
|
23
|
+
* `MutationObserver` (see {@link attach}) prunes entries whose container is no
|
|
24
|
+
* longer connected, which unmounts the corresponding React subtree.
|
|
25
|
+
*/
|
|
26
|
+
export declare class PortalBridge {
|
|
27
|
+
private entries;
|
|
28
|
+
private listeners;
|
|
29
|
+
private nextId;
|
|
30
|
+
private cachedSnapshot;
|
|
31
|
+
private snapshotDirty;
|
|
32
|
+
private emitScheduled;
|
|
33
|
+
private pruneScheduled;
|
|
34
|
+
/**
|
|
35
|
+
* Register a React node to be rendered into `container`. The container is
|
|
36
|
+
* returned to core synchronously (matching the vanilla renderer contract); the
|
|
37
|
+
* React subtree commits on the host's next render.
|
|
38
|
+
*/
|
|
39
|
+
register(node: ReactNode, container: HTMLElement): {
|
|
40
|
+
id: string;
|
|
41
|
+
unregister: () => void;
|
|
42
|
+
};
|
|
43
|
+
private unregister;
|
|
44
|
+
/**
|
|
45
|
+
* Observe a root element and prune entries whose container has been detached by
|
|
46
|
+
* core (cell recycling). Returns a disconnect function.
|
|
47
|
+
*/
|
|
48
|
+
attach(root: HTMLElement): () => void;
|
|
49
|
+
/** Remove all entries (used on table teardown). */
|
|
50
|
+
clear(): void;
|
|
51
|
+
subscribe: (listener: () => void) => (() => void);
|
|
52
|
+
getSnapshot: () => PortalEntry[];
|
|
53
|
+
private emit;
|
|
54
|
+
private scheduleEmit;
|
|
55
|
+
private schedulePrune;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Renders one `createPortal` per registered entry. Call once from `<SimpleTable>`
|
|
59
|
+
* and include the result in its JSX so portals mount inside the host React tree.
|
|
60
|
+
*/
|
|
61
|
+
export declare function useTablePortals(bridge: PortalBridge): ReactNode;
|
|
62
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
1
|
import type { SimpleTableConfig } from "simple-table-core";
|
|
2
2
|
import type { SimpleTableReactProps } from "./types";
|
|
3
|
-
|
|
3
|
+
import type { PortalBridge } from "./PortalBridge";
|
|
4
|
+
export declare function buildVanillaConfig(config: SimpleTableReactProps, bridge: PortalBridge): SimpleTableConfig;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { default as SimpleTable } from "./SimpleTable";
|
|
2
2
|
export { asRows } from "simple-table-core";
|
|
3
|
-
export type { SimpleTableReactProps, TableInstance, ReactHeaderObject, ReactColumnEditorConfig, ReactIconsConfig, ReactIconElement, ReactCellRenderer, ReactHeaderRenderer, ReactFooterRenderer, ReactHeaderDropdown, ReactColumnEditorRowRenderer, ReactColumnEditorCustomRenderer, ReactLoadingStateRenderer, ReactErrorStateRenderer, ReactEmptyStateRenderer, HeaderRendererComponents, HeaderRendererProps, ColumnEditorRowRendererComponents, ColumnEditorRowRendererProps, FooterRendererProps, HeaderDropdownProps, } from "./types";
|
|
4
|
-
export type { Accessor, AggregationConfig, AggregationType, BoundingBox, Cell, CellChangeProps, CellClickProps, CellRenderer, CellRendererProps, CellValue, ChartOptions, ColumnEditorConfig, ColumnEditorRowRenderer, ColumnEditorCustomRenderer,
|
|
3
|
+
export type { SimpleTableReactProps, TableInstance, ReactHeaderObject, ReactColumnEditorConfig, ReactIconsConfig, ReactIconElement, ReactCellRenderer, ReactHeaderRenderer, ReactFooterRenderer, ReactHeaderDropdown, ReactColumnEditorRowRenderer, ReactColumnEditorCustomRenderer, ReactLoadingStateRenderer, ReactErrorStateRenderer, ReactEmptyStateRenderer, HeaderRendererComponents, HeaderRendererProps, ColumnEditorRowRendererComponents, ColumnEditorRowRendererProps, ColumnEditorCustomRendererProps, FooterRendererProps, HeaderDropdownProps, } from "./types";
|
|
4
|
+
export type { Accessor, AggregationConfig, AggregationType, BoundingBox, Cell, CellChangeProps, CellClickProps, CellRenderer, CellRendererProps, CellValue, ChartOptions, ColumnEditorConfig, ColumnEditorRowRenderer, ColumnEditorCustomRenderer, ColumnEditorSearchFunction, ColumnType, ColumnVisibilityState, Comparator, ComparatorProps, CustomTheme, CustomThemeProps, DragHandlerProps, EmptyStateRenderer, EmptyStateRendererProps, EnumOption, ErrorStateRenderer, ErrorStateRendererProps, ExportToCSVProps, ExportValueGetter, ExportValueProps, FilterCondition, GetRowId, GetRowIdParams, HeaderDropdown, HeaderRenderer, IconsConfig, LoadingStateRenderer, LoadingStateRendererProps, OnRowGroupExpandProps, OnSortProps, QuickFilterConfig, QuickFilterGetter, QuickFilterGetterProps, QuickFilterMode, Row, RowButtonProps, RowId, RowSelectionChangeProps, RowState, SetHeaderRenameProps, SharedTableProps, ShowWhen, SimpleTableConfig, SimpleTableProps, SortColumn, TableAPI, TableFilterState, TableHeaderProps, TableRowProps, Theme, UpdateDataProps, ValueFormatter, ValueFormatterProps, ValueGetter, ValueGetterProps, } from "simple-table-core";
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type React from "react";
|
|
2
|
-
import type { SimpleTableProps, SimpleTableConfig, HeaderObject, TableAPI, Row, CellRendererProps, HeaderRendererProps as VanillaHeaderRendererProps, FooterRendererProps as VanillaFooterRendererProps, LoadingStateRendererProps, ErrorStateRendererProps, EmptyStateRendererProps, HeaderDropdownProps as VanillaHeaderDropdownProps, ColumnEditorRowRendererProps as VanillaColumnEditorRowRendererProps, ColumnEditorCustomRendererProps, ColumnEditorConfig } from "simple-table-core";
|
|
2
|
+
import type { SimpleTableProps, SimpleTableConfig, HeaderObject, TableAPI, Row, CellRendererProps, HeaderRendererProps as VanillaHeaderRendererProps, FooterRendererProps as VanillaFooterRendererProps, LoadingStateRendererProps, ErrorStateRendererProps, EmptyStateRendererProps, HeaderDropdownProps as VanillaHeaderDropdownProps, ColumnEditorRowRendererProps as VanillaColumnEditorRowRendererProps, ColumnEditorCustomRendererProps as VanillaColumnEditorCustomRendererProps, ColumnEditorConfig } from "simple-table-core";
|
|
3
3
|
/** Passed to React `headerRenderer` / `headerDropdown`; slots are React nodes. */
|
|
4
4
|
export interface HeaderRendererComponents {
|
|
5
5
|
sortIcon?: React.ReactNode;
|
|
@@ -21,6 +21,12 @@ export interface ColumnEditorRowRendererComponents {
|
|
|
21
21
|
export type ColumnEditorRowRendererProps = Omit<VanillaColumnEditorRowRendererProps, "components"> & {
|
|
22
22
|
components: ColumnEditorRowRendererComponents;
|
|
23
23
|
};
|
|
24
|
+
/** Column editor custom-renderer slots as React nodes (core uses `HTMLElement`). */
|
|
25
|
+
export type ColumnEditorCustomRendererProps = Omit<VanillaColumnEditorCustomRendererProps, "searchSection" | "listSection" | "resetSection"> & {
|
|
26
|
+
searchSection?: React.ReactNode;
|
|
27
|
+
listSection?: React.ReactNode;
|
|
28
|
+
resetSection?: React.ReactNode;
|
|
29
|
+
};
|
|
24
30
|
export type FooterRendererProps = Omit<VanillaFooterRendererProps, "nextIcon" | "prevIcon"> & {
|
|
25
31
|
nextIcon?: React.ReactNode;
|
|
26
32
|
prevIcon?: React.ReactNode;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { ColumnEditorRowRendererComponents as VanillaColumnEditorRowComponents } from "simple-table-core";
|
|
2
|
+
import type { ColumnEditorRowRendererComponents as VanillaColumnEditorRowComponents, HeaderRendererComponents as VanillaHeaderRendererComponents } from "simple-table-core";
|
|
3
3
|
type DomSlotProps = {
|
|
4
4
|
node: Node;
|
|
5
5
|
};
|
|
@@ -13,6 +13,28 @@ export declare function ImperativeDomSlot({ node }: DomSlotProps): import("react
|
|
|
13
13
|
* Converts a core column-editor slot (string markup or a live node) into a ReactNode.
|
|
14
14
|
*/
|
|
15
15
|
export declare function domSlotToReactNode(value: string | Node | null | undefined): React.ReactNode;
|
|
16
|
+
/** Maps core header slots (live DOM icons) to React nodes for `headerRenderer` JSX. */
|
|
17
|
+
export declare function mapHeaderRendererComponentsForReact(components: VanillaHeaderRendererComponents | undefined): {
|
|
18
|
+
sortIcon?: React.ReactNode;
|
|
19
|
+
filterIcon?: React.ReactNode;
|
|
20
|
+
collapseIcon?: React.ReactNode;
|
|
21
|
+
labelContent?: React.ReactNode;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Bridges an *icon* slot into a ReactNode. Unlike {@link domSlotToReactNode}, a
|
|
25
|
+
* string is treated as HTML markup — core serializes React icons to HTML strings
|
|
26
|
+
* (via renderToStaticMarkup), so it must be rendered with dangerouslySetInnerHTML
|
|
27
|
+
* rather than as escaped text. Live DOM nodes still go through ImperativeDomSlot.
|
|
28
|
+
*/
|
|
29
|
+
export declare function iconSlotToReactNode(value: string | Node | null | undefined): React.ReactNode;
|
|
30
|
+
/** Maps core footer pagination icon slots (live DOM / HTML string) to React nodes for `footerRenderer` JSX. */
|
|
31
|
+
export declare function mapFooterIconsForReact(icons: {
|
|
32
|
+
nextIcon?: unknown;
|
|
33
|
+
prevIcon?: unknown;
|
|
34
|
+
}): {
|
|
35
|
+
nextIcon?: React.ReactNode;
|
|
36
|
+
prevIcon?: React.ReactNode;
|
|
37
|
+
};
|
|
16
38
|
/** Maps core column-editor row slots (live DOM) to React nodes for `rowRenderer` JSX. */
|
|
17
39
|
export declare function mapColumnEditorRowComponentsForReact(components: VanillaColumnEditorRowComponents): {
|
|
18
40
|
expandIcon?: React.ReactNode;
|
|
@@ -1,40 +1,56 @@
|
|
|
1
1
|
import React from "react";
|
|
2
|
-
import type { ColumnEditorCustomRendererProps as VanillaColumnEditorCustomRendererProps, ColumnEditorRowRendererProps as VanillaColumnEditorRowRendererProps } from "simple-table-core";
|
|
2
|
+
import type { ColumnEditorCustomRendererProps as VanillaColumnEditorCustomRendererProps, ColumnEditorRowRendererProps as VanillaColumnEditorRowRendererProps, HeaderRendererProps as VanillaHeaderRendererProps, HeaderDropdownProps as VanillaHeaderDropdownProps, FooterRendererProps as VanillaFooterRendererProps } from "simple-table-core";
|
|
3
|
+
import type { PortalBridge } from "../PortalBridge";
|
|
3
4
|
/**
|
|
4
5
|
* Wraps a React component into a function that returns an HTMLElement, matching
|
|
5
6
|
* the vanilla renderer contract expected by simple-table-core.
|
|
6
7
|
*
|
|
7
|
-
*
|
|
8
|
-
*
|
|
8
|
+
* The component is registered with the {@link PortalBridge} rather than mounted
|
|
9
|
+
* in its own `createRoot`, so it renders as part of the host React tree and
|
|
10
|
+
* inherits context. The returned container is filled on the host's next render.
|
|
9
11
|
*/
|
|
10
|
-
export declare function wrapReactRenderer<P extends object>(Component: React.ComponentType<P>): (props: P) => HTMLElement;
|
|
12
|
+
export declare function wrapReactRenderer<P extends object>(bridge: PortalBridge, Component: React.ComponentType<P>): (props: P) => HTMLElement;
|
|
11
13
|
/**
|
|
12
|
-
* Like {@link wrapReactRenderer}
|
|
13
|
-
*
|
|
14
|
+
* Like {@link wrapReactRenderer} but uses `display: contents` so layout is
|
|
15
|
+
* unchanged when core appends this node (no extra box vs a plain div). Used for
|
|
16
|
+
* cell renderers.
|
|
14
17
|
*/
|
|
15
|
-
export declare function
|
|
18
|
+
export declare function wrapReactRendererIntoFragment<P extends object>(bridge: PortalBridge, Component: React.ComponentType<P>): (props: P) => HTMLElement;
|
|
16
19
|
/**
|
|
17
|
-
*
|
|
18
|
-
*
|
|
20
|
+
* Like {@link wrapReactRenderer} for header renderers: core passes `components.*`
|
|
21
|
+
* (sortIcon / filterIcon / collapseIcon / labelContent) as live DOM nodes; this
|
|
22
|
+
* bridges them to React nodes so consumers can use them directly in JSX.
|
|
23
|
+
*/
|
|
24
|
+
export declare function wrapReactHeaderRenderer(bridge: PortalBridge, Component: React.ComponentType<VanillaHeaderRendererProps>): (props: VanillaHeaderRendererProps) => HTMLElement;
|
|
25
|
+
/**
|
|
26
|
+
* Like {@link wrapReactHeaderRenderer} for the header dropdown, which shares the
|
|
27
|
+
* same `components` slot shape.
|
|
28
|
+
*/
|
|
29
|
+
export declare function wrapReactHeaderDropdown(bridge: PortalBridge, Component: React.ComponentType<VanillaHeaderDropdownProps>): (props: VanillaHeaderDropdownProps) => HTMLElement;
|
|
30
|
+
/**
|
|
31
|
+
* Like {@link wrapReactRenderer} for footer renderers: bridges the `nextIcon` /
|
|
32
|
+
* `prevIcon` pagination slots (live DOM) to React nodes for JSX use.
|
|
33
|
+
*/
|
|
34
|
+
export declare function wrapReactFooterRenderer(bridge: PortalBridge, Component: React.ComponentType<VanillaFooterRendererProps>): (props: VanillaFooterRendererProps) => HTMLElement;
|
|
35
|
+
/**
|
|
36
|
+
* Like {@link wrapReactRenderer} for column editor rows: core passes `components.*`
|
|
37
|
+
* as live DOM nodes; this maps them to React nodes so consumers can use normal JSX.
|
|
19
38
|
*/
|
|
20
|
-
export declare function
|
|
39
|
+
export declare function wrapReactColumnEditorRowRenderer(bridge: PortalBridge, Component: React.ComponentType<object>): (props: VanillaColumnEditorRowRendererProps) => HTMLElement;
|
|
21
40
|
/**
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* Commit scheduling matches {@link wrapReactRenderer} (microtask + flushSync).
|
|
41
|
+
* Maps `searchSection` / `listSection` / `resetSection` HTMLElement slots for
|
|
42
|
+
* `columnEditorConfig.customRenderer` the same way as row slots.
|
|
25
43
|
*/
|
|
26
|
-
export declare function
|
|
44
|
+
export declare function wrapReactColumnEditorCustomRenderer(bridge: PortalBridge, Component: React.ComponentType<object>): (props: VanillaColumnEditorCustomRendererProps) => HTMLElement;
|
|
27
45
|
/**
|
|
28
|
-
* Renders a static ReactNode into an HTMLElement
|
|
29
|
-
* Used for props like tableEmptyStateRenderer that are
|
|
46
|
+
* Renders a static ReactNode into an HTMLElement using server-side static
|
|
47
|
+
* rendering. Used for props like tableEmptyStateRenderer that are static markup
|
|
48
|
+
* (not interactive and not called with arguments). These do not need context.
|
|
30
49
|
*/
|
|
31
50
|
export declare function wrapReactNode(node: React.ReactNode): HTMLElement;
|
|
32
51
|
/**
|
|
33
52
|
* Converts a ReactNode to an HTML string using server-side static rendering.
|
|
34
53
|
* Used for icon props where the vanilla table expects a string | HTMLElement | SVGSVGElement.
|
|
35
|
-
* Uses renderToStaticMarkup so it works synchronously from any context — including
|
|
36
|
-
* inside a useEffect — unlike createRoot alone without a follow-up commit, which
|
|
37
|
-
* can yield empty output when React defers the nested root.
|
|
38
54
|
*/
|
|
39
55
|
export declare function reactNodeToHtmlString(node: React.ReactNode): string;
|
|
40
56
|
/** Returns true if the value is a React component (function or class). */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@simple-table/react",
|
|
3
|
-
"version": "3.7.
|
|
3
|
+
"version": "3.7.5",
|
|
4
4
|
"main": "dist/cjs/index.js",
|
|
5
5
|
"module": "dist/index.es.js",
|
|
6
6
|
"types": "dist/types/react/src/index.d.ts",
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"react-dom": ">=18.0.0"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"simple-table-core": "3.7.
|
|
32
|
+
"simple-table-core": "3.7.5"
|
|
33
33
|
},
|
|
34
34
|
"devDependencies": {
|
|
35
35
|
"@rollup/plugin-alias": "^4.0.4",
|