@panneau/lists 4.1.1 → 5.0.0-alpha.0

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.
Files changed (138) hide show
  1. package/README.md +112 -0
  2. package/dist/List.d.ts +26 -0
  3. package/dist/List.d.ts.map +1 -0
  4. package/dist/List.js +38 -0
  5. package/dist/List.js.map +1 -0
  6. package/dist/ListView.css +101 -0
  7. package/dist/ListView.d.ts +70 -0
  8. package/dist/ListView.d.ts.map +1 -0
  9. package/dist/ListView.js +322 -0
  10. package/dist/ListView.js.map +1 -0
  11. package/dist/ListView.module.js +28 -0
  12. package/dist/ListView.module.js.map +1 -0
  13. package/dist/actions/ActionButton.d.ts +15 -0
  14. package/dist/actions/ActionButton.d.ts.map +1 -0
  15. package/dist/actions/ActionButton.js +34 -0
  16. package/dist/actions/ActionButton.js.map +1 -0
  17. package/dist/actions/Actions.css +58 -0
  18. package/dist/actions/Actions.module.js +20 -0
  19. package/dist/actions/Actions.module.js.map +1 -0
  20. package/dist/actions/ConfirmDialog.d.ts +15 -0
  21. package/dist/actions/ConfirmDialog.d.ts.map +1 -0
  22. package/dist/actions/ConfirmDialog.js +157 -0
  23. package/dist/actions/ConfirmDialog.js.map +1 -0
  24. package/dist/actions/RowActions.d.ts +17 -0
  25. package/dist/actions/RowActions.d.ts.map +1 -0
  26. package/dist/actions/RowActions.js +95 -0
  27. package/dist/actions/RowActions.js.map +1 -0
  28. package/dist/actions/actions.d.ts +23 -0
  29. package/dist/actions/actions.d.ts.map +1 -0
  30. package/dist/actions/actions.js +56 -0
  31. package/dist/actions/actions.js.map +1 -0
  32. package/dist/actions/icons.d.ts +5 -0
  33. package/dist/actions/icons.d.ts.map +1 -0
  34. package/dist/actions/icons.js +23 -0
  35. package/dist/actions/icons.js.map +1 -0
  36. package/dist/cx.d.ts +3 -0
  37. package/dist/cx.d.ts.map +1 -0
  38. package/dist/cx.js +9 -0
  39. package/dist/cx.js.map +1 -0
  40. package/dist/displays/Displays.css +71 -0
  41. package/dist/displays/Displays.module.js +30 -0
  42. package/dist/displays/Displays.module.js.map +1 -0
  43. package/dist/displays/displays.d.ts +36 -0
  44. package/dist/displays/displays.d.ts.map +1 -0
  45. package/dist/displays/displays.js +570 -0
  46. package/dist/displays/displays.js.map +1 -0
  47. package/dist/filters/Filters.css +71 -0
  48. package/dist/filters/Filters.d.ts +38 -0
  49. package/dist/filters/Filters.d.ts.map +1 -0
  50. package/dist/filters/Filters.js +240 -0
  51. package/dist/filters/Filters.js.map +1 -0
  52. package/dist/filters/Filters.module.js +24 -0
  53. package/dist/filters/Filters.module.js.map +1 -0
  54. package/dist/filters/controls.d.ts +23 -0
  55. package/dist/filters/controls.d.ts.map +1 -0
  56. package/dist/filters/controls.js +405 -0
  57. package/dist/filters/controls.js.map +1 -0
  58. package/dist/filters/format.d.ts +16 -0
  59. package/dist/filters/format.d.ts.map +1 -0
  60. package/dist/filters/format.js +43 -0
  61. package/dist/filters/format.js.map +1 -0
  62. package/dist/index.d.ts +18 -10
  63. package/dist/index.d.ts.map +1 -0
  64. package/dist/index.js +17 -66
  65. package/dist/layouts/CardsLayout.css +72 -0
  66. package/dist/layouts/CardsLayout.d.ts +4 -0
  67. package/dist/layouts/CardsLayout.d.ts.map +1 -0
  68. package/dist/layouts/CardsLayout.js +111 -0
  69. package/dist/layouts/CardsLayout.js.map +1 -0
  70. package/dist/layouts/CardsLayout.module.js +24 -0
  71. package/dist/layouts/CardsLayout.module.js.map +1 -0
  72. package/dist/layouts/ItemTitle.d.ts +10 -0
  73. package/dist/layouts/ItemTitle.d.ts.map +1 -0
  74. package/dist/layouts/ItemTitle.js +30 -0
  75. package/dist/layouts/ItemTitle.js.map +1 -0
  76. package/dist/layouts/TableLayout.css +177 -0
  77. package/dist/layouts/TableLayout.d.ts +9 -0
  78. package/dist/layouts/TableLayout.d.ts.map +1 -0
  79. package/dist/layouts/TableLayout.js +208 -0
  80. package/dist/layouts/TableLayout.js.map +1 -0
  81. package/dist/layouts/TableLayout.module.js +32 -0
  82. package/dist/layouts/TableLayout.module.js.map +1 -0
  83. package/dist/layouts/builtIn.d.ts +6 -0
  84. package/dist/layouts/builtIn.d.ts.map +1 -0
  85. package/dist/layouts/builtIn.js +12 -0
  86. package/dist/layouts/builtIn.js.map +1 -0
  87. package/dist/layouts/link.css +16 -0
  88. package/dist/layouts/link.module.js +8 -0
  89. package/dist/layouts/link.module.js.map +1 -0
  90. package/dist/messages.d.ts +2 -0
  91. package/dist/messages.d.ts.map +1 -0
  92. package/dist/messages.js +1 -0
  93. package/dist/plugin.d.ts +13 -0
  94. package/dist/plugin.d.ts.map +1 -0
  95. package/dist/plugin.js +19 -0
  96. package/dist/plugin.js.map +1 -0
  97. package/dist/query.d.ts +21 -0
  98. package/dist/query.d.ts.map +1 -0
  99. package/dist/query.js +65 -0
  100. package/dist/query.js.map +1 -0
  101. package/dist/selection.d.ts +9 -0
  102. package/dist/selection.d.ts.map +1 -0
  103. package/dist/selection.js +19 -0
  104. package/dist/selection.js.map +1 -0
  105. package/dist/toolbar/LayoutSwitch.d.ts +8 -0
  106. package/dist/toolbar/LayoutSwitch.d.ts.map +1 -0
  107. package/dist/toolbar/LayoutSwitch.js +108 -0
  108. package/dist/toolbar/LayoutSwitch.js.map +1 -0
  109. package/dist/toolbar/Pagination.d.ts +13 -0
  110. package/dist/toolbar/Pagination.d.ts.map +1 -0
  111. package/dist/toolbar/Pagination.js +62 -0
  112. package/dist/toolbar/Pagination.js.map +1 -0
  113. package/dist/toolbar/SearchField.d.ts +9 -0
  114. package/dist/toolbar/SearchField.d.ts.map +1 -0
  115. package/dist/toolbar/SearchField.js +64 -0
  116. package/dist/toolbar/SearchField.js.map +1 -0
  117. package/dist/toolbar/SortSelect.d.ts +9 -0
  118. package/dist/toolbar/SortSelect.d.ts.map +1 -0
  119. package/dist/toolbar/SortSelect.js +90 -0
  120. package/dist/toolbar/SortSelect.js.map +1 -0
  121. package/dist/toolbar/Toolbar.css +72 -0
  122. package/dist/toolbar/Toolbar.module.js +22 -0
  123. package/dist/toolbar/Toolbar.module.js.map +1 -0
  124. package/dist/types.d.ts +105 -0
  125. package/dist/types.d.ts.map +1 -0
  126. package/dist/useDraft.d.ts +11 -0
  127. package/dist/useDraft.d.ts.map +1 -0
  128. package/dist/useDraft.js +77 -0
  129. package/dist/useDraft.js.map +1 -0
  130. package/dist/useListState.d.ts +4 -0
  131. package/dist/useListState.d.ts.map +1 -0
  132. package/dist/useListState.js +10 -0
  133. package/dist/useListState.js.map +1 -0
  134. package/dist/values.d.ts +21 -0
  135. package/dist/values.d.ts.map +1 -0
  136. package/dist/values.js +52 -0
  137. package/dist/values.js.map +1 -0
  138. package/package.json +27 -57
