@feltmaps/js-sdk 1.5.0-next.5 → 1.5.0-next.7

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/client.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";var g=Object.defineProperty;var F=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var b=Object.prototype.hasOwnProperty;var I=(e,n)=>{for(var r in n)g(e,r,{get:n[r],enumerable:!0})},x=(e,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let l of S(n))!b.call(e,l)&&l!==r&&g(e,l,{get:()=>n[l],enumerable:!(s=F(n,l))||s.enumerable});return e};var f=e=>x(g({},"__esModule",{value:!0}),e);var K={};I(K,{Felt:()=>M});module.exports=f(K);function o(e,n){return r=>{let s=new MessageChannel,l=r.handler,i="options"in r?r.options:void 0,a=crypto.randomUUID();return e.postMessage({type:"felt.addListener",event:i?{eventName:n,id:a,options:i}:{eventName:n,id:a}},"*",[s.port2]),s.port1.onmessage=d=>{l(d.data)},()=>{s.port1.onmessage=null,s.port1.close(),s.port2.close(),e.postMessage({type:"felt.removeListener",id:a},"*")}}}function t(e,n){return r=>{let s=new MessageChannel;return e.postMessage({type:n,params:r},"*",[s.port2]),new Promise((l,i)=>{s.port1.onmessage=a=>{a.data&&typeof a.data=="object"&&"__error__"in a.data?i(new Error(a.data.__error__)):l(a.data),s.port1.close(),s.port2.close()}})}}var u=e=>({getElement:t(e,"getElement"),getElementGeometry:t(e,"getElementGeometry"),getElements:t(e,"getElements"),setElementGroupVisibility:t(e,"setElementGroupVisibility"),getElementGroup:t(e,"getElementGroup"),getElementGroups:t(e,"getElementGroups"),onElementChange:o(e,"onElementChange"),onElementCreate:o(e,"onElementCreate"),onElementDelete:o(e,"onElementDelete"),onElementGroupChange:o(e,"onElementGroupChange"),createElement:t(e,"createElement"),updateElement:t(e,"updateElement"),deleteElement:t(e,"deleteElement")});var C=e=>({onPointerClick:o(e,"onPointerClick"),onPointerMove:o(e,"onPointerMove")});var h=e=>({getLayer:t(e,"getLayer"),getLayers:t(e,"getLayers"),setLayerVisibility:t(e,"setLayerVisibility"),setLayerStyle:t(e,"setLayerStyle"),setLayerLegendVisibility:t(e,"setLayerLegendVisibility"),onLayerChange:o(e,"onLayerChange"),getLayerGroup:t(e,"getLayerGroup"),getLayerGroups:t(e,"getLayerGroups"),setLayerGroupVisibility:t(e,"setLayerGroupVisibility"),setLayerGroupLegendVisibility:t(e,"setLayerGroupLegendVisibility"),onLayerGroupChange:o(e,"onLayerGroupChange"),getLegendItem:t(e,"getLegendItem"),getLegendItems:t(e,"getLegendItems"),setLegendItemVisibility:t(e,"setLegendItemVisibility"),onLegendItemChange:o(e,"onLegendItemChange"),getLayerFilters:t(e,"getLayerFilters"),setLayerFilters:t(e,"setLayerFilters"),getRenderedFeatures:t(e,"getRenderedFeatures")});var L=e=>({getMapDetails:t(e,"getMapDetails")});var T=e=>({onSelectionChange:o(e,"onSelectionChange"),getSelection:t(e,"getSelection"),selectFeature:t(e,"selectFeature"),clearSelection:t(e,"clearSelection")});var E=e=>({setTool:t(e,"setTool"),getTool:t(e,"getTool"),onToolChange:o(e,"onToolChange"),setToolSettings:t(e,"setToolSettings"),getToolSettings:t(e,"getToolSettings"),onToolSettingsChange:o(e,"onToolSettingsChange")});var v=e=>({updateUiControls:t(e,"updateUiControls"),setOnMapInteractionsUi:t(e,"setOnMapInteractionsUi")});var P=e=>({getViewport:t(e,"getViewport"),setViewport:t(e,"setViewport"),getViewportConstraints:t(e,"getViewportConstraints"),setViewportConstraints:t(e,"setViewportConstraints"),fitViewportToBounds:t(e,"fitViewportToBounds"),onViewportMove:o(e,"onViewportMove"),onViewportMoveEnd:o(e,"onViewportMoveEnd"),onMapIdle:o(e,"onMapIdle")});function V(e){return{iframe:null,...P(e),...v(e),...h(e),...u(e),...T(e),...C(e),...E(e),...L(e)}}var M={embed(e,n,r){let s={uiControls:{showLegend:!0,cooperativeGestures:!0,fullScreenButton:!0,geolocation:!1,zoomControls:!0,scaleBar:!0},initialViewport:void 0,origin:"https://felt.com"},l=r?.origin??s.origin,i=new URL(`${l}/embed/map/${n}`),a={showLegend:"legend",cooperativeGestures:"cooperativeGestures",fullScreenButton:"link",geolocation:"geolocation",zoomControls:"zoomControls",scaleBar:"scaleBar"},d={...s.uiControls,...r?.uiControls};for(let[m,y]of G(d))y!=null&&i.searchParams.set(a[m],y?"1":"0");if(r?.token&&i.searchParams.set("token",r.token),r?.initialViewport){let m=r.initialViewport;i.searchParams.set("loc",`${m.center.latitude},${m.center.longitude},${m.zoom}z`)}let c=e.tagName==="IFRAME",p=c?e:e.ownerDocument.createElement("iframe");return p.src=i.toString(),c||(p.style.width="100%",p.style.height="100%",p.style.border="none",p.style.margin="0",e.appendChild(p)),p.referrerPolicy="strict-origin-when-cross-origin",new Promise((m,y)=>{p.addEventListener("load",()=>{p.contentWindow==null?y(new Error("Failed to load Felt map")):m(p.contentWindow)},{once:!0})}).then(M.connect).then(m=>(Object.defineProperties(m,{iframe:{value:p,writable:!1,configurable:!1}}),m))},connect(e){let n=V(e);return new Promise((r,s)=>{let l=setTimeout(()=>{s(new Error("Failed to load Felt map")),clearInterval(a)},5e3),i=new MessageChannel,a=setInterval(()=>{e.postMessage({type:"felt.ready"},"*",[i.port2])},100);i.port1.onmessage=d=>{d.data===!0&&(clearInterval(a),clearTimeout(l),i.port1.close(),i.port2.close(),r(n))}})}},G=Object.entries;0&&(module.exports={Felt});
1
+ "use strict";var g=Object.defineProperty;var b=Object.getOwnPropertyDescriptor;var S=Object.getOwnPropertyNames;var F=Object.prototype.hasOwnProperty;var G=(e,n)=>{for(var r in n)g(e,r,{get:n[r],enumerable:!0})},I=(e,n,r,s)=>{if(n&&typeof n=="object"||typeof n=="function")for(let l of S(n))!F.call(e,l)&&l!==r&&g(e,l,{get:()=>n[l],enumerable:!(s=b(n,l))||s.enumerable});return e};var x=e=>I(g({},"__esModule",{value:!0}),e);var K={};G(K,{Felt:()=>M});module.exports=x(K);function o(e,n){return r=>{let s=new MessageChannel,l=r.handler,a="options"in r?r.options:void 0,i=crypto.randomUUID();return e.postMessage({type:"felt.addListener",event:a?{eventName:n,id:i,options:a}:{eventName:n,id:i}},"*",[s.port2]),s.port1.onmessage=d=>{l(d.data)},()=>{s.port1.onmessage=null,s.port1.close(),s.port2.close(),e.postMessage({type:"felt.removeListener",id:i},"*")}}}function t(e,n){return r=>{let s=new MessageChannel;return e.postMessage({type:n,params:r},"*",[s.port2]),new Promise((l,a)=>{s.port1.onmessage=i=>{i.data&&typeof i.data=="object"&&"__error__"in i.data?a(new Error(i.data.__error__)):l(i.data),s.port1.close(),s.port2.close()}})}}var u=e=>({getElement:t(e,"getElement"),getElementGeometry:t(e,"getElementGeometry"),getElements:t(e,"getElements"),setElementGroupVisibility:t(e,"setElementGroupVisibility"),getElementGroup:t(e,"getElementGroup"),getElementGroups:t(e,"getElementGroups"),onElementChange:o(e,"onElementChange"),onElementCreate:o(e,"onElementCreate"),onElementCreateEnd:o(e,"onElementCreateEnd"),onElementDelete:o(e,"onElementDelete"),onElementGroupChange:o(e,"onElementGroupChange"),createElement:t(e,"createElement"),updateElement:t(e,"updateElement"),deleteElement:t(e,"deleteElement")});var C=e=>({onPointerClick:o(e,"onPointerClick"),onPointerMove:o(e,"onPointerMove")});var h=e=>({getLayer:t(e,"getLayer"),getLayers:t(e,"getLayers"),setLayerVisibility:t(e,"setLayerVisibility"),setLayerStyle:t(e,"setLayerStyle"),setLayerLegendVisibility:t(e,"setLayerLegendVisibility"),onLayerChange:o(e,"onLayerChange"),getLayerGroup:t(e,"getLayerGroup"),getLayerGroups:t(e,"getLayerGroups"),setLayerGroupVisibility:t(e,"setLayerGroupVisibility"),setLayerGroupLegendVisibility:t(e,"setLayerGroupLegendVisibility"),onLayerGroupChange:o(e,"onLayerGroupChange"),getLegendItem:t(e,"getLegendItem"),getLegendItems:t(e,"getLegendItems"),setLegendItemVisibility:t(e,"setLegendItemVisibility"),onLegendItemChange:o(e,"onLegendItemChange"),getLayerFilters:t(e,"getLayerFilters"),setLayerFilters:t(e,"setLayerFilters"),getRenderedFeatures:t(e,"getRenderedFeatures"),getCategoryData:t(e,"getCategoryData"),getHistogramData:t(e,"getHistogramData"),getAggregates:t(e,"getAggregates")});var L=e=>({getMapDetails:t(e,"getMapDetails")});var T=e=>({onSelectionChange:o(e,"onSelectionChange"),getSelection:t(e,"getSelection"),selectFeature:t(e,"selectFeature"),clearSelection:t(e,"clearSelection")});var E=e=>({setTool:t(e,"setTool"),getTool:t(e,"getTool"),onToolChange:o(e,"onToolChange"),setToolSettings:t(e,"setToolSettings"),getToolSettings:t(e,"getToolSettings"),onToolSettingsChange:o(e,"onToolSettingsChange")});var v=e=>({updateUiControls:t(e,"updateUiControls"),setOnMapInteractionsUi:t(e,"setOnMapInteractionsUi"),showLayerDataTable:t(e,"showLayerDataTable"),hideLayerDataTable:t(e,"hideLayerDataTable")});var P=e=>({getViewport:t(e,"getViewport"),setViewport:t(e,"setViewport"),getViewportConstraints:t(e,"getViewportConstraints"),setViewportConstraints:t(e,"setViewportConstraints"),fitViewportToBounds:t(e,"fitViewportToBounds"),onViewportMove:o(e,"onViewportMove"),onViewportMoveEnd:o(e,"onViewportMoveEnd"),onMapIdle:o(e,"onMapIdle")});function V(e){return{iframe:null,...P(e),...v(e),...h(e),...u(e),...T(e),...C(e),...E(e),...L(e)}}var M={embed(e,n,r){let s={uiControls:{showLegend:!0,cooperativeGestures:!0,fullScreenButton:!0,geolocation:!1,zoomControls:!0,scaleBar:!0},initialViewport:void 0,origin:"https://felt.com"},l=r?.origin??s.origin,a=new URL(`${l}/embed/map/${n}`),i={showLegend:"legend",cooperativeGestures:"cooperativeGestures",fullScreenButton:"link",geolocation:"geolocation",zoomControls:"zoomControls",scaleBar:"scaleBar"},d={...s.uiControls,...r?.uiControls};for(let[p,y]of f(d))y!=null&&a.searchParams.set(i[p],y?"1":"0");if(r?.token&&a.searchParams.set("token",r.token),r?.initialViewport){let p=r.initialViewport;a.searchParams.set("loc",`${p.center.latitude},${p.center.longitude},${p.zoom}z`)}let c=e.tagName==="IFRAME",m=c?e:e.ownerDocument.createElement("iframe");return m.src=a.toString(),c||(m.style.width="100%",m.style.height="100%",m.style.border="none",m.style.margin="0",e.appendChild(m)),m.referrerPolicy="strict-origin-when-cross-origin",new Promise((p,y)=>{m.addEventListener("load",()=>{m.contentWindow==null?y(new Error("Failed to load Felt map")):p(m.contentWindow)},{once:!0})}).then(M.connect).then(p=>(Object.defineProperties(p,{iframe:{value:m,writable:!1,configurable:!1}}),p))},connect(e){let n=V(e);return new Promise((r,s)=>{let l=setTimeout(()=>{s(new Error("Failed to load Felt map")),clearInterval(i)},5e3),a=new MessageChannel,i=setInterval(()=>{e.postMessage({type:"felt.ready"},"*",[a.port2])},100);a.port1.onmessage=d=>{d.data===!0&&(clearInterval(i),clearTimeout(l),a.port1.close(),a.port2.close(),r(n))}})}},f=Object.entries;0&&(module.exports={Felt});
package/dist/client.d.cts CHANGED
@@ -1,5 +1,5 @@
1
- import { E as Element, G as Geometry, a as GetElementsConstraint, b as ElementGroup, c as GetElementGroupsConstraint, S as SetVisibilityRequest, d as ElementChangeCallbackParams, e as ElementGroupChangeCallbackParams, f as ElementCreate, g as ElementUpdate, L as Layer, h as GetLayersConstraint, i as LayerChangeCallbackParams, j as LayerGroup, k as GetLayerGroupsConstraint, l as LayerGroupChangeCallbackParams, m as LegendItemIdentifier, n as LegendItem, o as LegendItemsConstraint, p as LegendItemChangeCallbackParams, q as LayerFilters, F as Filters, r as GetRenderedFeaturesConstraint, s as Feature, M as MapInteractionEvent, t as MapDetails, u as EntityNode, v as FeatureSelection, T as ToolType, I as InputToolSettings, C as ConfigurableToolType, w as ToolSettingsMap, x as ToolSettingsChangeEvent, z as zInfer, V as ViewportState, y as SetViewportCenterZoomParams, A as ViewportConstraints, B as ViewportFitBoundsParams, D as ViewportCenterZoom } from './types-BKxKmuZn.cjs';
2
- export { H as CircleElementCreate, J as CircleElementRead, K as CircleElementUpdate, aw as CircleToolSettings, ai as ElementGroupNode, aj as ElementNode, ak as FeatureNode, an as FeltBoundary, ao as FeltZoom, af as FilterExpression, ag as FilterLogicGate, ah as FilterTernary, N as HighlighterElementCreate, O as HighlighterElementRead, P as HighlighterElementUpdate, ax as HighlighterToolSettings, Q as ImageElementCreate, R as ImageElementRead, U as ImageElementUpdate, ap as LatLng, al as LayerGroupNode, am as LayerNode, ad as LayerProcessingStatus, aq as LineStringGeometry, ay as LineToolSettings, W as LinkElementRead, ar as LngLatTuple, X as MarkerElementCreate, Y as MarkerElementRead, Z as MarkerElementUpdate, az as MarkerToolSettings, as as MultiLineStringGeometry, at as MultiPolygonGeometry, _ as NoteElementCreate, $ as NoteElementRead, a0 as NoteElementUpdate, aA as NoteToolSettings, a1 as PathElementCreate, a2 as PathElementRead, a3 as PathElementUpdate, aB as PinToolSettings, a4 as PlaceElementCreate, a5 as PlaceElementRead, a6 as PlaceElementUpdate, aC as PlaceFrame, aD as PlaceSymbol, au as PointGeometry, a7 as PolygonElementCreate, a8 as PolygonElementRead, a9 as PolygonElementUpdate, av as PolygonGeometry, aE as PolygonToolSettings, ae as RasterValue, aF as RouteToolSettings, aa as TextElementCreate, ab as TextElementRead, ac as TextElementUpdate, aG as TextToolSettings } from './types-BKxKmuZn.cjs';
1
+ import { E as Element, G as Geometry, a as GetElementsConstraint, b as ElementGroup, c as GetElementGroupsConstraint, S as SetVisibilityRequest, d as ElementChangeCallbackParams, e as ElementGroupChangeCallbackParams, f as ElementCreate, g as ElementUpdate, L as Layer, h as GetLayersConstraint, i as LayerChangeCallbackParams, j as LayerGroup, k as GetLayerGroupsConstraint, l as LayerGroupChangeCallbackParams, m as LegendItemIdentifier, n as LegendItem, o as LegendItemsConstraint, p as LegendItemChangeCallbackParams, q as LayerFilters, F as Filters, r as GetRenderedFeaturesConstraint, s as Feature, t as GetLayerCategoriesParams, u as GetLayerCategoriesGroup, v as GetLayerHistogramParams, w as GetLayerHistogramBin, A as AggregationMethod, x as GetLayerCalculationParams, M as MapInteractionEvent, y as MapDetails, z as EntityNode, B as FeatureSelection, T as ToolType, I as InputToolSettings, C as ConfigurableToolType, D as ToolSettingsMap, H as ToolSettingsChangeEvent, J as zInfer, K as SortConfig, V as ViewportState, N as SetViewportCenterZoomParams, O as ViewportConstraints, P as ViewportFitBoundsParams, Q as ViewportCenterZoom } from './types-XLCA2cX-.cjs';
2
+ export { ap as AggregationConfig, R as CircleElementCreate, U as CircleElementRead, W as CircleElementUpdate, aH as CircleToolSettings, as as ElementGroupNode, at as ElementNode, au as FeatureNode, ax as FeltBoundary, ay as FeltZoom, am as FilterExpression, an as FilterLogicGate, ao as FilterTernary, X as HighlighterElementCreate, Y as HighlighterElementRead, Z as HighlighterElementUpdate, aI as HighlighterToolSettings, _ as ImageElementCreate, $ as ImageElementRead, a0 as ImageElementUpdate, az as LatLng, av as LayerGroupNode, aw as LayerNode, ak as LayerProcessingStatus, aA as LineStringGeometry, aJ as LineToolSettings, a1 as LinkElementRead, aB as LngLatTuple, a2 as MarkerElementCreate, a3 as MarkerElementRead, a4 as MarkerElementUpdate, aK as MarkerToolSettings, aq as MultiAggregationConfig, aC as MultiLineStringGeometry, aD as MultiPolygonGeometry, a5 as NoteElementCreate, a6 as NoteElementRead, a7 as NoteElementUpdate, aL as NoteToolSettings, a8 as PathElementCreate, a9 as PathElementRead, aa as PathElementUpdate, aM as PinToolSettings, ab as PlaceElementCreate, ac as PlaceElementRead, ad as PlaceElementUpdate, aN as PlaceFrame, aO as PlaceSymbol, aE as PointGeometry, ae as PolygonElementCreate, af as PolygonElementRead, ag as PolygonElementUpdate, aF as PolygonGeometry, aP as PolygonToolSettings, al as RasterValue, aQ as RouteToolSettings, aG as SortDirection, ah as TextElementCreate, ai as TextElementRead, aj as TextElementUpdate, aR as TextToolSettings, ar as ValueConfiguration } from './types-XLCA2cX-.cjs';
3
3
  import { z } from 'zod';
