react-listing-engine 0.6.5 → 0.6.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/README.md +33 -41
- package/dist/chunk-4CZJODMK.cjs +2 -0
- package/dist/chunk-GSWGCJCO.js +2 -0
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +93 -11
- package/dist/index.d.ts +93 -11
- package/dist/index.js +1 -1
- package/dist/listing-app-BtNNEkX1.d.cts +347 -0
- package/dist/listing-app-IG1awue3.d.ts +347 -0
- package/dist/styled/index.cjs +1 -1
- package/dist/styled/index.d.cts +6 -7
- package/dist/styled/index.d.ts +6 -7
- package/dist/styled/index.js +1 -1
- package/dist/styles.css +31 -99
- package/package.json +12 -27
- package/dist/chunk-2VUHLHHX.cjs +0 -2
- package/dist/chunk-35KYEBAC.js +0 -2
- package/dist/chunk-CGT3RHJ7.js +0 -2
- package/dist/chunk-EYXV5OMY.cjs +0 -2
- package/dist/chunk-R3FX2V3N.js +0 -2
- package/dist/chunk-RXHR66FS.cjs +0 -2
- package/dist/components-provider-FinfaqUT.d.cts +0 -131
- package/dist/components-provider-cWVWEDXC.d.ts +0 -131
- package/dist/listing-app-BMoMKD4c.d.cts +0 -213
- package/dist/listing-app-BSJKGh7k.d.ts +0 -213
- package/dist/shadcn/index.cjs +0 -2
- package/dist/shadcn/index.d.cts +0 -259
- package/dist/shadcn/index.d.ts +0 -259
- package/dist/shadcn/index.js +0 -2
- package/dist/url-sync.controller-DK5W_0OZ.d.ts +0 -89
- package/dist/url-sync.controller-DXSIWgTa.d.cts +0 -89
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
import { L as LatLng, a as MapProvider } from './map-provider.interface-DT-v1plm.cjs';
|
|
4
|
-
import { D as DatasetDefinition, F as FilterRegistry, e as IListingComponents, I as IListingConfigOptions } from './components-provider-FinfaqUT.cjs';
|
|
5
|
-
|
|
6
|
-
type BottomNavView = 'list' | 'map';
|
|
7
|
-
interface IBottomNavAction {
|
|
8
|
-
label: string;
|
|
9
|
-
icon?: ReactNode;
|
|
10
|
-
onClick(): void;
|
|
11
|
-
}
|
|
12
|
-
interface IBottomNavProps {
|
|
13
|
-
view: BottomNavView;
|
|
14
|
-
onViewChange(view: BottomNavView): void;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Mobile-only bottom navigation (`.rle-bottom-nav`, hidden at 768px+ by CSS --
|
|
18
|
-
* see `styles.css`): a floating **List | Map** segmented toggle
|
|
19
|
-
* (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
|
|
20
|
-
* full-area panels is visible. The **Filters** button and the optional caller
|
|
21
|
-
* action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
|
|
22
|
-
* the footer pill carries the view toggle alone. No lucide/icon library
|
|
23
|
-
* dependency -- every icon here is a small inline SVG, matching the rest of
|
|
24
|
-
* `/styled`'s zero-extra-dependency policy.
|
|
25
|
-
*/
|
|
26
|
-
declare function BottomNav({ view, onViewChange }: IBottomNavProps): react.JSX.Element;
|
|
27
|
-
|
|
28
|
-
interface IStyledListingLayoutProps {
|
|
29
|
-
/**
|
|
30
|
-
* Optional header search box, LIBRARY-wired (unlike `/shadcn`'s
|
|
31
|
-
* consumer-managed `search`): name the `TFilters` field it drives via
|
|
32
|
-
* `filterKey`, and the layout reads the current value from the engine's
|
|
33
|
-
* filters and writes edits back with `applyFilters({ [filterKey]: value ||
|
|
34
|
-
* undefined })`. Rendered in BOTH the desktop filter bar and the mobile
|
|
35
|
-
* header. Do NOT also register `filterKey` as a `ListingFilters` control --
|
|
36
|
-
* it would then render twice. Omitted entirely when not passed.
|
|
37
|
-
*/
|
|
38
|
-
search?: {
|
|
39
|
-
filterKey: string;
|
|
40
|
-
placeholder?: string;
|
|
41
|
-
};
|
|
42
|
-
/** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
|
|
43
|
-
toolbarEnd?: ReactNode;
|
|
44
|
-
/** Optional bottom-nav action button (e.g. "Add"), forwarded verbatim to `<BottomNav action={...} />`. Omit to render just Filters + the List|Map toggle. */
|
|
45
|
-
mobileAction?: IBottomNavAction;
|
|
46
|
-
/**
|
|
47
|
-
* Whether a map is configured. When `false`, the map region is dropped and
|
|
48
|
-
* the results list fills the full width as a multi-column grid, and the
|
|
49
|
-
* mobile List|Map toggle is omitted (nothing to toggle to). Defaults to
|
|
50
|
-
* `true` (the split list/map view). `ListingApp` passes `map != null`.
|
|
51
|
-
*/
|
|
52
|
-
hasMap?: boolean;
|
|
53
|
-
/** Whether the layout fetches the first page itself on mount (`engine.applyFilters({})`). Defaults to `true`. */
|
|
54
|
-
autoFetch?: boolean;
|
|
55
|
-
/** Forwarded verbatim to `<ListingMap center={mapCenter} />` -- see that component's "Auto-fit" doc comment. */
|
|
56
|
-
mapCenter?: LatLng;
|
|
57
|
-
/** Forwarded verbatim to `<ListingMap zoom={mapZoom} />`. */
|
|
58
|
-
mapZoom?: number;
|
|
59
|
-
className?: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Full, responsive, Tailwind-free listing experience -- the `/styled`
|
|
63
|
-
* counterpart to `/shadcn`'s `ListingLayout`, built from the same
|
|
64
|
-
* structure-only compound components (`~/react`) plus the injected
|
|
65
|
-
* `Styled*` slot components, but with a richer mobile experience: a bottom
|
|
66
|
-
* nav (`BottomNav`) and a bottom sheet (`BottomSheet`) for filters, instead
|
|
67
|
-
* of `/shadcn`'s inline mobile toggle bar. Every class used here is one of
|
|
68
|
-
* the `.rle-*` layout classes added to `styles.css` alongside this file --
|
|
69
|
-
* no Tailwind, no inline styles, no other stylesheet required.
|
|
70
|
-
*
|
|
71
|
-
* STRUCTURE (`.rle-app`):
|
|
72
|
-
* - `.rle-filter-bar` (desktop only, hidden below 1024px by CSS): the
|
|
73
|
-
* optional `Search` slot and `<ListingFilters>` laid out as a single
|
|
74
|
-
* horizontally-scrolling row (`className="rle-filters-row"`,
|
|
75
|
-
* `groupClassName="rle-filter-group"`) with edge fades. The result header +
|
|
76
|
-
* `toolbarEnd` are NOT here -- they sit in `.rle-list-header` above the list.
|
|
77
|
-
* - `.rle-list-header` (top of `.rle-list`): `<ListingResultHeader>` (title +
|
|
78
|
-
* count) at the left, `toolbarEnd` (sort control, save-search, ...) at the
|
|
79
|
-
* right -- a heading for the results, on every viewport.
|
|
80
|
-
* - `.rle-body.rle-split`: a CSS grid from 768px up (list column floors at
|
|
81
|
-
* 340px, caps at 42%; map takes the rest); below that, a single full-area
|
|
82
|
-
* panel with exactly one of `.rle-list`/`.rle-map` visible at a time via
|
|
83
|
-
* `data-mobile-view` (see `styles.css`'s mobile media query). Both regions
|
|
84
|
-
* stay mounted at ALL times regardless of viewport/toggle state -- only
|
|
85
|
-
* their visibility flips -- so neither `ListingList` nor `ListingMap`
|
|
86
|
-
* remounts (and re-triggers its own mount effects) on toggle or resize.
|
|
87
|
-
* - `<BottomNav>`: mobile-only (CSS-hidden at 768px+). Wired to the same
|
|
88
|
-
* `mobileView` state as the CSS toggle, `mobileAction`, and opens the
|
|
89
|
-
* filters `<BottomSheet>`.
|
|
90
|
-
* - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
|
|
91
|
-
* stacked vertically (`className="rle-filter-stack"`) for the sheet's
|
|
92
|
-
* narrower body, plus a footer with "Clear all" (resets every registered
|
|
93
|
-
* filter to `undefined` via `engine.filters.list()`'s keys, routed through
|
|
94
|
-
* `engine.applyFilters` -- the one bulk mutator, same as `ListingFilters`
|
|
95
|
-
* itself uses) and "Show N results" (just closes the sheet -- every filter
|
|
96
|
-
* control already applies live via its own `onChange`, so there is nothing
|
|
97
|
-
* left to commit).
|
|
98
|
-
* - Fetches the first page itself on mount (`engine.applyFilters({})`) by
|
|
99
|
-
* default, exactly like `/shadcn`'s `ListingLayout` -- pass `autoFetch={false}`
|
|
100
|
-
* to opt out and drive the first fetch yourself.
|
|
101
|
-
*/
|
|
102
|
-
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Same two-shape `map` prop as `/shadcn`'s `ListingApp` (see that file's
|
|
106
|
-
* `useResolvedMap` doc comment for why the `{ apiKey }` shorthand is resolved
|
|
107
|
-
* via a dynamic `import()` rather than a static one -- the reasoning is
|
|
108
|
-
* identical here). Re-declared rather than imported from `~/shadcn`: the two
|
|
109
|
-
* styled adapters are SIBLINGS, not a hierarchy -- `/styled` never depends on
|
|
110
|
-
* `/shadcn` (or vice versa), each is self-contained against `~/core`/`~/react`.
|
|
111
|
-
*/
|
|
112
|
-
type ListingAppMapProp = {
|
|
113
|
-
provider: MapProvider;
|
|
114
|
-
center?: LatLng;
|
|
115
|
-
zoom?: number;
|
|
116
|
-
} | {
|
|
117
|
-
apiKey: string;
|
|
118
|
-
mapId?: string;
|
|
119
|
-
center?: LatLng;
|
|
120
|
-
zoom?: number;
|
|
121
|
-
};
|
|
122
|
-
interface ListingAppProps<TFilters> {
|
|
123
|
-
/**
|
|
124
|
-
* One or more marker-layer datasets; the FIRST entry is the primary
|
|
125
|
-
* dataset (drives the results list + pagination) -- same "insertion
|
|
126
|
-
* order" rule `composeListingProviders`/`withDataset` already follow.
|
|
127
|
-
* Entity-erased (`any`, not `TEntity`) for the same reason
|
|
128
|
-
* `DatasetRegistry<unknown, TFilters>` is: one array can legitimately hold
|
|
129
|
-
* heterogeneous layers (a properties dataset and a businesses dataset have
|
|
130
|
-
* different entity types) -- see `compose-listing-providers.ts`'s
|
|
131
|
-
* `withDataset` doc comment.
|
|
132
|
-
*/
|
|
133
|
-
datasets: DatasetDefinition<any, TFilters>[];
|
|
134
|
-
/** A `(reg) => { reg.add(...); }` callback that registers your filters -- forwarded verbatim to `withFilters`. */
|
|
135
|
-
filters?: (reg: FilterRegistry<TFilters>) => void;
|
|
136
|
-
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map (the styled layout shows a "Map unavailable" fallback). */
|
|
137
|
-
map?: ListingAppMapProp;
|
|
138
|
-
/** Slot overrides, merged OVER the `/styled` defaults -- see this file's doc comment for how the merge works. */
|
|
139
|
-
components?: Partial<IListingComponents>;
|
|
140
|
-
/**
|
|
141
|
-
* Hydrates the engine's initial filters on mount -- typically read from
|
|
142
|
-
* the CONSUMER's own URL (e.g. `rentalFiltersFromQuery(new
|
|
143
|
-
* URLSearchParams(window.location.search))`), but any source works. Half
|
|
144
|
-
* of the event-based URL API this component exposes: `ListingApp` never
|
|
145
|
-
* reads `window.location` itself, it only accepts filters as a prop.
|
|
146
|
-
*/
|
|
147
|
-
initialFilters?: TFilters;
|
|
148
|
-
/**
|
|
149
|
-
* EVENT OUT: fires with the engine's current filters (`TFilters`, not the
|
|
150
|
-
* store's `DeepReadonly` wrapper) every time `ListingEventType.FiltersChanged`
|
|
151
|
-
* fires on the underlying engine -- i.e. on every `engine.applyFilters(...)`
|
|
152
|
-
* call, INCLUDING the one `StyledListingLayout` makes on mount when
|
|
153
|
-
* `autoFetch` is on (a `{}` patch that still round-trips through
|
|
154
|
-
* `currentFilters()` and re-emits the very `initialFilters` this component
|
|
155
|
-
* was given). That first call is intentionally NOT suppressed: a
|
|
156
|
-
* consumer's handler is expected to write filters back to a URL via
|
|
157
|
-
* `history.replaceState` (or a router's equivalent), and replacing the URL
|
|
158
|
-
* with the SAME query string it already hydrated from is a no-op, not a
|
|
159
|
-
* visible echo -- so "just always emit" is simpler than tracking a
|
|
160
|
-
* first-call flag for no behavioral gain. This is the OTHER half of the
|
|
161
|
-
* event-based URL API: `ListingApp` (and the engine underneath it) never
|
|
162
|
-
* touches `window.history` -- the CONSUMER owns routing, driven by this
|
|
163
|
-
* callback plus `initialFilters` above. `UrlSyncController`/`BrowserHistoryPort`
|
|
164
|
-
* (`~/core`, `~/react`) remain exported as optional, lower-level helpers
|
|
165
|
-
* for consumers who want the library to own `window.history` directly, but
|
|
166
|
-
* they are no longer the primary/recommended path for new integrations.
|
|
167
|
-
*/
|
|
168
|
-
onFiltersChange?: (filters: TFilters) => void;
|
|
169
|
-
/** The mobile bottom-nav "Add" action -- forwarded verbatim to `StyledListingLayout`/`BottomNav`. */
|
|
170
|
-
mobileAction?: IBottomNavAction;
|
|
171
|
-
search?: IStyledListingLayoutProps['search'];
|
|
172
|
-
toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
|
|
173
|
-
config?: Partial<IListingConfigOptions>;
|
|
174
|
-
autoFetch?: boolean;
|
|
175
|
-
className?: string;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Turnkey, batteries-included, Tailwind-free entry point -- the `/styled`
|
|
179
|
-
* counterpart to `/shadcn`'s `ListingApp`, and (per `src/index.ts`) the
|
|
180
|
-
* package's MAIN-ENTRY default: `import { ListingApp } from
|
|
181
|
-
* 'react-listing-engine'` gives you this component. Pass datasets + filters +
|
|
182
|
-
* a map + component overrides, and `ListingApp` composes
|
|
183
|
-
* `composeListingProviders(...)`, `<ListingProvider>`, the `/styled` defaults,
|
|
184
|
-
* and `<StyledListingLayout>` for you.
|
|
185
|
-
*
|
|
186
|
-
* `TEntity` still can't be inferred from these props (`datasets` narrows it,
|
|
187
|
-
* but a multi-dataset array widens back to the union/`unknown` in practice)
|
|
188
|
-
* -- annotate the call site when entity-level typing matters, exactly like
|
|
189
|
-
* `<ListingProvider<TEntity, TFilters>>` itself.
|
|
190
|
-
*
|
|
191
|
-
* COMPONENTS MERGE: `components` overrides are applied ON TOP of the
|
|
192
|
-
* `/styled` defaults via ONE explicit `{ ...styledDefaultComponents,
|
|
193
|
-
* ...components }` object, passed to a single `<ListingComponentsProvider>`
|
|
194
|
-
* -- never as a nested `<ListingComponentsProvider>` inside
|
|
195
|
-
* `StyledComponentsProviderWithDefaults`. `ListingComponentsProvider` merges
|
|
196
|
-
* `provided ?? ITS OWN private, unstyled fallbacks` per slot (it does not
|
|
197
|
-
* read the parent context -- see `src/react/components-provider.tsx`), so
|
|
198
|
-
* nesting would silently discard every un-overridden `/styled` default
|
|
199
|
-
* instead of keeping it.
|
|
200
|
-
*
|
|
201
|
-
* URL SYNC IS EVENT-BASED, NOT INTERNAL: unlike `/shadcn`'s `ListingApp`,
|
|
202
|
-
* this component takes no `urlSync` prop and never constructs/starts a
|
|
203
|
-
* `UrlSyncController` -- it never touches `window.history`. Instead it
|
|
204
|
-
* accepts `initialFilters` (hydrate FROM the consumer's URL) and emits
|
|
205
|
-
* `onFiltersChange` (write TO the consumer's URL/router) -- see both props'
|
|
206
|
-
* doc comments for the full contract. This keeps the library's surface
|
|
207
|
-
* router-agnostic (a plain `history.replaceState`, a Next.js `router.replace`,
|
|
208
|
-
* a React Router `setSearchParams`, etc. all work identically from the
|
|
209
|
-
* consumer's side) instead of assuming `window.history` is the right target.
|
|
210
|
-
*/
|
|
211
|
-
declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element | null;
|
|
212
|
-
|
|
213
|
-
export { BottomNav as B, type IBottomNavAction as I, ListingApp as L, StyledListingLayout as S, type ListingAppProps as a, type BottomNavView as b, type IBottomNavProps as c, type IStyledListingLayoutProps as d, type ListingAppMapProp as e };
|
|
@@ -1,213 +0,0 @@
|
|
|
1
|
-
import * as react from 'react';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
3
|
-
import { L as LatLng, a as MapProvider } from './map-provider.interface-DT-v1plm.js';
|
|
4
|
-
import { D as DatasetDefinition, F as FilterRegistry, e as IListingComponents, I as IListingConfigOptions } from './components-provider-cWVWEDXC.js';
|
|
5
|
-
|
|
6
|
-
type BottomNavView = 'list' | 'map';
|
|
7
|
-
interface IBottomNavAction {
|
|
8
|
-
label: string;
|
|
9
|
-
icon?: ReactNode;
|
|
10
|
-
onClick(): void;
|
|
11
|
-
}
|
|
12
|
-
interface IBottomNavProps {
|
|
13
|
-
view: BottomNavView;
|
|
14
|
-
onViewChange(view: BottomNavView): void;
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* Mobile-only bottom navigation (`.rle-bottom-nav`, hidden at 768px+ by CSS --
|
|
18
|
-
* see `styles.css`): a floating **List | Map** segmented toggle
|
|
19
|
-
* (`.rle-viewtoggle`) that drives which of `StyledListingLayout`'s two
|
|
20
|
-
* full-area panels is visible. The **Filters** button and the optional caller
|
|
21
|
-
* action (e.g. "Save") live in the mobile header (`MobileHeader`) instead, so
|
|
22
|
-
* the footer pill carries the view toggle alone. No lucide/icon library
|
|
23
|
-
* dependency -- every icon here is a small inline SVG, matching the rest of
|
|
24
|
-
* `/styled`'s zero-extra-dependency policy.
|
|
25
|
-
*/
|
|
26
|
-
declare function BottomNav({ view, onViewChange }: IBottomNavProps): react.JSX.Element;
|
|
27
|
-
|
|
28
|
-
interface IStyledListingLayoutProps {
|
|
29
|
-
/**
|
|
30
|
-
* Optional header search box, LIBRARY-wired (unlike `/shadcn`'s
|
|
31
|
-
* consumer-managed `search`): name the `TFilters` field it drives via
|
|
32
|
-
* `filterKey`, and the layout reads the current value from the engine's
|
|
33
|
-
* filters and writes edits back with `applyFilters({ [filterKey]: value ||
|
|
34
|
-
* undefined })`. Rendered in BOTH the desktop filter bar and the mobile
|
|
35
|
-
* header. Do NOT also register `filterKey` as a `ListingFilters` control --
|
|
36
|
-
* it would then render twice. Omitted entirely when not passed.
|
|
37
|
-
*/
|
|
38
|
-
search?: {
|
|
39
|
-
filterKey: string;
|
|
40
|
-
placeholder?: string;
|
|
41
|
-
};
|
|
42
|
-
/** Extra content rendered in `.rle-list-header` (above the list), to the right of `ListingResultHeader` (e.g. a sort control + save-search). */
|
|
43
|
-
toolbarEnd?: ReactNode;
|
|
44
|
-
/** Optional bottom-nav action button (e.g. "Add"), forwarded verbatim to `<BottomNav action={...} />`. Omit to render just Filters + the List|Map toggle. */
|
|
45
|
-
mobileAction?: IBottomNavAction;
|
|
46
|
-
/**
|
|
47
|
-
* Whether a map is configured. When `false`, the map region is dropped and
|
|
48
|
-
* the results list fills the full width as a multi-column grid, and the
|
|
49
|
-
* mobile List|Map toggle is omitted (nothing to toggle to). Defaults to
|
|
50
|
-
* `true` (the split list/map view). `ListingApp` passes `map != null`.
|
|
51
|
-
*/
|
|
52
|
-
hasMap?: boolean;
|
|
53
|
-
/** Whether the layout fetches the first page itself on mount (`engine.applyFilters({})`). Defaults to `true`. */
|
|
54
|
-
autoFetch?: boolean;
|
|
55
|
-
/** Forwarded verbatim to `<ListingMap center={mapCenter} />` -- see that component's "Auto-fit" doc comment. */
|
|
56
|
-
mapCenter?: LatLng;
|
|
57
|
-
/** Forwarded verbatim to `<ListingMap zoom={mapZoom} />`. */
|
|
58
|
-
mapZoom?: number;
|
|
59
|
-
className?: string;
|
|
60
|
-
}
|
|
61
|
-
/**
|
|
62
|
-
* Full, responsive, Tailwind-free listing experience -- the `/styled`
|
|
63
|
-
* counterpart to `/shadcn`'s `ListingLayout`, built from the same
|
|
64
|
-
* structure-only compound components (`~/react`) plus the injected
|
|
65
|
-
* `Styled*` slot components, but with a richer mobile experience: a bottom
|
|
66
|
-
* nav (`BottomNav`) and a bottom sheet (`BottomSheet`) for filters, instead
|
|
67
|
-
* of `/shadcn`'s inline mobile toggle bar. Every class used here is one of
|
|
68
|
-
* the `.rle-*` layout classes added to `styles.css` alongside this file --
|
|
69
|
-
* no Tailwind, no inline styles, no other stylesheet required.
|
|
70
|
-
*
|
|
71
|
-
* STRUCTURE (`.rle-app`):
|
|
72
|
-
* - `.rle-filter-bar` (desktop only, hidden below 1024px by CSS): the
|
|
73
|
-
* optional `Search` slot and `<ListingFilters>` laid out as a single
|
|
74
|
-
* horizontally-scrolling row (`className="rle-filters-row"`,
|
|
75
|
-
* `groupClassName="rle-filter-group"`) with edge fades. The result header +
|
|
76
|
-
* `toolbarEnd` are NOT here -- they sit in `.rle-list-header` above the list.
|
|
77
|
-
* - `.rle-list-header` (top of `.rle-list`): `<ListingResultHeader>` (title +
|
|
78
|
-
* count) at the left, `toolbarEnd` (sort control, save-search, ...) at the
|
|
79
|
-
* right -- a heading for the results, on every viewport.
|
|
80
|
-
* - `.rle-body.rle-split`: a CSS grid from 768px up (list column floors at
|
|
81
|
-
* 340px, caps at 42%; map takes the rest); below that, a single full-area
|
|
82
|
-
* panel with exactly one of `.rle-list`/`.rle-map` visible at a time via
|
|
83
|
-
* `data-mobile-view` (see `styles.css`'s mobile media query). Both regions
|
|
84
|
-
* stay mounted at ALL times regardless of viewport/toggle state -- only
|
|
85
|
-
* their visibility flips -- so neither `ListingList` nor `ListingMap`
|
|
86
|
-
* remounts (and re-triggers its own mount effects) on toggle or resize.
|
|
87
|
-
* - `<BottomNav>`: mobile-only (CSS-hidden at 768px+). Wired to the same
|
|
88
|
-
* `mobileView` state as the CSS toggle, `mobileAction`, and opens the
|
|
89
|
-
* filters `<BottomSheet>`.
|
|
90
|
-
* - `<BottomSheet title="Filters">`: the SAME `<ListingFilters>` component,
|
|
91
|
-
* stacked vertically (`className="rle-filter-stack"`) for the sheet's
|
|
92
|
-
* narrower body, plus a footer with "Clear all" (resets every registered
|
|
93
|
-
* filter to `undefined` via `engine.filters.list()`'s keys, routed through
|
|
94
|
-
* `engine.applyFilters` -- the one bulk mutator, same as `ListingFilters`
|
|
95
|
-
* itself uses) and "Show N results" (just closes the sheet -- every filter
|
|
96
|
-
* control already applies live via its own `onChange`, so there is nothing
|
|
97
|
-
* left to commit).
|
|
98
|
-
* - Fetches the first page itself on mount (`engine.applyFilters({})`) by
|
|
99
|
-
* default, exactly like `/shadcn`'s `ListingLayout` -- pass `autoFetch={false}`
|
|
100
|
-
* to opt out and drive the first fetch yourself.
|
|
101
|
-
*/
|
|
102
|
-
declare function StyledListingLayout({ search, toolbarEnd, mobileAction, autoFetch, hasMap, mapCenter, mapZoom, className, }: IStyledListingLayoutProps): react.JSX.Element;
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Same two-shape `map` prop as `/shadcn`'s `ListingApp` (see that file's
|
|
106
|
-
* `useResolvedMap` doc comment for why the `{ apiKey }` shorthand is resolved
|
|
107
|
-
* via a dynamic `import()` rather than a static one -- the reasoning is
|
|
108
|
-
* identical here). Re-declared rather than imported from `~/shadcn`: the two
|
|
109
|
-
* styled adapters are SIBLINGS, not a hierarchy -- `/styled` never depends on
|
|
110
|
-
* `/shadcn` (or vice versa), each is self-contained against `~/core`/`~/react`.
|
|
111
|
-
*/
|
|
112
|
-
type ListingAppMapProp = {
|
|
113
|
-
provider: MapProvider;
|
|
114
|
-
center?: LatLng;
|
|
115
|
-
zoom?: number;
|
|
116
|
-
} | {
|
|
117
|
-
apiKey: string;
|
|
118
|
-
mapId?: string;
|
|
119
|
-
center?: LatLng;
|
|
120
|
-
zoom?: number;
|
|
121
|
-
};
|
|
122
|
-
interface ListingAppProps<TFilters> {
|
|
123
|
-
/**
|
|
124
|
-
* One or more marker-layer datasets; the FIRST entry is the primary
|
|
125
|
-
* dataset (drives the results list + pagination) -- same "insertion
|
|
126
|
-
* order" rule `composeListingProviders`/`withDataset` already follow.
|
|
127
|
-
* Entity-erased (`any`, not `TEntity`) for the same reason
|
|
128
|
-
* `DatasetRegistry<unknown, TFilters>` is: one array can legitimately hold
|
|
129
|
-
* heterogeneous layers (a properties dataset and a businesses dataset have
|
|
130
|
-
* different entity types) -- see `compose-listing-providers.ts`'s
|
|
131
|
-
* `withDataset` doc comment.
|
|
132
|
-
*/
|
|
133
|
-
datasets: DatasetDefinition<any, TFilters>[];
|
|
134
|
-
/** A `(reg) => { reg.add(...); }` callback that registers your filters -- forwarded verbatim to `withFilters`. */
|
|
135
|
-
filters?: (reg: FilterRegistry<TFilters>) => void;
|
|
136
|
-
/** A ready `MapProvider`, or `{ apiKey, mapId? }` to build a `googleProvider` internally. Omit for no map (the styled layout shows a "Map unavailable" fallback). */
|
|
137
|
-
map?: ListingAppMapProp;
|
|
138
|
-
/** Slot overrides, merged OVER the `/styled` defaults -- see this file's doc comment for how the merge works. */
|
|
139
|
-
components?: Partial<IListingComponents>;
|
|
140
|
-
/**
|
|
141
|
-
* Hydrates the engine's initial filters on mount -- typically read from
|
|
142
|
-
* the CONSUMER's own URL (e.g. `rentalFiltersFromQuery(new
|
|
143
|
-
* URLSearchParams(window.location.search))`), but any source works. Half
|
|
144
|
-
* of the event-based URL API this component exposes: `ListingApp` never
|
|
145
|
-
* reads `window.location` itself, it only accepts filters as a prop.
|
|
146
|
-
*/
|
|
147
|
-
initialFilters?: TFilters;
|
|
148
|
-
/**
|
|
149
|
-
* EVENT OUT: fires with the engine's current filters (`TFilters`, not the
|
|
150
|
-
* store's `DeepReadonly` wrapper) every time `ListingEventType.FiltersChanged`
|
|
151
|
-
* fires on the underlying engine -- i.e. on every `engine.applyFilters(...)`
|
|
152
|
-
* call, INCLUDING the one `StyledListingLayout` makes on mount when
|
|
153
|
-
* `autoFetch` is on (a `{}` patch that still round-trips through
|
|
154
|
-
* `currentFilters()` and re-emits the very `initialFilters` this component
|
|
155
|
-
* was given). That first call is intentionally NOT suppressed: a
|
|
156
|
-
* consumer's handler is expected to write filters back to a URL via
|
|
157
|
-
* `history.replaceState` (or a router's equivalent), and replacing the URL
|
|
158
|
-
* with the SAME query string it already hydrated from is a no-op, not a
|
|
159
|
-
* visible echo -- so "just always emit" is simpler than tracking a
|
|
160
|
-
* first-call flag for no behavioral gain. This is the OTHER half of the
|
|
161
|
-
* event-based URL API: `ListingApp` (and the engine underneath it) never
|
|
162
|
-
* touches `window.history` -- the CONSUMER owns routing, driven by this
|
|
163
|
-
* callback plus `initialFilters` above. `UrlSyncController`/`BrowserHistoryPort`
|
|
164
|
-
* (`~/core`, `~/react`) remain exported as optional, lower-level helpers
|
|
165
|
-
* for consumers who want the library to own `window.history` directly, but
|
|
166
|
-
* they are no longer the primary/recommended path for new integrations.
|
|
167
|
-
*/
|
|
168
|
-
onFiltersChange?: (filters: TFilters) => void;
|
|
169
|
-
/** The mobile bottom-nav "Add" action -- forwarded verbatim to `StyledListingLayout`/`BottomNav`. */
|
|
170
|
-
mobileAction?: IBottomNavAction;
|
|
171
|
-
search?: IStyledListingLayoutProps['search'];
|
|
172
|
-
toolbarEnd?: IStyledListingLayoutProps['toolbarEnd'];
|
|
173
|
-
config?: Partial<IListingConfigOptions>;
|
|
174
|
-
autoFetch?: boolean;
|
|
175
|
-
className?: string;
|
|
176
|
-
}
|
|
177
|
-
/**
|
|
178
|
-
* Turnkey, batteries-included, Tailwind-free entry point -- the `/styled`
|
|
179
|
-
* counterpart to `/shadcn`'s `ListingApp`, and (per `src/index.ts`) the
|
|
180
|
-
* package's MAIN-ENTRY default: `import { ListingApp } from
|
|
181
|
-
* 'react-listing-engine'` gives you this component. Pass datasets + filters +
|
|
182
|
-
* a map + component overrides, and `ListingApp` composes
|
|
183
|
-
* `composeListingProviders(...)`, `<ListingProvider>`, the `/styled` defaults,
|
|
184
|
-
* and `<StyledListingLayout>` for you.
|
|
185
|
-
*
|
|
186
|
-
* `TEntity` still can't be inferred from these props (`datasets` narrows it,
|
|
187
|
-
* but a multi-dataset array widens back to the union/`unknown` in practice)
|
|
188
|
-
* -- annotate the call site when entity-level typing matters, exactly like
|
|
189
|
-
* `<ListingProvider<TEntity, TFilters>>` itself.
|
|
190
|
-
*
|
|
191
|
-
* COMPONENTS MERGE: `components` overrides are applied ON TOP of the
|
|
192
|
-
* `/styled` defaults via ONE explicit `{ ...styledDefaultComponents,
|
|
193
|
-
* ...components }` object, passed to a single `<ListingComponentsProvider>`
|
|
194
|
-
* -- never as a nested `<ListingComponentsProvider>` inside
|
|
195
|
-
* `StyledComponentsProviderWithDefaults`. `ListingComponentsProvider` merges
|
|
196
|
-
* `provided ?? ITS OWN private, unstyled fallbacks` per slot (it does not
|
|
197
|
-
* read the parent context -- see `src/react/components-provider.tsx`), so
|
|
198
|
-
* nesting would silently discard every un-overridden `/styled` default
|
|
199
|
-
* instead of keeping it.
|
|
200
|
-
*
|
|
201
|
-
* URL SYNC IS EVENT-BASED, NOT INTERNAL: unlike `/shadcn`'s `ListingApp`,
|
|
202
|
-
* this component takes no `urlSync` prop and never constructs/starts a
|
|
203
|
-
* `UrlSyncController` -- it never touches `window.history`. Instead it
|
|
204
|
-
* accepts `initialFilters` (hydrate FROM the consumer's URL) and emits
|
|
205
|
-
* `onFiltersChange` (write TO the consumer's URL/router) -- see both props'
|
|
206
|
-
* doc comments for the full contract. This keeps the library's surface
|
|
207
|
-
* router-agnostic (a plain `history.replaceState`, a Next.js `router.replace`,
|
|
208
|
-
* a React Router `setSearchParams`, etc. all work identically from the
|
|
209
|
-
* consumer's side) instead of assuming `window.history` is the right target.
|
|
210
|
-
*/
|
|
211
|
-
declare function ListingApp<TEntity, TFilters>(props: ListingAppProps<TFilters>): react.JSX.Element | null;
|
|
212
|
-
|
|
213
|
-
export { BottomNav as B, type IBottomNavAction as I, ListingApp as L, StyledListingLayout as S, type ListingAppProps as a, type BottomNavView as b, type IBottomNavProps as c, type IStyledListingLayoutProps as d, type ListingAppMapProp as e };
|
package/dist/shadcn/index.cjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports, "__esModule", {value: true}); function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) { newObj[key] = obj[key]; } } } newObj.default = obj; return newObj; } } function _nullishCoalesce(lhs, rhsFn) { if (lhs != null) { return lhs; } else { return rhsFn(); } } function _optionalChain(ops) { let lastAccessLHS = undefined; let value = ops[0]; let i = 1; while (i < ops.length) { const op = ops[i]; const fn = ops[i + 1]; i += 2; if ((op === 'optionalAccess' || op === 'optionalCall') && value == null) { return undefined; } if (op === 'access' || op === 'optionalAccess') { lastAccessLHS = value; value = fn(value); } else if (op === 'call' || op === 'optionalCall') { value = fn((...args) => value.call(lastAccessLHS, ...args)); lastAccessLHS = undefined; } } return value; }"use client";
|
|
2
|
-
var _chunk2VUHLHHXcjs = require('../chunk-2VUHLHHX.cjs');var _chunkEYXV5OMYcjs = require('../chunk-EYXV5OMY.cjs');var _clsx = require('clsx');var _tailwindmerge = require('tailwind-merge');function s(...e){return _tailwindmerge.twMerge.call(void 0, _clsx.clsx.call(void 0, e))}var _jsxruntime = require('react/jsx-runtime');function ae(e){return typeof e!="number"?e:new Intl.NumberFormat("en-US",{style:"currency",currency:"USD",maximumFractionDigits:0}).format(e)}function w({item:e,selected:o,onSelect:t}){let r=_nullishCoalesce(e, () => ({})),l=s("flex w-full flex-col overflow-hidden rounded-lg border bg-card text-left text-card-foreground shadow-sm","motion-safe:transition-shadow",t&&"hover:shadow-md focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",o&&"ring-2 ring-ring"),a=_jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment,{children:[r.imageUrl&&_jsxruntime.jsx.call(void 0, "img",{src:r.imageUrl,alt:_nullishCoalesce(r.title, () => ("")),className:"aspect-video w-full rounded-t-lg object-cover"}),_jsxruntime.jsxs.call(void 0, "div",{className:"flex flex-1 flex-col gap-1 p-3",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"flex items-start justify-between gap-2",children:[r.title&&_jsxruntime.jsx.call(void 0, "span",{className:"font-medium",children:r.title}),r.badge&&_jsxruntime.jsx.call(void 0, "span",{className:"shrink-0 rounded-full bg-muted px-2 py-0.5 text-xs font-medium text-muted-foreground",children:r.badge})]}),r.subtitle&&_jsxruntime.jsx.call(void 0, "span",{className:"text-sm text-muted-foreground",children:r.subtitle}),r.price!=null&&_jsxruntime.jsx.call(void 0, "span",{className:"mt-1 font-semibold tabular-nums",children:ae(r.price)})]})]});return t?_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:t,"aria-pressed":_nullishCoalesce(o, () => (!1)),className:l,children:a}):_jsxruntime.jsx.call(void 0, "article",{className:l,children:a})}function C(e){return _jsxruntime.jsxs.call(void 0, "div",{role:"status",className:"flex flex-col items-center justify-center gap-2 px-4 py-12 text-center text-muted-foreground",children:[_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:1.5,strokeLinecap:"round",strokeLinejoin:"round",className:"h-8 w-8","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "circle",{cx:"11",cy:"11",r:"7"}),_jsxruntime.jsx.call(void 0, "path",{d:"m21 21-4.3-4.3"})]}),_jsxruntime.jsx.call(void 0, "p",{className:"text-sm font-medium text-foreground",children:"No results"}),_jsxruntime.jsx.call(void 0, "p",{className:"text-xs text-muted-foreground",children:"Try adjusting your filters or search terms."})]})}function I({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"flex flex-col gap-3",children:e})}function D(e){return _jsxruntime.jsx.call(void 0, "div",{className:"flex flex-col gap-3 p-3",role:"status","aria-busy":"true","aria-label":"Loading results",children:Array.from({length:3}).map((o,t)=>_jsxruntime.jsxs.call(void 0, "div",{className:"flex flex-col gap-2 motion-safe:animate-pulse",children:[_jsxruntime.jsx.call(void 0, "div",{className:"aspect-video w-full rounded-md bg-muted"}),_jsxruntime.jsx.call(void 0, "div",{className:"h-4 w-2/3 rounded-md bg-muted"}),_jsxruntime.jsx.call(void 0, "div",{className:"h-3 w-1/3 rounded-md bg-muted"})]},t))})}function M({point:e}){let o=_nullishCoalesce(e.entity, () => ({}));return _jsxruntime.jsx.call(void 0, "span",{className:"rounded-full border bg-background px-2 py-0.5 text-xs font-medium tabular-nums shadow-sm",children:_nullishCoalesce(o.price, () => (""))})}function F({entity:e,onClose:o}){let t=_nullishCoalesce(e, () => ({}));return _jsxruntime.jsxs.call(void 0, "div",{className:"relative w-64 rounded-lg border bg-popover p-3 text-popover-foreground shadow-md",role:"group","aria-label":"Location details",children:[_jsxruntime.jsx.call(void 0, "button",{type:"button",onClick:o,"aria-label":"Close",className:"absolute right-2 top-2 rounded-md p-1 text-muted-foreground motion-safe:transition-colors hover:bg-foreground/[0.06] hover:text-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring",children:_jsxruntime.jsxs.call(void 0, "svg",{xmlns:"http://www.w3.org/2000/svg",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:2,strokeLinecap:"round",strokeLinejoin:"round",className:"h-4 w-4","aria-hidden":"true",children:[_jsxruntime.jsx.call(void 0, "path",{d:"M18 6 6 18"}),_jsxruntime.jsx.call(void 0, "path",{d:"m6 6 12 12"})]})}),_jsxruntime.jsxs.call(void 0, "div",{className:"pr-6",children:[t.title&&_jsxruntime.jsx.call(void 0, "div",{className:"font-medium",children:t.title}),t.subtitle&&_jsxruntime.jsx.call(void 0, "div",{className:"text-sm text-muted-foreground",children:t.subtitle}),t.price!=null&&_jsxruntime.jsx.call(void 0, "div",{className:"mt-1 font-semibold tabular-nums",children:t.price})]})]})}function S({count:e,total:o}){let t=o!=null&&o!==e?`${e} of ${o} results`:`${e} results`;return _jsxruntime.jsx.call(void 0, "div",{className:"text-sm tabular-nums text-muted-foreground",children:t})}function T({value:e,onChange:o,placeholder:t}){return _jsxruntime.jsx.call(void 0, "input",{type:"search",value:e,placeholder:t,onChange:r=>o(r.target.value),"aria-label":_nullishCoalesce(t, () => ("Search")),className:s("h-9 w-full rounded-md border bg-background px-3 text-sm text-foreground placeholder:text-muted-foreground","focus-visible:border-ring focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring")})}function R({children:e}){return _jsxruntime.jsx.call(void 0, "aside",{className:"flex w-full flex-col gap-4 p-4 md:border-r md:border-border",children:e})}function A({children:e}){return _jsxruntime.jsx.call(void 0, "div",{className:"flex items-center gap-2 border-b p-2",children:e})}var g={Card:w,Marker:M,Popup:F,Sidebar:R,FilterPanel:I,Search:T,Empty:C,Loading:D,ResultHeader:S,Toolbar:A};function ge({children:e}){return _jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{...g,children:e})}var _react = require('react');var Le=_jsxruntime.jsx.call(void 0, "p",{className:"px-4 text-center text-sm text-muted-foreground",children:"Map unavailable - provide a Google Maps API key"});function E({search:e,className:o,toolbarEnd:t,autoFetch:r=!0,mapCenter:l,mapZoom:a}){let p=_chunkEYXV5OMYcjs.s.call(void 0, ),{Search:u}=_chunkEYXV5OMYcjs.q.call(void 0, ),[f,y]=_react.useState.call(void 0, "list");_react.useEffect.call(void 0, ()=>{r!==!1&&p.applyFilters({})},[p,r]);let h=f==="map"?"hidden md:block":"block",P=f==="list"?"hidden md:block":"block";return _jsxruntime.jsxs.call(void 0, "div",{className:s("flex h-full min-h-0 w-full flex-col bg-background text-foreground",o),"data-slot":"listing-layout",children:[_jsxruntime.jsxs.call(void 0, "div",{className:"sticky top-0 z-10 flex flex-wrap items-end gap-3 border-b border-border bg-background p-3","data-slot":"listing-layout-filter-bar",children:[e&&_jsxruntime.jsx.call(void 0, "div",{className:"w-full min-w-0 sm:w-auto sm:max-w-xs sm:flex-1",children:_jsxruntime.jsx.call(void 0, u,{value:e.value,onChange:e.onChange,placeholder:e.placeholder})}),_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.v,{className:"flex flex-wrap items-end gap-3",groupClassName:"min-w-0"}),_jsxruntime.jsxs.call(void 0, "div",{className:"ml-auto flex items-center gap-3",children:[_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.A,{}),t]})]}),_jsxruntime.jsx.call(void 0, "div",{className:"flex items-center justify-center gap-1 border-b border-border bg-background p-2 md:hidden","data-slot":"listing-layout-mobile-toggle",children:_jsxruntime.jsx.call(void 0, "div",{role:"group","aria-label":"View",className:"inline-flex rounded-md border border-border p-0.5",children:[{view:"list",label:"List"},{view:"map",label:"Map"}].map(({view:d,label:n})=>_jsxruntime.jsx.call(void 0, "button",{type:"button","aria-pressed":f===d,onClick:()=>y(d),className:s("rounded-[5px] px-3 py-1 text-sm font-medium motion-safe:transition-colors",f===d?"bg-primary text-primary-foreground":"text-muted-foreground hover:bg-foreground/[0.06] hover:text-foreground"),children:n},d))})}),_jsxruntime.jsxs.call(void 0, "div",{className:"grid min-h-0 flex-1 md:grid-cols-[minmax(340px,42%)_1fr]","data-slot":"listing-layout-split",children:[_jsxruntime.jsxs.call(void 0, "div",{className:s("min-h-0 overflow-y-auto p-3",h),"data-slot":"listing-layout-list",children:[_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.x,{className:"grid content-start gap-3 [grid-template-columns:repeat(auto-fill,minmax(200px,1fr))]"}),_jsxruntime.jsx.call(void 0, "div",{className:"mt-4 flex justify-center",children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.z,{})})]}),_jsxruntime.jsx.call(void 0, "div",{className:s("min-h-0 md:sticky md:top-0",P),"data-slot":"listing-layout-map",children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.y,{center:l,zoom:a,fallback:Le})})]})]})}function ee(e){return"provider"in e}function Pe(e){let o=e!=null&&!ee(e),t=o?e.apiKey:void 0,r=o?e.mapId:void 0,[l,a]=_react.useState.call(void 0, ()=>!e||ee(e)?{ready:!0,provider:_optionalChain([e, 'optionalAccess', _2 => _2.provider])}:{ready:!1});return _react.useEffect.call(void 0, ()=>{if(!t)return;let p=!1;return Promise.resolve().then(() => _interopRequireWildcard(require("../maps/google/index.cjs"))).then(({googleProvider:u})=>{p||a({ready:!0,provider:u({apiKey:t,mapId:r})})}),()=>{p=!0}},[t,r]),l}function Ne(e){let{datasets:o,filters:t,map:r,components:l,urlSync:a,initialFilters:p,config:u,className:f,search:y,autoFetch:h}=e,{ready:P,provider:d}=Pe(r);if(!P)return null;let n=[];for(let oe of o)n.push(_chunkEYXV5OMYcjs.k.call(void 0, oe));t&&n.push(_chunkEYXV5OMYcjs.l.call(void 0, t)),d&&n.push(_chunkEYXV5OMYcjs.j.call(void 0, d)),a instanceof _chunk2VUHLHHXcjs.a&&n.push(_chunkEYXV5OMYcjs.m.call(void 0, a)),p&&n.push(_chunkEYXV5OMYcjs.n.call(void 0, p)),u&&n.push(_chunkEYXV5OMYcjs.i.call(void 0, u));let te=_chunkEYXV5OMYcjs.h.call(void 0, ...n),re={...g,...l};return _jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.B,{...te,children:_jsxruntime.jsx.call(void 0, _chunkEYXV5OMYcjs.p,{...re,children:_jsxruntime.jsx.call(void 0, E,{className:f,search:y,autoFetch:h,mapCenter:_optionalChain([r, 'optionalAccess', _3 => _3.center]),mapZoom:_optionalChain([r, 'optionalAccess', _4 => _4.zoom])})})})}exports.DefaultCard = w; exports.DefaultEmpty = C; exports.DefaultFilterPanel = I; exports.DefaultLoading = D; exports.DefaultMarker = M; exports.DefaultPopup = F; exports.DefaultResultHeader = S; exports.DefaultSearch = T; exports.DefaultSidebar = R; exports.DefaultToolbar = A; exports.ListingApp = Ne; exports.ListingComponentsProviderWithDefaults = ge; exports.ListingLayout = E; exports.cn = s; exports.shadcnDefaultComponents = g;
|