@@ -0,0 +1,405 @@
1
+ import { messages } from "../messages.js";
2
+ import { useDraft } from "../useDraft.js";
3
+ import Filters_module_default from "./Filters.module.js";
4
+ import { c } from "react/compiler-runtime";
5
+ import { Fieldset, Select, Switch, TextInput, usePanneauIntl } from "@panneau/ui";
6
+ import { jsx, jsxs } from "react/jsx-runtime";
7
+ import { DateField } from "@panneau/fields/date";
8
+ import { RelationField } from "@panneau/fields/relation";
9
+ //#region src/filters/controls.tsx
10
+ function asStrings(value) {
11
+ if (Array.isArray(value)) return value.map(String);
12
+ return value === void 0 || value === null || value === "" ? [] : [String(value)];
13
+ }
14
+ /** A text filter: the list changes once the user stops typing. */
15
+ function TextFilter(t0) {
16
+ const $ = c(10);
17
+ const { label, value, onChange } = t0;
18
+ const current = typeof value === "string" || typeof value === "number" ? String(value) : "";
19
+ let t1;
20
+ if ($[0] !== onChange) {
21
+ t1 = (next) => onChange(next !== "" ? next : void 0);
22
+ $[0] = onChange;
23
+ $[1] = t1;
24
+ } else t1 = $[1];
25
+ const { draft, setDraft, flush } = useDraft(current, t1);
26
+ let t2;
27
+ if ($[2] !== flush) {
28
+ t2 = (event) => {
29
+ if (event.key === "Enter") flush();
30
+ };
31
+ $[2] = flush;
32
+ $[3] = t2;
33
+ } else t2 = $[3];
34
+ let t3;
35
+ if ($[4] !== draft || $[5] !== flush || $[6] !== label || $[7] !== setDraft || $[8] !== t2) {
36
+ t3 = /* @__PURE__ */ jsx(TextInput, {
37
+ label,
38
+ value: draft,
39
+ onChange: setDraft,
40
+ onKeyDown: t2,
41
+ onBlur: flush,
42
+ className: Filters_module_default.control
43
+ });
44
+ $[4] = draft;
45
+ $[5] = flush;
46
+ $[6] = label;
47
+ $[7] = setDraft;
48
+ $[8] = t2;
49
+ $[9] = t3;
50
+ } else t3 = $[9];
51
+ return t3;
52
+ }
53
+ /** A choice among the options, or several with `multiple`. */
54
+ function SelectFilter(t0) {
55
+ const $ = c(27);
56
+ const { filter, label, options, value, onChange } = t0;
57
+ const intl = usePanneauIntl();
58
+ let T0;
59
+ let t1;
60
+ let t2;
61
+ let t3;
62
+ let t4;
63
+ let t5;
64
+ if ($[0] !== filter.multiple || $[1] !== intl || $[2] !== label || $[3] !== onChange || $[4] !== options || $[5] !== value) {
65
+ t5 = Symbol.for("react.early_return_sentinel");
66
+ bb0: {
67
+ const selected = asStrings(value);
68
+ let t6;
69
+ if ($[12] !== options) {
70
+ t6 = (values) => options.filter((option) => values.includes(String(option.value))).map(_temp);
71
+ $[12] = options;
72
+ $[13] = t6;
73
+ } else t6 = $[13];
74
+ const toOptions = t6;
75
+ let t7;
76
+ if ($[14] !== intl) {
77
+ t7 = intl.formatMessage(messages.any);
78
+ $[14] = intl;
79
+ $[15] = t7;
80
+ } else t7 = $[15];
81
+ const placeholder = t7;
82
+ if (filter.multiple === true) {
83
+ let t8;
84
+ if ($[16] !== onChange) {
85
+ t8 = (next) => onChange(next.length > 0 ? next : void 0);
86
+ $[16] = onChange;
87
+ $[17] = t8;
88
+ } else t8 = $[17];
89
+ t5 = /* @__PURE__ */ jsx(Select, {
90
+ multiple: true,
91
+ label,
92
+ options,
93
+ placeholder,
94
+ value: toOptions(selected),
95
+ onChange: t8,
96
+ className: Filters_module_default.control
97
+ });
98
+ break bb0;
99
+ }
100
+ T0 = Select;
101
+ t1 = label;
102
+ t2 = options;
103
+ t3 = placeholder;
104
+ t4 = toOptions(selected)[0] ?? null;
105
+ }
106
+ $[0] = filter.multiple;
107
+ $[1] = intl;
108
+ $[2] = label;
109
+ $[3] = onChange;
110
+ $[4] = options;
111
+ $[5] = value;
112
+ $[6] = T0;
113
+ $[7] = t1;
114
+ $[8] = t2;
115
+ $[9] = t3;
116
+ $[10] = t4;
117
+ $[11] = t5;
118
+ } else {
119
+ T0 = $[6];
120
+ t1 = $[7];
121
+ t2 = $[8];
122
+ t3 = $[9];
123
+ t4 = $[10];
124
+ t5 = $[11];
125
+ }
126
+ if (t5 !== Symbol.for("react.early_return_sentinel")) return t5;
127
+ let t6;
128
+ if ($[18] !== onChange) {
129
+ t6 = (next_0) => onChange(next_0 ?? void 0);
130
+ $[18] = onChange;
131
+ $[19] = t6;
132
+ } else t6 = $[19];
133
+ let t7;
134
+ if ($[20] !== T0 || $[21] !== t1 || $[22] !== t2 || $[23] !== t3 || $[24] !== t4 || $[25] !== t6) {
135
+ t7 = /* @__PURE__ */ jsx(T0, {
136
+ label: t1,
137
+ options: t2,
138
+ placeholder: t3,
139
+ value: t4,
140
+ onChange: t6,
141
+ className: Filters_module_default.control
142
+ });
143
+ $[20] = T0;
144
+ $[21] = t1;
145
+ $[22] = t2;
146
+ $[23] = t3;
147
+ $[24] = t4;
148
+ $[25] = t6;
149
+ $[26] = t7;
150
+ } else t7 = $[26];
151
+ return t7;
152
+ }
153
+ /** On or off: on filters with `true`, off removes the filter. */
154
+ function _temp(option_0) {
155
+ return option_0.value;
156
+ }
157
+ function ToggleFilter(t0) {
158
+ const $ = c(6);
159
+ const { label, value, onChange } = t0;
160
+ const t1 = String(value) === "true";
161
+ let t2;
162
+ if ($[0] !== onChange) {
163
+ t2 = (checked) => onChange(checked ? true : void 0);
164
+ $[0] = onChange;
165
+ $[1] = t2;
166
+ } else t2 = $[1];
167
+ let t3;
168
+ if ($[2] !== label || $[3] !== t1 || $[4] !== t2) {
169
+ t3 = /* @__PURE__ */ jsx(Switch, {
170
+ isSelected: t1,
171
+ onChange: t2,
172
+ className: Filters_module_default.toggle,
173
+ children: label
174
+ });
175
+ $[2] = label;
176
+ $[3] = t1;
177
+ $[4] = t2;
178
+ $[5] = t3;
179
+ } else t3 = $[5];
180
+ return t3;
181
+ }
182
+ /** A day (`2026-10-15`). */
183
+ function DateFilter(t0) {
184
+ const $ = c(6);
185
+ const { label, value, onChange } = t0;
186
+ const t1 = typeof value === "string" && value !== "" ? value : null;
187
+ let t2;
188
+ if ($[0] !== onChange) {
189
+ t2 = (next) => onChange(next ?? void 0);
190
+ $[0] = onChange;
191
+ $[1] = t2;
192
+ } else t2 = $[1];
193
+ let t3;
194
+ if ($[2] !== label || $[3] !== t1 || $[4] !== t2) {
195
+ t3 = /* @__PURE__ */ jsx(DateField, {
196
+ label,
197
+ value: t1,
198
+ onChange: t2,
199
+ className: Filters_module_default.control
200
+ });
201
+ $[2] = label;
202
+ $[3] = t1;
203
+ $[4] = t2;
204
+ $[5] = t3;
205
+ } else t3 = $[5];
206
+ return t3;
207
+ }
208
+ /**
209
+ * A range of days, sent as `[from, to]` (`filter[published_at][]=2026-01-01&…`). An open end is an
210
+ * empty string.
211
+ */
212
+ function DateRangeFilter(t0) {
213
+ const $ = c(26);
214
+ const { label, value, onChange } = t0;
215
+ const intl = usePanneauIntl();
216
+ let t1;
217
+ if ($[0] !== value) {
218
+ t1 = asStrings(value);
219
+ $[0] = value;
220
+ $[1] = t1;
221
+ } else t1 = $[1];
222
+ const [t2, t3] = t1;
223
+ const from = t2 === void 0 ? "" : t2;
224
+ const to = t3 === void 0 ? "" : t3;
225
+ let t4;
226
+ if ($[2] !== onChange) {
227
+ t4 = (nextFrom, nextTo) => onChange(nextFrom === "" && nextTo === "" ? void 0 : [nextFrom, nextTo]);
228
+ $[2] = onChange;
229
+ $[3] = t4;
230
+ } else t4 = $[3];
231
+ const set = t4;
232
+ let t5;
233
+ if ($[4] !== intl) {
234
+ t5 = intl.formatMessage(messages.from);
235
+ $[4] = intl;
236
+ $[5] = t5;
237
+ } else t5 = $[5];
238
+ const t6 = from !== "" ? from : null;
239
+ let t7;
240
+ if ($[6] !== set || $[7] !== to) {
241
+ t7 = (next) => set(next ?? "", to);
242
+ $[6] = set;
243
+ $[7] = to;
244
+ $[8] = t7;
245
+ } else t7 = $[8];
246
+ let t8;
247
+ if ($[9] !== t5 || $[10] !== t6 || $[11] !== t7) {
248
+ t8 = /* @__PURE__ */ jsx(DateField, {
249
+ label: t5,
250
+ value: t6,
251
+ onChange: t7
252
+ });
253
+ $[9] = t5;
254
+ $[10] = t6;
255
+ $[11] = t7;
256
+ $[12] = t8;
257
+ } else t8 = $[12];
258
+ let t9;
259
+ if ($[13] !== intl) {
260
+ t9 = intl.formatMessage(messages.to);
261
+ $[13] = intl;
262
+ $[14] = t9;
263
+ } else t9 = $[14];
264
+ const t10 = to !== "" ? to : null;
265
+ let t11;
266
+ if ($[15] !== from || $[16] !== set) {
267
+ t11 = (next_0) => set(from, next_0 ?? "");
268
+ $[15] = from;
269
+ $[16] = set;
270
+ $[17] = t11;
271
+ } else t11 = $[17];
272
+ let t12;
273
+ if ($[18] !== t10 || $[19] !== t11 || $[20] !== t9) {
274
+ t12 = /* @__PURE__ */ jsx(DateField, {
275
+ label: t9,
276
+ value: t10,
277
+ onChange: t11
278
+ });
279
+ $[18] = t10;
280
+ $[19] = t11;
281
+ $[20] = t9;
282
+ $[21] = t12;
283
+ } else t12 = $[21];
284
+ let t13;
285
+ if ($[22] !== label || $[23] !== t12 || $[24] !== t8) {
286
+ t13 = /* @__PURE__ */ jsxs(Fieldset, {
287
+ legend: label,
288
+ className: Filters_module_default.range,
289
+ children: [t8, t12]
290
+ });
291
+ $[22] = label;
292
+ $[23] = t12;
293
+ $[24] = t8;
294
+ $[25] = t13;
295
+ } else t13 = $[25];
296
+ return t13;
297
+ }
298
+ /**
299
+ * An item of another resource (`resource`), or several with `multiple`, picked with the relation
300
+ * source of the fields context. The filter keeps their ids; their labels are remembered for the
301
+ * chips.
302
+ */
303
+ function RelationFilter(t0) {
304
+ const $ = c(23);
305
+ const { filter, label, value, onChange, onLabel, getValueLabel } = t0;
306
+ let t1;
307
+ if ($[0] !== getValueLabel || $[1] !== value) {
308
+ let t2;
309
+ if ($[3] !== getValueLabel) {
310
+ t2 = (id) => ({
311
+ id,
312
+ label: getValueLabel(id) ?? id
313
+ });
314
+ $[3] = getValueLabel;
315
+ $[4] = t2;
316
+ } else t2 = $[4];
317
+ t1 = asStrings(value).map(t2);
318
+ $[0] = getValueLabel;
319
+ $[1] = value;
320
+ $[2] = t1;
321
+ } else t1 = $[2];
322
+ const references = t1;
323
+ let t2;
324
+ if ($[5] !== onLabel) {
325
+ t2 = (next) => next.forEach((reference) => onLabel(reference.id, reference.label));
326
+ $[5] = onLabel;
327
+ $[6] = t2;
328
+ } else t2 = $[6];
329
+ const remember = t2;
330
+ if (filter.multiple === true) {
331
+ const t3 = filter.resource ?? filter.id;
332
+ let t4;
333
+ if ($[7] !== onChange || $[8] !== remember) {
334
+ t4 = (next_0) => {
335
+ remember(next_0 ?? []);
336
+ const ids = next_0 !== null && next_0.length > 0 ? next_0.map(_temp2) : void 0;
337
+ onChange(ids);
338
+ };
339
+ $[7] = onChange;
340
+ $[8] = remember;
341
+ $[9] = t4;
342
+ } else t4 = $[9];
343
+ let t5;
344
+ if ($[10] !== label || $[11] !== references || $[12] !== t3 || $[13] !== t4) {
345
+ t5 = /* @__PURE__ */ jsx(RelationField, {
346
+ multiple: true,
347
+ label,
348
+ resource: t3,
349
+ value: references,
350
+ onChange: t4,
351
+ className: Filters_module_default.control
352
+ });
353
+ $[10] = label;
354
+ $[11] = references;
355
+ $[12] = t3;
356
+ $[13] = t4;
357
+ $[14] = t5;
358
+ } else t5 = $[14];
359
+ return t5;
360
+ }
361
+ const t3 = filter.resource ?? filter.id;
362
+ const t4 = references[0] ?? null;
363
+ let t5;
364
+ if ($[15] !== onChange || $[16] !== remember) {
365
+ t5 = (next_1) => {
366
+ remember(next_1 !== null ? [next_1] : []);
367
+ onChange(next_1?.id);
368
+ };
369
+ $[15] = onChange;
370
+ $[16] = remember;
371
+ $[17] = t5;
372
+ } else t5 = $[17];
373
+ let t6;
374
+ if ($[18] !== label || $[19] !== t3 || $[20] !== t4 || $[21] !== t5) {
375
+ t6 = /* @__PURE__ */ jsx(RelationField, {
376
+ label,
377
+ resource: t3,
378
+ value: t4,
379
+ onChange: t5,
380
+ className: Filters_module_default.control
381
+ });
382
+ $[18] = label;
383
+ $[19] = t3;
384
+ $[20] = t4;
385
+ $[21] = t5;
386
+ $[22] = t6;
387
+ } else t6 = $[22];
388
+ return t6;
389
+ }
390
+ /** The built-in filter controls, by filter type. Unknown types are text filters. */
391
+ function _temp2(reference_0) {
392
+ return reference_0.id;
393
+ }
394
+ var builtInFilters = {
395
+ text: TextFilter,
396
+ select: SelectFilter,
397
+ toggle: ToggleFilter,
398
+ date: DateFilter,
399
+ "date-range": DateRangeFilter,
400
+ relation: RelationFilter
401
+ };
402
+ //#endregion
403
+ export { DateFilter, DateRangeFilter, RelationFilter, SelectFilter, TextFilter, ToggleFilter, builtInFilters };
404
+
405
+ //# sourceMappingURL=controls.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"controls.js","names":["label","draft","setDraft","flush","options","placeholder","option","next","references","reference","_c","styles"],"sources":["../../src/filters/controls.tsx"],"sourcesContent":["import { DateField } from '@panneau/fields/date';\nimport { RelationField } from '@panneau/fields/relation';\nimport type { FilterValue } from '@panneau/protocol';\nimport { Fieldset, type OptionValue, Select, Switch, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { FilterControlProps, FilterEntry } from '../types';\nimport { useDraft } from '../useDraft';\nimport styles from './Filters.module.css';\n\nfunction asStrings(value: unknown): string[] {\n if (Array.isArray(value)) {\n return value.map(String);\n }\n return value === undefined || value === null || value === '' ? [] : [String(value)];\n}\n\n/** A text filter: the list changes once the user stops typing. */\nexport function TextFilter({ label, value, onChange }: FilterControlProps) {\n const current = typeof value === 'string' || typeof value === 'number' ? String(value) : '';\n const { draft, setDraft, flush } = useDraft(current, (next) =>\n onChange(next !== '' ? next : undefined),\n );\n return (\n <TextInput\n label={label}\n value={draft}\n onChange={setDraft}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n flush();\n }\n }}\n onBlur={flush}\n className={styles.control}\n />\n );\n}\n\n/** A choice among the options, or several with `multiple`. */\nexport function SelectFilter({ filter, label, options, value, onChange }: FilterControlProps) {\n const intl = usePanneauIntl();\n const selected = asStrings(value);\n // Values from the URL are strings: match them to the options' values.\n const toOptions = (values: readonly string[]): OptionValue[] =>\n options\n .filter((option) => values.includes(String(option.value)))\n .map((option) => option.value);\n const placeholder = intl.formatMessage(messages.any);\n if (filter.multiple === true) {\n return (\n <Select\n multiple\n label={label}\n options={options}\n placeholder={placeholder}\n value={toOptions(selected)}\n onChange={(next) => onChange(next.length > 0 ? next : undefined)}\n className={styles.control}\n />\n );\n }\n return (\n <Select\n label={label}\n options={options}\n placeholder={placeholder}\n value={toOptions(selected)[0] ?? null}\n onChange={(next) => onChange(next ?? undefined)}\n className={styles.control}\n />\n );\n}\n\n/** On or off: on filters with `true`, off removes the filter. */\nexport function ToggleFilter({ label, value, onChange }: FilterControlProps) {\n return (\n <Switch\n isSelected={String(value) === 'true'}\n onChange={(checked) => onChange(checked ? true : undefined)}\n className={styles.toggle}\n >\n {label}\n </Switch>\n );\n}\n\n/** A day (`2026-10-15`). */\nexport function DateFilter({ label, value, onChange }: FilterControlProps) {\n return (\n <DateField\n label={label}\n value={typeof value === 'string' && value !== '' ? value : null}\n onChange={(next) => onChange(next ?? undefined)}\n className={styles.control}\n />\n );\n}\n\n/**\n * A range of days, sent as `[from, to]` (`filter[published_at][]=2026-01-01&…`). An open end is an\n * empty string.\n */\nexport function DateRangeFilter({ label, value, onChange }: FilterControlProps) {\n const intl = usePanneauIntl();\n const [from = '', to = ''] = asStrings(value);\n const set = (nextFrom: string, nextTo: string) =>\n onChange(nextFrom === '' && nextTo === '' ? undefined : [nextFrom, nextTo]);\n return (\n <Fieldset legend={label} className={styles.range}>\n <DateField\n label={intl.formatMessage(messages.from)}\n value={from !== '' ? from : null}\n onChange={(next) => set(next ?? '', to)}\n />\n <DateField\n label={intl.formatMessage(messages.to)}\n value={to !== '' ? to : null}\n onChange={(next) => set(from, next ?? '')}\n />\n </Fieldset>\n );\n}\n\n/**\n * An item of another resource (`resource`), or several with `multiple`, picked with the relation\n * source of the fields context. The filter keeps their ids; their labels are remembered for the\n * chips.\n */\nexport function RelationFilter({\n filter,\n label,\n value,\n onChange,\n onLabel,\n getValueLabel,\n}: FilterControlProps) {\n const references = asStrings(value).map((id) => ({ id, label: getValueLabel(id) ?? id }));\n const remember = (next: readonly { id: string; label: string }[]) =>\n next.forEach((reference) => onLabel(reference.id, reference.label));\n if (filter.multiple === true) {\n return (\n <RelationField\n multiple\n label={label}\n resource={filter.resource ?? filter.id}\n value={references}\n onChange={(next) => {\n remember(next ?? []);\n const ids: FilterValue | undefined =\n next !== null && next.length > 0\n ? next.map((reference) => reference.id)\n : undefined;\n onChange(ids);\n }}\n className={styles.control}\n />\n );\n }\n return (\n <RelationField\n label={label}\n resource={filter.resource ?? filter.id}\n value={references[0] ?? null}\n onChange={(next) => {\n remember(next !== null ? [next] : []);\n onChange(next?.id);\n }}\n className={styles.control}\n />\n );\n}\n\n/** The built-in filter controls, by filter type. Unknown types are text filters. */\nexport const builtInFilters: Readonly<Record<string, FilterEntry>> = {\n text: TextFilter,\n select: SelectFilter,\n toggle: ToggleFilter,\n date: DateFilter,\n 'date-range': DateRangeFilter,\n relation: RelationFilter,\n};\n"],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { IntlShape } from 'react-intl';
2
+ import type { Field, Filter, Option } from '@panneau/protocol';
3
+ import type { ListColumn } from '../types';
4
+ /** The label of a filter: its `label`, the label of its field, or its id. */
5
+ export declare function getFilterLabel(filter: Filter, columns: readonly ListColumn[], fields: readonly Field[]): string;
6
+ /** The field a filter filters, when a column or the list's fields have one with its id. */
7
+ export declare function findFilterField(filter: Filter, columns: readonly ListColumn[], fields: readonly Field[]): Field | null;
8
+ /** The options of a filter: its own, or those of the field it filters. */
9
+ export declare function getFilterOptions(filter: Filter, columns: readonly ListColumn[], fields: readonly Field[]): readonly Option[];
10
+ /** The value of an active filter, as the text of its chip. */
11
+ export declare function formatFilterValue(filter: Filter, value: unknown, { intl, options, getValueLabel, }: {
12
+ intl: IntlShape;
13
+ options: readonly Option[];
14
+ getValueLabel: (value: string) => string | null;
15
+ }): string;
16
+ //# sourceMappingURL=format.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.d.ts","sourceRoot":"","sources":["../../src/filters/format.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAE5C,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAG/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,6EAA6E;AAC7E,wBAAgB,cAAc,CAC1B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,GACzB,MAAM,CAMR;AAED,2FAA2F;AAC3F,wBAAgB,eAAe,CAC3B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,GACzB,KAAK,GAAG,IAAI,CAMd;AAED,0EAA0E;AAC1E,wBAAgB,gBAAgB,CAC5B,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,SAAS,UAAU,EAAE,EAC9B,MAAM,EAAE,SAAS,KAAK,EAAE,GACzB,SAAS,MAAM,EAAE,CAEnB;AAcD,8DAA8D;AAC9D,wBAAgB,iBAAiB,CAC7B,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,OAAO,EACd,EACI,IAAI,EACJ,OAAO,EACP,aAAa,GAChB,EAAE;IACC,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,aAAa,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,MAAM,GAAG,IAAI,CAAC;CACnD,GACF,MAAM,CAqBR"}
@@ -0,0 +1,43 @@
1
+ import { messages } from "../messages.js";
2
+ import { getFieldOptions, getOptionLabel } from "../values.js";
3
+ //#region src/filters/format.ts
4
+ /** The label of a filter: its `label`, the label of its field, or its id. */
5
+ function getFilterLabel(filter, columns, fields) {
6
+ if (filter.label !== void 0) return filter.label;
7
+ return findFilterField(filter, columns, fields)?.label ?? filter.id;
8
+ }
9
+ /** The field a filter filters, when a column or the list's fields have one with its id. */
10
+ function findFilterField(filter, columns, fields) {
11
+ return fields.find((field) => field.name === filter.id) ?? columns.find((column) => column.field?.name === filter.id)?.field ?? null;
12
+ }
13
+ /** The options of a filter: its own, or those of the field it filters. */
14
+ function getFilterOptions(filter, columns, fields) {
15
+ return filter.options ?? getFieldOptions(findFilterField(filter, columns, fields));
16
+ }
17
+ var DATE_ONLY = /^(\d{4})-(\d{2})-(\d{2})$/;
18
+ function formatDay(value, intl) {
19
+ const match = DATE_ONLY.exec(value);
20
+ if (match === null) return value;
21
+ return intl.formatDate(new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])), { dateStyle: "medium" });
22
+ }
23
+ /** The value of an active filter, as the text of its chip. */
24
+ function formatFilterValue(filter, value, { intl, options, getValueLabel }) {
25
+ const values = Array.isArray(value) ? value : [value];
26
+ switch (filter.type) {
27
+ case "toggle": return intl.formatMessage(String(value) === "true" ? messages.yes : messages.no);
28
+ case "date": return formatDay(String(value), intl);
29
+ case "date-range": {
30
+ const [from = "", to = ""] = values.map(String);
31
+ return intl.formatMessage(messages.dateRange, {
32
+ from: from !== "" ? formatDay(from, intl) : "…",
33
+ to: to !== "" ? formatDay(to, intl) : "…"
34
+ });
35
+ }
36
+ case "relation": return values.map((entry) => getValueLabel(String(entry)) ?? String(entry)).join(", ");
37
+ default: return values.map((entry) => getOptionLabel(options, entry) ?? String(entry)).join(", ");
38
+ }
39
+ }
40
+ //#endregion
41
+ export { findFilterField, formatFilterValue, getFilterLabel, getFilterOptions };
42
+
43
+ //# sourceMappingURL=format.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"format.js","names":[],"sources":["../../src/filters/format.ts"],"sourcesContent":["import type { IntlShape } from 'react-intl';\n\nimport type { Field, Filter, Option } from '@panneau/protocol';\n\nimport { messages } from '../messages';\nimport type { ListColumn } from '../types';\nimport { getFieldOptions, getOptionLabel } from '../values';\n\n/** The label of a filter: its `label`, the label of its field, or its id. */\nexport function getFilterLabel(\n filter: Filter,\n columns: readonly ListColumn[],\n fields: readonly Field[],\n): string {\n if (filter.label !== undefined) {\n return filter.label;\n }\n const field = findFilterField(filter, columns, fields);\n return field?.label ?? filter.id;\n}\n\n/** The field a filter filters, when a column or the list's fields have one with its id. */\nexport function findFilterField(\n filter: Filter,\n columns: readonly ListColumn[],\n fields: readonly Field[],\n): Field | null {\n return (\n fields.find((field) => field.name === filter.id) ??\n columns.find((column) => column.field?.name === filter.id)?.field ??\n null\n );\n}\n\n/** The options of a filter: its own, or those of the field it filters. */\nexport function getFilterOptions(\n filter: Filter,\n columns: readonly ListColumn[],\n fields: readonly Field[],\n): readonly Option[] {\n return filter.options ?? getFieldOptions(findFilterField(filter, columns, fields));\n}\n\nconst DATE_ONLY = /^(\\d{4})-(\\d{2})-(\\d{2})$/;\n\nfunction formatDay(value: string, intl: IntlShape): string {\n const match = DATE_ONLY.exec(value);\n if (match === null) {\n return value;\n }\n return intl.formatDate(new Date(Number(match[1]), Number(match[2]) - 1, Number(match[3])), {\n dateStyle: 'medium',\n });\n}\n\n/** The value of an active filter, as the text of its chip. */\nexport function formatFilterValue(\n filter: Filter,\n value: unknown,\n {\n intl,\n options,\n getValueLabel,\n }: {\n intl: IntlShape;\n options: readonly Option[];\n getValueLabel: (value: string) => string | null;\n },\n): string {\n const values: unknown[] = Array.isArray(value) ? value : [value];\n switch (filter.type) {\n case 'toggle':\n return intl.formatMessage(String(value) === 'true' ? messages.yes : messages.no);\n case 'date':\n return formatDay(String(value), intl);\n case 'date-range': {\n const [from = '', to = ''] = values.map(String);\n return intl.formatMessage(messages.dateRange, {\n from: from !== '' ? formatDay(from, intl) : '…',\n to: to !== '' ? formatDay(to, intl) : '…',\n });\n }\n case 'relation':\n return values.map((entry) => getValueLabel(String(entry)) ?? String(entry)).join(', ');\n default:\n return values\n .map((entry) => getOptionLabel(options, entry) ?? String(entry))\n .join(', ');\n }\n}\n"],"mappings":";;;;AASA,SAAgB,eACZ,QACA,SACA,QACM;CACN,IAAI,OAAO,UAAU,KAAA,GACjB,OAAO,OAAO;CAGlB,OADc,gBAAgB,QAAQ,SAAS,MACxC,CAAA,EAAO,SAAS,OAAO;AAClC;;AAGA,SAAgB,gBACZ,QACA,SACA,QACY;CACZ,OACI,OAAO,MAAM,UAAU,MAAM,SAAS,OAAO,EAAE,KAC/C,QAAQ,MAAM,WAAW,OAAO,OAAO,SAAS,OAAO,EAAE,CAAC,EAAE,SAC5D;AAER;;AAGA,SAAgB,iBACZ,QACA,SACA,QACiB;CACjB,OAAO,OAAO,WAAW,gBAAgB,gBAAgB,QAAQ,SAAS,MAAM,CAAC;AACrF;AAEA,IAAM,YAAY;AAElB,SAAS,UAAU,OAAe,MAAyB;CACvD,MAAM,QAAQ,UAAU,KAAK,KAAK;CAClC,IAAI,UAAU,MACV,OAAO;CAEX,OAAO,KAAK,WAAW,IAAI,KAAK,OAAO,MAAM,EAAE,GAAG,OAAO,MAAM,EAAE,IAAI,GAAG,OAAO,MAAM,EAAE,CAAC,GAAG,EACvF,WAAW,SACf,CAAC;AACL;;AAGA,SAAgB,kBACZ,QACA,OACA,EACI,MACA,SACA,iBAME;CACN,MAAM,SAAoB,MAAM,QAAQ,KAAK,IAAI,QAAQ,CAAC,KAAK;CAC/D,QAAQ,OAAO,MAAf;EACI,KAAK,UACD,OAAO,KAAK,cAAc,OAAO,KAAK,MAAM,SAAS,SAAS,MAAM,SAAS,EAAE;EACnF,KAAK,QACD,OAAO,UAAU,OAAO,KAAK,GAAG,IAAI;EACxC,KAAK,cAAc;GACf,MAAM,CAAC,OAAO,IAAI,KAAK,MAAM,OAAO,IAAI,MAAM;GAC9C,OAAO,KAAK,cAAc,SAAS,WAAW;IAC1C,MAAM,SAAS,KAAK,UAAU,MAAM,IAAI,IAAI;IAC5C,IAAI,OAAO,KAAK,UAAU,IAAI,IAAI,IAAI;GAC1C,CAAC;EACL;EACA,KAAK,YACD,OAAO,OAAO,KAAK,UAAU,cAAc,OAAO,KAAK,CAAC,KAAK,OAAO,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;EACzF,SACI,OAAO,OACF,KAAK,UAAU,eAAe,SAAS,KAAK,KAAK,OAAO,KAAK,CAAC,CAAC,CAC/D,KAAK,IAAI;CACtB;AACJ"}
package/dist/index.d.ts CHANGED
@@ -1,10 +1,18 @@
1
- import * as react from 'react';
2
- import { ReactNode } from 'react';
3
-
4
- interface ListsProviderProps {
5
- components?: Record<string, unknown> | null;
6
- children?: ReactNode;
7
- }
8
- declare function ListsProvider({ components: injectedComponents, children, ...props }: ListsProviderProps): react.JSX.Element;
9
-
10
- export { ListsProvider as default };
1
+ export { type ListActions, getActionHref, groupListActions, isAllowedOn } from './actions/actions';
2
+ export { ConfirmDialog, type ConfirmDialogProps } from './actions/ConfirmDialog';
3
+ export { BooleanDisplay, ColorDisplay, DateDisplay, DateTimeDisplay, EmailDisplay, EmptyValue, MediaDisplay, NumberDisplay, RelationDisplay, RichTextDisplay, SelectDisplay, TextDisplay, TimeDisplay, UrlDisplay, builtInDisplays, } from './displays/displays';
4
+ export { DateFilter, DateRangeFilter, RelationFilter, SelectFilter, TextFilter, ToggleFilter, builtInFilters, } from './filters/controls';
5
+ export { CardsLayout } from './layouts/CardsLayout';
6
+ export { TableLayout } from './layouts/TableLayout';
7
+ export { builtInLayouts } from './layouts/builtIn';
8
+ export { List, type ListProps } from './List';
9
+ export { ListView, type ListViewProps } from './ListView';
10
+ export { listsPlugin } from './plugin';
11
+ export { type LocalQueryOptions, type LocalQueryResult, applyListQuery } from './query';
12
+ export { countSelected, getPageSelection, isItemSelected } from './selection';
13
+ export { Pagination, type PaginationProps } from './toolbar/Pagination';
14
+ export { SearchField, type SearchFieldProps } from './toolbar/SearchField';
15
+ export type { DisplayEntry, DisplayProps, FilterControlProps, FilterEntry, ListActionEvent, ListActionHandler, ListColumn, ListItem, ListLayoutEntry, ListLayoutProps, } from './types';
16
+ export { useListState } from './useListState';
17
+ export { getLocalizedValue, toText } from './values';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,gBAAgB,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AACnG,OAAO,EAAE,aAAa,EAAE,KAAK,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AACjF,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,aAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,eAAe,GAClB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACH,UAAU,EACV,eAAe,EACf,cAAc,EACd,YAAY,EACZ,UAAU,EACV,YAAY,EACZ,cAAc,GACjB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,KAAK,SAAS,EAAE,MAAM,QAAQ,CAAC;AAC9C,OAAO,EAAE,QAAQ,EAAE,KAAK,aAAa,EAAE,MAAM,YAAY,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AACxF,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,UAAU,EAAE,KAAK,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACxE,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;AAC3E,YAAY,EACR,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,WAAW,EACX,eAAe,EACf,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,eAAe,EACf,eAAe,GAClB,MAAM,SAAS,CAAC;AACjB,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC"}
package/dist/index.js CHANGED
@@ -1,66 +1,17 @@
1
- import { c } from 'react/compiler-runtime';
2
- import { ComponentsProvider, LISTS_NAMESPACE } from '@panneau/core/contexts';
3
- import listTable from '@panneau/list-table';
4
- import listCards from '@panneau/list-cards';
5
- import listCalendar from '@panneau/list-calendar';
6
- import { jsx } from 'react/jsx-runtime';
7
-
8
- var components = /*#__PURE__*/Object.freeze({
9
- __proto__: null,
10
- Calendar: listCalendar,
11
- Cards: listCards,
12
- Table: listTable
13
- });
14
-
15
- function ListsProvider(t0) {
16
- const $ = c(10);
17
- let props;
18
- let t1;
19
- let t2;
20
- if ($[0] !== t0) {
21
- ({
22
- components: t1,
23
- children: t2,
24
- ...props
25
- } = t0);
26
- $[0] = t0;
27
- $[1] = props;
28
- $[2] = t1;
29
- $[3] = t2;
30
- } else {
31
- props = $[1];
32
- t1 = $[2];
33
- t2 = $[3];
34
- }
35
- const injectedComponents = t1 === undefined ? null : t1;
36
- const children = t2 === undefined ? null : t2;
37
- let t3;
38
- if ($[4] !== injectedComponents) {
39
- t3 = {
40
- ...components,
41
- ...injectedComponents
42
- };
43
- $[4] = injectedComponents;
44
- $[5] = t3;
45
- } else {
46
- t3 = $[5];
47
- }
48
- let t4;
49
- if ($[6] !== children || $[7] !== props || $[8] !== t3) {
50
- t4 = /*#__PURE__*/jsx(ComponentsProvider, {
51
- namespace: LISTS_NAMESPACE,
52
- components: t3,
53
- ...props,
54
- children: children
55
- });
56
- $[6] = children;
57
- $[7] = props;
58
- $[8] = t3;
59
- $[9] = t4;
60
- } else {
61
- t4 = $[9];
62
- }
63
- return t4;
64
- }
65
-
66
- export { ListsProvider as default };
1
+ import { getActionHref, groupListActions, isAllowedOn } from "./actions/actions.js";
2
+ import { ConfirmDialog } from "./actions/ConfirmDialog.js";
3
+ import { getLocalizedValue, toText } from "./values.js";
4
+ import { BooleanDisplay, ColorDisplay, DateDisplay, DateTimeDisplay, EmailDisplay, EmptyValue, MediaDisplay, NumberDisplay, RelationDisplay, RichTextDisplay, SelectDisplay, TextDisplay, TimeDisplay, UrlDisplay, builtInDisplays } from "./displays/displays.js";
5
+ import { DateFilter, DateRangeFilter, RelationFilter, SelectFilter, TextFilter, ToggleFilter, builtInFilters } from "./filters/controls.js";
6
+ import { CardsLayout } from "./layouts/CardsLayout.js";
7
+ import { TableLayout } from "./layouts/TableLayout.js";
8
+ import { builtInLayouts } from "./layouts/builtIn.js";
9
+ import { countSelected, getPageSelection, isItemSelected } from "./selection.js";
10
+ import { Pagination } from "./toolbar/Pagination.js";
11
+ import { SearchField } from "./toolbar/SearchField.js";
12
+ import { useListState } from "./useListState.js";
13
+ import { ListView } from "./ListView.js";
14
+ import { applyListQuery } from "./query.js";
15
+ import { List } from "./List.js";
16
+ import { listsPlugin } from "./plugin.js";
17
+ export { BooleanDisplay, CardsLayout, ColorDisplay, ConfirmDialog, DateDisplay, DateFilter, DateRangeFilter, DateTimeDisplay, EmailDisplay, EmptyValue, List, ListView, MediaDisplay, NumberDisplay, Pagination, RelationDisplay, RelationFilter, RichTextDisplay, SearchField, SelectDisplay, SelectFilter, TableLayout, TextDisplay, TextFilter, TimeDisplay, ToggleFilter, UrlDisplay, applyListQuery, builtInDisplays, builtInFilters, builtInLayouts, countSelected, getActionHref, getLocalizedValue, getPageSelection, groupListActions, isAllowedOn, isItemSelected, listsPlugin, toText, useListState };