4
4
 
5
5
  /**
@@ -62,7 +62,7 @@ interface ElementsController {
62
62
  *
63
63
  * @example
64
64
  * ```typescript
65
- * felt.getElementGroup("element-group-1");
65
+ * const elementGroup = await felt.getElementGroup("element-group-1");
66
66
  * ```
67
67
  * @returns The requested element group.
68
68
  */
@@ -111,13 +111,67 @@ interface ElementsController {
111
111
  /**
112
112
  * The handler that is called when an element is created.
113
113
  *
114
+ * This will fire when elements are created programatically, or when the
115
+ * user starts creating an element with a drawing tool.
116
+ *
117
+ * When the user creates an element with a drawing tool, it can begin in
118
+ * an invalid state, such as if you've just placed a single point in a polygon.
119
+ *
120
+ * You can use the `isBeingCreated` property to determine if the element is
121
+ * still being created by a drawing tool.
122
+ *
123
+ * If you want to know when the element is finished being created, you can
124
+ * use the `onToolCreateElementEnd` listener.
125
+ *
114
126
  * @param change - An object describing the change that occurred.
115
127
  */
116
128
  handler: (change: ElementChangeCallbackParams) => void;
117
129
  }): VoidFunction;
130
+ /**
131
+ * Listens for when a new element is finished being created by a drawing tool.
132
+ *
133
+ * This differs from the `onElementCreate` listener, which fires whenever an
134
+ * element is first created. This fires when the user finishes creating an element
135
+ * which could be after a series of interactions.
136
+ *
137
+ * For example, when creating a polygon, the user places a series of points then
138
+ * finishes by pressing Enter or Escape. Or when creating a Place element, they
139
+ * add the marker, type a label, then finally deselect the element.
140
+ *
141
+ * @returns A function to unsubscribe from the listener
142
+ *
143
+ * @example
144
+ * ```typescript
145
+ * const unsubscribe = felt.onToolCreatedElement({
146
+ * handler: (params) => console.log(params),
147
+ * });
148
+ *
149
+ * // later on...
150
+ * unsubscribe();
151
+ * ```
152
+ */
153
+ onElementCreateEnd(args: {
154
+ /**
155
+ * The handler to call whenever this event fires.
156
+ *
157
+ * @param params - An object containing the element that was created.
158
+ */
159
+ handler: (params: {
160
+ element: Element;
161
+ }) => void;
162
+ }): VoidFunction;
118
163
  /**
119
164
  * Adds a listener for when an element changes.
120
165
  *
166
+ * This will fire when an element is being edited, either on the map by the user
167
+ * or programatically.
168
+ *
169
+ * Like the `onElementCreate` listener, this will fire when an element is
170
+ * still being created by a drawing tool.
171
+ *
172
+ * You can check the `isBeingCreated` property to determine if the element is
173
+ * still being created by a drawing tool.
174
+ *
121
175
  * @returns A function to unsubscribe from the listener
122
176
  *
123
177
  * @event
@@ -235,7 +289,7 @@ interface LayersController {
235
289
  *
236
290
  * @example
237
291
  * ```typescript
238
- * const layers = await felt.getLayer({ ids: ["layer-1", "layer-2"] });
292
+ * const layer = await felt.getLayer("layer-1");
239
293
  * ```
240
294
  * @returns The requested layer.
241
295
  */
@@ -356,7 +410,7 @@ interface LayersController {
356
410
  *
357
411
  * @example
358
412
  * ```typescript
359
- * felt.getLayerGroup("layer-group-1");
413
+ * const layerGroup = await felt.getLayerGroup("layer-group-1");
360
414
  * ```
361
415
  * @returns The requested layer group.
362
416
  */
@@ -537,6 +591,157 @@ interface LayersController {
537
591
  * The constraints to apply to the features returned from the map.
538
592
  */
539
593
  params?: GetRenderedFeaturesConstraint): Promise<Array<Feature>>;
594
+ /**
595
+ * Gets values from a layer grouped by a given attribute.
596
+ *
597
+ * @remarks
598
+ * Groups features in your layer by unique values in the specified attribute and calculates
599
+ * a value for each group. By default, this value is the count of features in each group.
600
+ *
601
+ * You can apply filters in two ways:
602
+ * 1. At the top level (using `boundary` and `filters`), which affects both what categories
603
+ * are included and how values are calculated
604
+ * 2. In the `values` configuration, which only affects the values but keeps all categories
605
+ *
606
+ * This two-level filtering is particularly useful when you want to compare subsets of data
607
+ * while maintaining consistent categories. For example, you might want to show the distribution
608
+ * of all building types in a city, but only count buildings built after 2000 in each category.
609
+ *
610
+ * @example
611
+ * ```typescript
612
+ * // Basic grouping: Count of buildings by type
613
+ * const buildingsByType = await felt.getCategoryData({
614
+ * layerId: "buildings",
615
+ * attribute: "type"
616
+ * });
617
+ *
618
+ * // Filtered grouping: Only count buildings in downtown
619
+ * const downtownBuildingsByType = await felt.getCategoryData({
620
+ * layerId: "buildings",
621
+ * attribute: "type",
622
+ * boundary: [-122.43, 47.60, -122.33, 47.62] // downtown boundary
623
+ * });
624
+ *
625
+ * // Advanced: Show all building types, but only sum floor area of recent buildings
626
+ * const recentBuildingAreaByType = await felt.getCategoryData({
627
+ * layerId: "buildings",
628
+ * attribute: "type",
629
+ * values: {
630
+ * filters: ["year_built", "gte", 2000],
631
+ * aggregation: {
632
+ * method: "sum",
633
+ * attribute: "floor_area"
634
+ * }
635
+ * }
636
+ * });
637
+ *
638
+ * // Compare residential density across neighborhoods while only counting recent buildings
639
+ * const newBuildingDensityByNeighborhood = await felt.getCategoryData({
640
+ * layerId: "buildings",
641
+ * attribute: "neighborhood",
642
+ * values: {
643
+ * filters: ["year_built", "gte", 2000],
644
+ * aggregation: {
645
+ * method: "avg",
646
+ * attribute: "units_per_acre"
647
+ * }
648
+ * }
649
+ * });
650
+ * ```
651
+ */
652
+ getCategoryData(params: GetLayerCategoriesParams): Promise<Array<GetLayerCategoriesGroup>>;
653
+ /**
654
+ * Gets a histogram of values from a layer for a given attribute.
655
+ *
656
+ * @remarks
657
+ * Creates bins (ranges) for numeric data and counts how many features fall into each bin,
658
+ * or returns aggregated values for each bin.
659
+ *
660
+ * You can control how the bins are created using the `steps` parameter, choosing from
661
+ * several methods like equal intervals, quantiles, or natural breaks (Jenks), or passing
662
+ * in the step values directly if you know how you want to bin the data.
663
+ *
664
+ * Like getCategoryData, you can apply filters in two ways:
665
+ * 1. At the top level (using `boundary` and `filters`), which affects both how the bins
666
+ * are calculated and what features are counted in each bin
667
+ * 2. In the `values` configuration, which only affects what gets counted but keeps the
668
+ * bin ranges the same
669
+ *
670
+ * This is particularly useful when you want to compare distributions while keeping
671
+ * consistent bin ranges. For example, you might want to compare the distribution of
672
+ * building heights in different years while using the same height ranges.
673
+ *
674
+ * @example
675
+ * ```typescript
676
+ * // Basic histogram: Building heights in 5 natural break bins
677
+ * const buildingHeights = await felt.getHistogramData({
678
+ * layerId: "buildings",
679
+ * attribute: "height",
680
+ * steps: { type: "jenks", count: 5 }
681
+ * });
682
+ *
683
+ * // Compare old vs new buildings using the same height ranges
684
+ * const oldBuildingHeights = await felt.getHistogramData({
685
+ * layerId: "buildings",
686
+ * attribute: "height",
687
+ * steps: [0, 20, 50, 100, 200, 500],
688
+ * values: {
689
+ * filters: ["year_built", "lt", 1950]
690
+ * }
691
+ * });
692
+ *
693
+ * const newBuildingHeights = await felt.getHistogramData({
694
+ * layerId: "buildings",
695
+ * attribute: "height",
696
+ * steps: [0, 20, 50, 100, 200, 500], // Same ranges as above
697
+ * values: {
698
+ * filters: ["year_built", "gte", 1950]
699
+ * }
700
+ * });
701
+ * ```
702
+ */
703
+ getHistogramData(params: GetLayerHistogramParams): Promise<Array<GetLayerHistogramBin>>;
704
+ /**
705
+ * Calculates a single aggregate value for a layer based on the provided configuration.
706
+ *
707
+ * @remarks
708
+ * Performs statistical calculations on your data, like counting features or computing
709
+ * averages, sums, etc. You can focus your calculation on specific areas or subsets
710
+ * of your data using boundaries and filters.
711
+ *
712
+ * When no aggregation is specified, it counts features. When an aggregation is provided,
713
+ * it performs that calculation (average, sum, etc.) on the specified attribute.
714
+ *
715
+ * @example
716
+ * ```typescript
717
+ * // Count all residential buildings
718
+ * const residentialCount = await felt.getAggregates({
719
+ * layerId: "buildings",
720
+ * filters: ["type", "eq", "residential"]
721
+ * });
722
+ *
723
+ * // Calculate average home value in a specific neighborhood
724
+ * const avgHomeValue = await felt.getAggregates({
725
+ * layerId: "buildings",
726
+ * boundary: [-122.43, 47.60, -122.33, 47.62], // neighborhood boundary
727
+ * aggregation: {
728
+ * method: "avg",
729
+ * attribute: "assessed_value"
730
+ * }
731
+ * });
732
+ *
733
+ * // Find the maximum building height for buildings built after 2000
734
+ * const maxNewBuildingHeight = await felt.getAggregates({
735
+ * layerId: "buildings",
736
+ * filters: ["year_built", "gte", 2000],
737
+ * aggregation: {
738
+ * method: "max",
739
+ * attribute: "height"
740
+ * }
741
+ * });
742
+ * ```
743
+ */
744
+ getAggregates<T extends AggregationMethod | "count">(params: GetLayerCalculationParams<T>): Promise<Record<T, number | null>>;
540
745
  }
541
746
 
542
747
  /**
@@ -718,7 +923,7 @@ interface ToolsController {
718
923
  * @param tool - The tool to set.
719
924
  *
720
925
  * @example
721
- * ```ts
926
+ * ```typescript
722
927
  * // Set the tool to "marker"
723
928
  * felt.setTool("marker");
724
929
  *
@@ -733,7 +938,7 @@ interface ToolsController {
733
938
  * @returns The current tool, or `null` if no tool is in use.
734
939
  *
735
940
  * @example
736
- * ```ts
941
+ * ```typescript
737
942
  * const tool = await felt.getTool(); // "marker", "polygon", etc.
738
943
  * ```
739
944
  */
@@ -744,7 +949,7 @@ interface ToolsController {
744
949
  * @returns A function to unsubscribe from the listener
745
950
  *
746
951
  * @example
747
- * ```ts
952
+ * ```typescript
748
953
  * const unsubscribe = felt.onToolChange({
749
954
  * handler: tool => console.log(tool),
750
955
  * });
@@ -922,8 +1127,10 @@ declare const UiOnMapInteractionsOptionsSchema: z.ZodObject<{
922
1127
  }>;
923
1128
 
924
1129
  /**
925
- * The UI controller allows you to enable and disable UI controls on the
926
- * embedded map.
1130
+ * The UI controller allows you to control various aspects of the Felt UI in your embedded map.
1131
+ *
1132
+ * This includes enabling/disabling UI controls, managing on-map interactions, and controlling
1133
+ * the visibility of UI components like the data table.
927
1134
  *
928
1135
  * @group Controller
929
1136
  * @public
@@ -947,6 +1154,42 @@ interface UiController {
947
1154
  * will still be selected when clicked.
948
1155
  */
949
1156
  setOnMapInteractionsUi(options: UiOnMapInteractionsOptions): void;
1157
+ /**
1158
+ * Shows a data table view for the specified layer, optionally sorted by a given attribute.
1159
+ *
1160
+ * @example
1161
+ * ```typescript
1162
+ * // Show data table with default sorting
1163
+ * await felt.showLayerDataTable({
1164
+ * layerId: "layer-1",
1165
+ * });
1166
+ *
1167
+ * // Show data table sorted by height in descending order
1168
+ * await felt.showLayerDataTable({
1169
+ * layerId: "layer-1",
1170
+ * sorting: {
1171
+ * attribute: "height",
1172
+ * direction: "desc",
1173
+ * },
1174
+ * });
1175
+ *
1176
+ * // Show the data table pane with no table visible
1177
+ * await felt.showLayerDataTable();
1178
+ * ```
1179
+ */
1180
+ showLayerDataTable(params?: {
1181
+ layerId: string;
1182
+ sorting?: SortConfig;
1183
+ }): Promise<void>;
1184
+ /**
1185
+ * Hides the data table.
1186
+ *
1187
+ * @example
1188
+ * ```typescript
1189
+ * await felt.hideLayerDataTable();
1190
+ * ```
1191
+ */
1192
+ hideLayerDataTable(): Promise<void>;
950
1193
  }
951
1194
 
952
1195
  /**
@@ -1277,4 +1520,4 @@ declare const Felt: {
1277
1520
  connect(feltWindow: Window): Promise<FeltController>;
1278
1521
  };
1279
1522
 
1280
- export { ConfigurableToolType, Element, ElementChangeCallbackParams, ElementCreate, ElementGroup, ElementGroupChangeCallbackParams, ElementUpdate, type ElementsController, EntityNode, Feature, FeatureSelection, Felt, type FeltController, type FeltEmbedOptions, Filters, Geometry, GetElementGroupsConstraint, GetElementsConstraint, GetLayerGroupsConstraint, GetLayersConstraint, GetRenderedFeaturesConstraint, InputToolSettings, type InteractionsController, Layer, LayerChangeCallbackParams, LayerFilters, LayerGroup, LayerGroupChangeCallbackParams, type LayersController, LegendItem, LegendItemChangeCallbackParams, LegendItemIdentifier, LegendItemsConstraint, MapDetails, MapInteractionEvent, type MiscController, type UiOnMapInteractionsOptions as OnMapInteractionsOptions, type SelectionController, SetViewportCenterZoomParams, SetVisibilityRequest, ToolSettingsChangeEvent, ToolSettingsMap, ToolType, type ToolsController, type UiController, type UiControlsOptions, ViewportCenterZoom, ViewportConstraints, type ViewportController, ViewportFitBoundsParams, ViewportState };
1523
+ export { AggregationMethod, ConfigurableToolType, Element, ElementChangeCallbackParams, ElementCreate, ElementGroup, ElementGroupChangeCallbackParams, ElementUpdate, type ElementsController, EntityNode, Feature, FeatureSelection, Felt, type FeltController, type FeltEmbedOptions, Filters, Geometry, GetElementGroupsConstraint, GetElementsConstraint, GetLayerCalculationParams, GetLayerCategoriesGroup, GetLayerCategoriesParams, GetLayerGroupsConstraint, GetLayerHistogramBin, GetLayerHistogramParams, GetLayersConstraint, GetRenderedFeaturesConstraint, InputToolSettings, type InteractionsController, Layer, LayerChangeCallbackParams, LayerFilters, LayerGroup, LayerGroupChangeCallbackParams, type LayersController, LegendItem, LegendItemChangeCallbackParams, LegendItemIdentifier, LegendItemsConstraint, MapDetails, MapInteractionEvent, type MiscController, type UiOnMapInteractionsOptions as OnMapInteractionsOptions, type SelectionController, SetViewportCenterZoomParams, SetVisibilityRequest, SortConfig, ToolSettingsChangeEvent, ToolSettingsMap, ToolType, type ToolsController, type UiController, type UiControlsOptions, ViewportCenterZoom, ViewportConstraints, type ViewportController, ViewportFitBoundsParams, ViewportState };