@panneau/lists 4.1.1 → 5.0.0-alpha.1
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 +116 -0
- package/dist/List.d.ts +26 -0
- package/dist/List.d.ts.map +1 -0
- package/dist/List.js +38 -0
- package/dist/List.js.map +1 -0
- package/dist/ListView.css +101 -0
- package/dist/ListView.d.ts +76 -0
- package/dist/ListView.d.ts.map +1 -0
- package/dist/ListView.js +325 -0
- package/dist/ListView.js.map +1 -0
- package/dist/ListView.module.js +28 -0
- package/dist/ListView.module.js.map +1 -0
- package/dist/actions/ActionButton.d.ts +18 -0
- package/dist/actions/ActionButton.d.ts.map +1 -0
- package/dist/actions/ActionButton.js +34 -0
- package/dist/actions/ActionButton.js.map +1 -0
- package/dist/actions/Actions.css +58 -0
- package/dist/actions/Actions.module.js +20 -0
- package/dist/actions/Actions.module.js.map +1 -0
- package/dist/actions/ConfirmDialog.d.ts +15 -0
- package/dist/actions/ConfirmDialog.d.ts.map +1 -0
- package/dist/actions/ConfirmDialog.js +157 -0
- package/dist/actions/ConfirmDialog.js.map +1 -0
- package/dist/actions/RowActions.d.ts +20 -0
- package/dist/actions/RowActions.d.ts.map +1 -0
- package/dist/actions/RowActions.js +99 -0
- package/dist/actions/RowActions.js.map +1 -0
- package/dist/actions/actions.d.ts +23 -0
- package/dist/actions/actions.d.ts.map +1 -0
- package/dist/actions/actions.js +56 -0
- package/dist/actions/actions.js.map +1 -0
- package/dist/actions/icons.d.ts +10 -0
- package/dist/actions/icons.d.ts.map +1 -0
- package/dist/actions/icons.js +27 -0
- package/dist/actions/icons.js.map +1 -0
- package/dist/cx.d.ts +3 -0
- package/dist/cx.d.ts.map +1 -0
- package/dist/cx.js +9 -0
- package/dist/cx.js.map +1 -0
- package/dist/displays/Displays.css +71 -0
- package/dist/displays/Displays.module.js +30 -0
- package/dist/displays/Displays.module.js.map +1 -0
- package/dist/displays/displays.d.ts +36 -0
- package/dist/displays/displays.d.ts.map +1 -0
- package/dist/displays/displays.js +570 -0
- package/dist/displays/displays.js.map +1 -0
- package/dist/filters/Filters.css +71 -0
- package/dist/filters/Filters.d.ts +38 -0
- package/dist/filters/Filters.d.ts.map +1 -0
- package/dist/filters/Filters.js +240 -0
- package/dist/filters/Filters.js.map +1 -0
- package/dist/filters/Filters.module.js +24 -0
- package/dist/filters/Filters.module.js.map +1 -0
- package/dist/filters/controls.d.ts +23 -0
- package/dist/filters/controls.d.ts.map +1 -0
- package/dist/filters/controls.js +431 -0
- package/dist/filters/controls.js.map +1 -0
- package/dist/filters/format.d.ts +16 -0
- package/dist/filters/format.d.ts.map +1 -0
- package/dist/filters/format.js +46 -0
- package/dist/filters/format.js.map +1 -0
- package/dist/index.d.ts +19 -10
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +18 -66
- package/dist/layouts/CardsLayout.css +72 -0
- package/dist/layouts/CardsLayout.d.ts +4 -0
- package/dist/layouts/CardsLayout.d.ts.map +1 -0
- package/dist/layouts/CardsLayout.js +111 -0
- package/dist/layouts/CardsLayout.js.map +1 -0
- package/dist/layouts/CardsLayout.module.js +24 -0
- package/dist/layouts/CardsLayout.module.js.map +1 -0
- package/dist/layouts/ItemTitle.d.ts +10 -0
- package/dist/layouts/ItemTitle.d.ts.map +1 -0
- package/dist/layouts/ItemTitle.js +30 -0
- package/dist/layouts/ItemTitle.js.map +1 -0
- package/dist/layouts/TableLayout.css +177 -0
- package/dist/layouts/TableLayout.d.ts +9 -0
- package/dist/layouts/TableLayout.d.ts.map +1 -0
- package/dist/layouts/TableLayout.js +208 -0
- package/dist/layouts/TableLayout.js.map +1 -0
- package/dist/layouts/TableLayout.module.js +32 -0
- package/dist/layouts/TableLayout.module.js.map +1 -0
- package/dist/layouts/builtIn.d.ts +6 -0
- package/dist/layouts/builtIn.d.ts.map +1 -0
- package/dist/layouts/builtIn.js +12 -0
- package/dist/layouts/builtIn.js.map +1 -0
- package/dist/layouts/link.css +16 -0
- package/dist/layouts/link.module.js +8 -0
- package/dist/layouts/link.module.js.map +1 -0
- package/dist/messages.d.ts +2 -0
- package/dist/messages.d.ts.map +1 -0
- package/dist/messages.js +1 -0
- package/dist/plugin.d.ts +13 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +19 -0
- package/dist/plugin.js.map +1 -0
- package/dist/query.d.ts +21 -0
- package/dist/query.d.ts.map +1 -0
- package/dist/query.js +70 -0
- package/dist/query.js.map +1 -0
- package/dist/selection.d.ts +9 -0
- package/dist/selection.d.ts.map +1 -0
- package/dist/selection.js +19 -0
- package/dist/selection.js.map +1 -0
- package/dist/toolbar/LayoutSwitch.d.ts +8 -0
- package/dist/toolbar/LayoutSwitch.d.ts.map +1 -0
- package/dist/toolbar/LayoutSwitch.js +108 -0
- package/dist/toolbar/LayoutSwitch.js.map +1 -0
- package/dist/toolbar/Pagination.d.ts +13 -0
- package/dist/toolbar/Pagination.d.ts.map +1 -0
- package/dist/toolbar/Pagination.js +62 -0
- package/dist/toolbar/Pagination.js.map +1 -0
- package/dist/toolbar/SearchField.d.ts +9 -0
- package/dist/toolbar/SearchField.d.ts.map +1 -0
- package/dist/toolbar/SearchField.js +64 -0
- package/dist/toolbar/SearchField.js.map +1 -0
- package/dist/toolbar/SortSelect.d.ts +9 -0
- package/dist/toolbar/SortSelect.d.ts.map +1 -0
- package/dist/toolbar/SortSelect.js +90 -0
- package/dist/toolbar/SortSelect.js.map +1 -0
- package/dist/toolbar/Toolbar.css +72 -0
- package/dist/toolbar/Toolbar.module.js +22 -0
- package/dist/toolbar/Toolbar.module.js.map +1 -0
- package/dist/types.d.ts +106 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/useDraft.d.ts +11 -0
- package/dist/useDraft.d.ts.map +1 -0
- package/dist/useDraft.js +77 -0
- package/dist/useDraft.js.map +1 -0
- package/dist/useListState.d.ts +4 -0
- package/dist/useListState.d.ts.map +1 -0
- package/dist/useListState.js +10 -0
- package/dist/useListState.js.map +1 -0
- package/dist/values.d.ts +21 -0
- package/dist/values.d.ts.map +1 -0
- package/dist/values.js +52 -0
- package/dist/values.js.map +1 -0
- package/package.json +27 -57
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { messages } from "../messages.js";
|
|
2
|
+
import { useDraft } from "../useDraft.js";
|
|
3
|
+
import Toolbar_module_default from "./Toolbar.module.js";
|
|
4
|
+
import { c } from "react/compiler-runtime";
|
|
5
|
+
import { Icon, TextInput, usePanneauIntl } from "@panneau/ui";
|
|
6
|
+
import { jsx } from "react/jsx-runtime";
|
|
7
|
+
import { Search } from "lucide-react";
|
|
8
|
+
//#region src/toolbar/SearchField.tsx
|
|
9
|
+
/** The search of a list (`q`). */
|
|
10
|
+
function SearchField(t0) {
|
|
11
|
+
const $ = c(13);
|
|
12
|
+
const { value, onChange } = t0;
|
|
13
|
+
const intl = usePanneauIntl();
|
|
14
|
+
const { draft, setDraft, flush } = useDraft(value, onChange);
|
|
15
|
+
let t1;
|
|
16
|
+
if ($[0] !== intl) {
|
|
17
|
+
t1 = intl.formatMessage(messages.search);
|
|
18
|
+
$[0] = intl;
|
|
19
|
+
$[1] = t1;
|
|
20
|
+
} else t1 = $[1];
|
|
21
|
+
let t2;
|
|
22
|
+
if ($[2] !== intl) {
|
|
23
|
+
t2 = intl.formatMessage(messages.searchPlaceholder);
|
|
24
|
+
$[2] = intl;
|
|
25
|
+
$[3] = t2;
|
|
26
|
+
} else t2 = $[3];
|
|
27
|
+
let t3;
|
|
28
|
+
if ($[4] === Symbol.for("react.memo_cache_sentinel")) {
|
|
29
|
+
t3 = /* @__PURE__ */ jsx(Icon, { icon: Search });
|
|
30
|
+
$[4] = t3;
|
|
31
|
+
} else t3 = $[4];
|
|
32
|
+
let t4;
|
|
33
|
+
if ($[5] !== flush) {
|
|
34
|
+
t4 = (event) => {
|
|
35
|
+
if (event.key === "Enter") flush();
|
|
36
|
+
};
|
|
37
|
+
$[5] = flush;
|
|
38
|
+
$[6] = t4;
|
|
39
|
+
} else t4 = $[6];
|
|
40
|
+
let t5;
|
|
41
|
+
if ($[7] !== draft || $[8] !== setDraft || $[9] !== t1 || $[10] !== t2 || $[11] !== t4) {
|
|
42
|
+
t5 = /* @__PURE__ */ jsx(TextInput, {
|
|
43
|
+
type: "search",
|
|
44
|
+
"aria-label": t1,
|
|
45
|
+
placeholder: t2,
|
|
46
|
+
prefix: t3,
|
|
47
|
+
value: draft,
|
|
48
|
+
onChange: setDraft,
|
|
49
|
+
onKeyDown: t4,
|
|
50
|
+
className: Toolbar_module_default.search
|
|
51
|
+
});
|
|
52
|
+
$[7] = draft;
|
|
53
|
+
$[8] = setDraft;
|
|
54
|
+
$[9] = t1;
|
|
55
|
+
$[10] = t2;
|
|
56
|
+
$[11] = t4;
|
|
57
|
+
$[12] = t5;
|
|
58
|
+
} else t5 = $[12];
|
|
59
|
+
return t5;
|
|
60
|
+
}
|
|
61
|
+
//#endregion
|
|
62
|
+
export { SearchField };
|
|
63
|
+
|
|
64
|
+
//# sourceMappingURL=SearchField.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SearchField.js","names":["Search","draft","setDraft","_c","styles"],"sources":["../../src/toolbar/SearchField.tsx"],"sourcesContent":["import { Search } from 'lucide-react';\n\nimport { Icon, TextInput, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport { useDraft } from '../useDraft';\nimport styles from './Toolbar.module.css';\n\nexport interface SearchFieldProps {\n /** The search of the query. */\n value: string;\n /** Called once the user stops typing, or presses Enter. */\n onChange: (q: string) => void;\n}\n\n/** The search of a list (`q`). */\nexport function SearchField({ value, onChange }: SearchFieldProps) {\n const intl = usePanneauIntl();\n const { draft, setDraft, flush } = useDraft(value, onChange);\n return (\n <TextInput\n type=\"search\"\n aria-label={intl.formatMessage(messages.search)}\n placeholder={intl.formatMessage(messages.searchPlaceholder)}\n prefix={<Icon icon={Search} />}\n value={draft}\n onChange={setDraft}\n onKeyDown={(event) => {\n if (event.key === 'Enter') {\n flush();\n }\n }}\n className={styles.search}\n />\n );\n}\n"],"mappings":";;;;;;;;;AAgBA,SAAO,YAAA,IAAA;CAAA,MAAA,IAAAG,EAAA,EAAA;CAAqB,MAAA,EAAA,OAAA,aAAA;CACxB,MAAA,OAAa,eAAe;CAC5B,MAAA,EAAA,OAAA,UAAA,UAAmC,SAAS,OAAO,QAAQ;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,MAAA;EAIzC,KAAA,KAAI,cAAe,SAAQ,MAAO;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,MAAA;EAClC,KAAA,KAAI,cAAe,SAAQ,iBAAkB;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA,IAAA,2BAAA,GAAA;EACnD,KAAA,oBAAC,MAAD,EAAYH,MAAA,OAAM,CAAA;EAAI,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,OAAA;EAGnB,MAAA,UAAA;GACP,IAAI,MAAK,QAAS,SACd,MAAM;EACT;EACJ,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,YAAA,EAAA,OAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAXL,KAAA,oBAAC,WAAD;GACS,MAAA;GACO,cAAA;GACC,aAAA;GACL,QAAA;GACDC,OAAA;GACGC,UAAA;GACC,WAAA;GAKA,WAAAE,uBAAM;EAAO,CAAA;EAC1B,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OAbF;AAaE"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ListColumn } from '../types';
|
|
2
|
+
export interface SortSelectProps {
|
|
3
|
+
columns: readonly ListColumn[];
|
|
4
|
+
sort: readonly string[];
|
|
5
|
+
onChange: (sort: string[]) => void;
|
|
6
|
+
}
|
|
7
|
+
/** The sort of a list without column headers (cards), by sortable column and direction. */
|
|
8
|
+
export declare function SortSelect({ columns, sort, onChange }: SortSelectProps): import("react").JSX.Element;
|
|
9
|
+
//# sourceMappingURL=SortSelect.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortSelect.d.ts","sourceRoot":"","sources":["../../src/toolbar/SortSelect.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAG3C,MAAM,WAAW,eAAe;IAC5B,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACxB,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;CACtC;AAID,2FAA2F;AAC3F,wBAAgB,UAAU,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,EAAE,eAAe,+BA8BtE"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { messages } from "../messages.js";
|
|
2
|
+
import Toolbar_module_default from "./Toolbar.module.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { Select, usePanneauIntl } from "@panneau/ui";
|
|
5
|
+
import { jsx } from "react/jsx-runtime";
|
|
6
|
+
//#region src/toolbar/SortSelect.tsx
|
|
7
|
+
var DEFAULT = "";
|
|
8
|
+
/** The sort of a list without column headers (cards), by sortable column and direction. */
|
|
9
|
+
function SortSelect(t0) {
|
|
10
|
+
const $ = c(18);
|
|
11
|
+
const { columns, sort, onChange } = t0;
|
|
12
|
+
const intl = usePanneauIntl();
|
|
13
|
+
let t1;
|
|
14
|
+
if ($[0] !== columns || $[1] !== intl) {
|
|
15
|
+
const sortable = columns.filter(_temp);
|
|
16
|
+
const label = _temp2;
|
|
17
|
+
let t2;
|
|
18
|
+
if ($[3] !== intl) {
|
|
19
|
+
t2 = intl.formatMessage(messages.defaultSort);
|
|
20
|
+
$[3] = intl;
|
|
21
|
+
$[4] = t2;
|
|
22
|
+
} else t2 = $[4];
|
|
23
|
+
let t3;
|
|
24
|
+
if ($[5] !== t2) {
|
|
25
|
+
t3 = {
|
|
26
|
+
value: DEFAULT,
|
|
27
|
+
label: t2
|
|
28
|
+
};
|
|
29
|
+
$[5] = t2;
|
|
30
|
+
$[6] = t3;
|
|
31
|
+
} else t3 = $[6];
|
|
32
|
+
let t4;
|
|
33
|
+
if ($[7] !== intl) {
|
|
34
|
+
t4 = (column_1) => [{
|
|
35
|
+
value: column_1.id,
|
|
36
|
+
label: intl.formatMessage(messages.sortAscending, { column: label(column_1) })
|
|
37
|
+
}, {
|
|
38
|
+
value: `-${column_1.id}`,
|
|
39
|
+
label: intl.formatMessage(messages.sortDescending, { column: label(column_1) })
|
|
40
|
+
}];
|
|
41
|
+
$[7] = intl;
|
|
42
|
+
$[8] = t4;
|
|
43
|
+
} else t4 = $[8];
|
|
44
|
+
t1 = [t3, ...sortable.flatMap(t4)];
|
|
45
|
+
$[0] = columns;
|
|
46
|
+
$[1] = intl;
|
|
47
|
+
$[2] = t1;
|
|
48
|
+
} else t1 = $[2];
|
|
49
|
+
const options = t1;
|
|
50
|
+
const current = sort[0] ?? DEFAULT;
|
|
51
|
+
let t2;
|
|
52
|
+
if ($[9] !== intl) {
|
|
53
|
+
t2 = intl.formatMessage(messages.sortBy);
|
|
54
|
+
$[9] = intl;
|
|
55
|
+
$[10] = t2;
|
|
56
|
+
} else t2 = $[10];
|
|
57
|
+
const t3 = options.some((option) => option.value === current) ? current : DEFAULT;
|
|
58
|
+
let t4;
|
|
59
|
+
if ($[11] !== onChange) {
|
|
60
|
+
t4 = (value) => onChange(value === null || value === DEFAULT ? [] : [String(value)]);
|
|
61
|
+
$[11] = onChange;
|
|
62
|
+
$[12] = t4;
|
|
63
|
+
} else t4 = $[12];
|
|
64
|
+
let t5;
|
|
65
|
+
if ($[13] !== options || $[14] !== t2 || $[15] !== t3 || $[16] !== t4) {
|
|
66
|
+
t5 = /* @__PURE__ */ jsx(Select, {
|
|
67
|
+
label: t2,
|
|
68
|
+
options,
|
|
69
|
+
value: t3,
|
|
70
|
+
onChange: t4,
|
|
71
|
+
className: Toolbar_module_default.sort
|
|
72
|
+
});
|
|
73
|
+
$[13] = options;
|
|
74
|
+
$[14] = t2;
|
|
75
|
+
$[15] = t3;
|
|
76
|
+
$[16] = t4;
|
|
77
|
+
$[17] = t5;
|
|
78
|
+
} else t5 = $[17];
|
|
79
|
+
return t5;
|
|
80
|
+
}
|
|
81
|
+
function _temp2(column_0) {
|
|
82
|
+
return typeof column_0.label === "string" ? column_0.label : column_0.id;
|
|
83
|
+
}
|
|
84
|
+
function _temp(column) {
|
|
85
|
+
return column.sortable === true;
|
|
86
|
+
}
|
|
87
|
+
//#endregion
|
|
88
|
+
export { SortSelect };
|
|
89
|
+
|
|
90
|
+
//# sourceMappingURL=SortSelect.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SortSelect.js","names":["column","options","_c","styles"],"sources":["../../src/toolbar/SortSelect.tsx"],"sourcesContent":["import { Select, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListColumn } from '../types';\nimport styles from './Toolbar.module.css';\n\nexport interface SortSelectProps {\n columns: readonly ListColumn[];\n sort: readonly string[];\n onChange: (sort: string[]) => void;\n}\n\nconst DEFAULT = '';\n\n/** The sort of a list without column headers (cards), by sortable column and direction. */\nexport function SortSelect({ columns, sort, onChange }: SortSelectProps) {\n const intl = usePanneauIntl();\n const sortable = columns.filter((column) => column.sortable === true);\n const label = (column: ListColumn) =>\n typeof column.label === 'string' ? column.label : column.id;\n const options = [\n { value: DEFAULT, label: intl.formatMessage(messages.defaultSort) },\n ...sortable.flatMap((column) => [\n {\n value: column.id,\n label: intl.formatMessage(messages.sortAscending, { column: label(column) }),\n },\n {\n value: `-${column.id}`,\n label: intl.formatMessage(messages.sortDescending, { column: label(column) }),\n },\n ]),\n ];\n const current = sort[0] ?? DEFAULT;\n return (\n <Select\n label={intl.formatMessage(messages.sortBy)}\n options={options}\n value={options.some((option) => option.value === current) ? current : DEFAULT}\n onChange={(value) =>\n onChange(value === null || value === DEFAULT ? [] : [String(value)])\n }\n className={styles.sort}\n />\n );\n}\n"],"mappings":";;;;;;AAYA,IAAM,UAAU;;AAGhB,SAAO,WAAA,IAAA;CAAA,MAAA,IAAAE,EAAA,EAAA;CAAoB,MAAA,EAAA,SAAA,MAAA,aAAA;CACvB,MAAA,OAAa,eAAe;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,WAAA,EAAA,OAAA,MAAA;EAC9B,MAAA,WAAiB,QAAO,OAAQ,KAAoC;EACpE,MAAA,QAAc;EACkD,IAAA;EAAA,IAAA,EAAA,OAAA,MAAA;GAEnC,KAAA,KAAI,cAAe,SAAQ,WAAY;GAAC,EAAA,KAAA;GAAA,EAAA,KAAA;EAAA,OAAA,KAAA,EAAA;EAAA,IAAA;EAAA,IAAA,EAAA,OAAA,IAAA;GAAjE,KAAA;IAAA,OAAS;IAAO,OAAS;GAAyC;GAAC,EAAA,KAAA;GAAA,EAAA,KAAA;EAAA,OAAA,KAAA,EAAA;EAAA,IAAA;EAAA,IAAA,EAAA,OAAA,MAAA;GAC/C,MAAA,aAAY,CAC5B;IAAA,OACWF,SAAM;IAAG,OACT,KAAI,cAAe,SAAQ,eAAgB,EAAA,QAAU,MAAMA,QAAM,EAAE,CAAC;GAC/E,GACA;IAAA,OACW,IAAIA,SAAM;IAAK,OACf,KAAI,cAAe,SAAQ,gBAAiB,EAAA,QAAU,MAAMA,QAAM,EAAE,CAAC;GAChF,CAAC;GACJ,EAAA,KAAA;GAAA,EAAA,KAAA;EAAA,OAAA,KAAA,EAAA;EAXW,KAAA,CACZ,IAAmE,GAChE,SAAQ,QAAS,EASnB,CAAC;EACL,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAZD,MAAA,UAAgB;CAahB,MAAA,UAAgB,KAAI,MAAJ;CAAmB,IAAA;CAAA,IAAA,EAAA,OAAA,MAAA;EAGpB,KAAA,KAAI,cAAe,SAAQ,MAAO;EAAC,EAAA,KAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAEnC,MAAA,KAAA,QAAO,MAAM,WAAY,OAAM,UAAW,OAA2B,IAArE,UAAA;CAAsE,IAAA;CAAA,IAAA,EAAA,QAAA,UAAA;EACnE,MAAA,UACN,SAAS,UAAU,QAAQ,UAAU,UAA5B,CAAA,IAAA,CAA4C,OAAO,KAAK,CAAC,CAAC;EAAC,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,WAAA,EAAA,QAAA,MAAA,EAAA,QAAA,MAAA,EAAA,QAAA,IAAA;EAL5E,KAAA,oBAAC,QAAD;GACW,OAAA;GACE;GACF,OAAA;GACG,UAAA;GAGC,WAAAG,uBAAM;EAAK,CAAA;EACxB,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OARF;AAQE;AA5BH,SAAA,OAAA,UAAA;CAAA,OAIC,OAAOH,SAAM,UAAW,WAAWA,SAAM,QAASA,SAAM;AAAG;AAJ5D,SAAA,MAAA,QAAA;CAAA,OAEyC,OAAM,aAAc;AAAI"}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
.panneau-search-xZg66e {
|
|
2
|
+
width: 16rem;
|
|
3
|
+
max-width: 100%;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.panneau-pagination-dNpeRL {
|
|
7
|
+
display: flex;
|
|
8
|
+
flex-wrap: wrap;
|
|
9
|
+
align-items: center;
|
|
10
|
+
justify-content: space-between;
|
|
11
|
+
gap: var(--panneau-space-3);
|
|
12
|
+
font-size: var(--panneau-font-size-sm);
|
|
13
|
+
color: var(--panneau-color-text-muted);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
.panneau-pages-e6sKuy {
|
|
17
|
+
display: flex;
|
|
18
|
+
align-items: center;
|
|
19
|
+
gap: var(--panneau-space-2);
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
.panneau-perPage-U3R-no {
|
|
23
|
+
width: 6rem;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
.panneau-layouts-VUhEzd {
|
|
27
|
+
display: inline-flex;
|
|
28
|
+
padding: 2px;
|
|
29
|
+
background-color: var(--panneau-color-surface-sunken);
|
|
30
|
+
border: var(--panneau-border-width) solid var(--panneau-color-border);
|
|
31
|
+
border-radius: var(--panneau-radius-md);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
.panneau-layoutButton-B28Z38 {
|
|
35
|
+
display: inline-flex;
|
|
36
|
+
align-items: center;
|
|
37
|
+
justify-content: center;
|
|
38
|
+
width: calc(var(--panneau-control-height) - 6px);
|
|
39
|
+
height: calc(var(--panneau-control-height) - 6px);
|
|
40
|
+
color: var(--panneau-color-text-muted);
|
|
41
|
+
background: none;
|
|
42
|
+
border: 0;
|
|
43
|
+
border-radius: var(--panneau-radius-sm);
|
|
44
|
+
cursor: pointer;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
.panneau-layoutButton-B28Z38[data-hovered] {
|
|
48
|
+
color: var(--panneau-color-text);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
.panneau-layoutButton-B28Z38[data-selected] {
|
|
52
|
+
color: var(--panneau-color-text);
|
|
53
|
+
background-color: var(--panneau-color-surface);
|
|
54
|
+
box-shadow: var(--panneau-shadow-sm);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.panneau-layoutButton-B28Z38[data-focus-visible] {
|
|
58
|
+
outline: var(--panneau-focus-width) solid var(--panneau-color-focus);
|
|
59
|
+
outline-offset: 1px;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
.panneau-sort-5bHxuN {
|
|
63
|
+
width: 14rem;
|
|
64
|
+
max-width: 100%;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
@container panneau-list (max-width: 40rem) {
|
|
68
|
+
.panneau-search-xZg66e,
|
|
69
|
+
.panneau-sort-5bHxuN {
|
|
70
|
+
width: 100%;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import "./Toolbar.css";
|
|
2
|
+
//#region src/toolbar/Toolbar.module.css
|
|
3
|
+
var search = "panneau-search-xZg66e";
|
|
4
|
+
var pagination = "panneau-pagination-dNpeRL";
|
|
5
|
+
var pages = "panneau-pages-e6sKuy";
|
|
6
|
+
var perPage = "panneau-perPage-U3R-no";
|
|
7
|
+
var layouts = "panneau-layouts-VUhEzd";
|
|
8
|
+
var layoutButton = "panneau-layoutButton-B28Z38";
|
|
9
|
+
var sort = "panneau-sort-5bHxuN";
|
|
10
|
+
var Toolbar_module_default = {
|
|
11
|
+
search,
|
|
12
|
+
pagination,
|
|
13
|
+
pages,
|
|
14
|
+
perPage,
|
|
15
|
+
layouts,
|
|
16
|
+
layoutButton,
|
|
17
|
+
sort
|
|
18
|
+
};
|
|
19
|
+
//#endregion
|
|
20
|
+
export { Toolbar_module_default as default, layoutButton, layouts, pages, pagination, perPage, search, sort };
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=Toolbar.module.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"Toolbar.module.js","names":[],"sources":["../../src/toolbar/Toolbar.module.css"],"sourcesContent":[".search {\n width: 16rem;\n max-width: 100%;\n}\n\n.pagination {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n justify-content: space-between;\n gap: var(--panneau-space-3);\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n}\n\n.pages {\n display: flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.perPage {\n width: 6rem;\n}\n\n.layouts {\n display: inline-flex;\n padding: 2px;\n background-color: var(--panneau-color-surface-sunken);\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-md);\n}\n\n.layoutButton {\n display: inline-flex;\n align-items: center;\n justify-content: center;\n width: calc(var(--panneau-control-height) - 6px);\n height: calc(var(--panneau-control-height) - 6px);\n color: var(--panneau-color-text-muted);\n background: none;\n border: 0;\n border-radius: var(--panneau-radius-sm);\n cursor: pointer;\n}\n\n.layoutButton[data-hovered] {\n color: var(--panneau-color-text);\n}\n\n.layoutButton[data-selected] {\n color: var(--panneau-color-text);\n background-color: var(--panneau-color-surface);\n box-shadow: var(--panneau-shadow-sm);\n}\n\n.layoutButton[data-focus-visible] {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n.sort {\n width: 14rem;\n max-width: 100%;\n}\n\n@container panneau-list (max-width: 40rem) {\n .search,\n .sort {\n width: 100%;\n }\n}\n"],"mappings":""}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import type { ComponentType, ReactNode } from 'react';
|
|
2
|
+
import type { Abilities, Action, ActionScope, Field, Filter, FilterValue, Option, Selection } from '@panneau/protocol';
|
|
3
|
+
/**
|
|
4
|
+
* An item of a list: an id, and the values of its fields. Items of the protocol (`Item`) are list
|
|
5
|
+
* items; so are a product's own records, without `version` or `abilities`.
|
|
6
|
+
*/
|
|
7
|
+
export interface ListItem {
|
|
8
|
+
id: string;
|
|
9
|
+
/** What the user can do with the item. Without abilities, every action is shown. */
|
|
10
|
+
abilities?: Abilities;
|
|
11
|
+
[key: string]: unknown;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* A column. A resolved column of `@panneau/core` (`ResolvedColumn`) is a column, and so is a
|
|
15
|
+
* column written by hand: `{ id: 'title', label: 'Title' }`.
|
|
16
|
+
*/
|
|
17
|
+
export interface ListColumn {
|
|
18
|
+
/** The column id. Without `render`, the value is `item[id]`. Also the key to sort by. */
|
|
19
|
+
id: string;
|
|
20
|
+
label?: ReactNode;
|
|
21
|
+
/** The field shown, for the display (options of a select, locales of a localized value). */
|
|
22
|
+
field?: Field | null;
|
|
23
|
+
/** How the value is displayed: a display of the registry (`date`, `select`). */
|
|
24
|
+
display?: string | null;
|
|
25
|
+
sortable?: boolean;
|
|
26
|
+
width?: number | string;
|
|
27
|
+
align?: 'start' | 'center' | 'end';
|
|
28
|
+
/** Renders the cell, instead of a display. */
|
|
29
|
+
render?: (item: ListItem) => ReactNode;
|
|
30
|
+
}
|
|
31
|
+
/** Props of a display: shows the value of a column for an item. */
|
|
32
|
+
export interface DisplayProps {
|
|
33
|
+
value: unknown;
|
|
34
|
+
item: ListItem;
|
|
35
|
+
column: ListColumn;
|
|
36
|
+
/** The column's field, or `null`. */
|
|
37
|
+
field: Field | null;
|
|
38
|
+
}
|
|
39
|
+
/** A registry entry: renders a value with a display (`date`, `select`, a plugin's own). */
|
|
40
|
+
export type DisplayEntry = ComponentType<DisplayProps>;
|
|
41
|
+
/** What a selection action or a toolbar action applies to. */
|
|
42
|
+
export interface ListActionEvent {
|
|
43
|
+
action: Action;
|
|
44
|
+
/** `item` for a row action, `selection` or `resource` for a toolbar action. */
|
|
45
|
+
scope: ActionScope;
|
|
46
|
+
/** The item of a row action. */
|
|
47
|
+
item?: ListItem;
|
|
48
|
+
/** The selection to send with a `selection` action, as the protocol's action request has it. */
|
|
49
|
+
selection?: Selection;
|
|
50
|
+
/** How many items the action applies to: 1 for an item, the selected count for a selection. */
|
|
51
|
+
count: number;
|
|
52
|
+
/** Selected items of the current page that don't allow the action: the backend skips them. */
|
|
53
|
+
skipped: readonly ListItem[];
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Runs an action. Lists ask for confirmation first when the action has `confirm`. A returned
|
|
57
|
+
* promise shows the action as pending until it settles; after a selection action succeeds, the
|
|
58
|
+
* selection is cleared, unless the handler gives `false` (the action didn't run, as when the user
|
|
59
|
+
* cancels its parameters). `useActionRunner()` of `@panneau/actions` is such a handler.
|
|
60
|
+
*/
|
|
61
|
+
export type ListActionHandler = (event: ListActionEvent) => unknown;
|
|
62
|
+
/** Props of a filter control. */
|
|
63
|
+
export interface FilterControlProps {
|
|
64
|
+
filter: Filter;
|
|
65
|
+
/** The filter's label: its `label`, or its id. */
|
|
66
|
+
label: string;
|
|
67
|
+
/** Options, from the filter or from the field it filters. */
|
|
68
|
+
options: readonly Option[];
|
|
69
|
+
/** The current value: strings, as the URL keeps them, or what the control set. */
|
|
70
|
+
value: unknown;
|
|
71
|
+
/** Sets the value, or removes the filter with `undefined`. */
|
|
72
|
+
onChange: (value: FilterValue | undefined) => void;
|
|
73
|
+
/** Remembers the label of a value, for the chip of the active filter (relations). */
|
|
74
|
+
onLabel: (value: string, label: string) => void;
|
|
75
|
+
/** The label remembered for a value, if any. */
|
|
76
|
+
getValueLabel: (value: string) => string | null;
|
|
77
|
+
}
|
|
78
|
+
/** A filter control, by filter type (`select`, `date`). */
|
|
79
|
+
export type FilterEntry = ComponentType<FilterControlProps>;
|
|
80
|
+
/** Props of a list layout: renders the items of the current page. */
|
|
81
|
+
export interface ListLayoutProps {
|
|
82
|
+
items: readonly ListItem[];
|
|
83
|
+
columns: readonly ListColumn[];
|
|
84
|
+
/** Renders the value of a column for an item, with its display. */
|
|
85
|
+
renderValue: (item: ListItem, column: ListColumn) => ReactNode;
|
|
86
|
+
/** The label of an item: its title, for checkboxes and actions. */
|
|
87
|
+
getItemLabel: (item: ListItem) => string;
|
|
88
|
+
/** A link to the item, when the list has one. */
|
|
89
|
+
getItemHref?: ((item: ListItem) => string | null) | undefined;
|
|
90
|
+
/** Whether items have checkboxes. */
|
|
91
|
+
selectable: boolean;
|
|
92
|
+
isSelected: (item: ListItem) => boolean;
|
|
93
|
+
onToggle: (item: ListItem) => void;
|
|
94
|
+
/** The row actions of an item, or `null` without any. */
|
|
95
|
+
renderActions: (item: ListItem) => ReactNode;
|
|
96
|
+
/** The current sort, as `sort` query values (`['-published_at']`). */
|
|
97
|
+
sort: readonly string[];
|
|
98
|
+
onSort: (column: ListColumn) => void;
|
|
99
|
+
/** Accessible name of the list. */
|
|
100
|
+
label: string;
|
|
101
|
+
/** The checkbox that selects the page, for layouts that show it in a header. */
|
|
102
|
+
pageSelection: ReactNode;
|
|
103
|
+
}
|
|
104
|
+
/** A list layout, by id (`table`, `cards`). */
|
|
105
|
+
export type ListLayoutEntry = ComponentType<ListLayoutProps>;
|
|
106
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A text that is typed locally and committed after a pause: the list query changes once the user
|
|
3
|
+
* stops typing, not on every key. A change of `value` from outside (a chip removed, the query
|
|
4
|
+
* reset) replaces the draft.
|
|
5
|
+
*/
|
|
6
|
+
export declare function useDraft(value: string, commit: (value: string) => void, delay?: number): {
|
|
7
|
+
draft: string;
|
|
8
|
+
setDraft: (draft: string) => void;
|
|
9
|
+
flush: () => void;
|
|
10
|
+
};
|
|
11
|
+
//# sourceMappingURL=useDraft.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDraft.d.ts","sourceRoot":"","sources":["../src/useDraft.ts"],"names":[],"mappings":"AAEA;;;;GAIG;AACH,wBAAgB,QAAQ,CACpB,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,EAC/B,KAAK,SAAM,GACZ;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,MAAM,IAAI,CAAA;CAAE,CAwBzE"}
|
package/dist/useDraft.js
ADDED
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { useEffect, useEffectEvent, useState } from "react";
|
|
3
|
+
//#region src/useDraft.ts
|
|
4
|
+
/**
|
|
5
|
+
* A text that is typed locally and committed after a pause: the list query changes once the user
|
|
6
|
+
* stops typing, not on every key. A change of `value` from outside (a chip removed, the query
|
|
7
|
+
* reset) replaces the draft.
|
|
8
|
+
*/
|
|
9
|
+
function useDraft(value, commit, t0) {
|
|
10
|
+
const $ = c(18);
|
|
11
|
+
const delay = t0 === void 0 ? 300 : t0;
|
|
12
|
+
const [draft, setDraft] = useState(value);
|
|
13
|
+
const [synced, setSynced] = useState(value);
|
|
14
|
+
if (value !== synced) {
|
|
15
|
+
setSynced(value);
|
|
16
|
+
setDraft(value);
|
|
17
|
+
}
|
|
18
|
+
let t1;
|
|
19
|
+
if ($[0] !== commit) {
|
|
20
|
+
t1 = (next) => commit(next);
|
|
21
|
+
$[0] = commit;
|
|
22
|
+
$[1] = t1;
|
|
23
|
+
} else t1 = $[1];
|
|
24
|
+
const onCommit = useEffectEvent(t1);
|
|
25
|
+
let t2;
|
|
26
|
+
if ($[2] !== delay || $[3] !== draft || $[4] !== onCommit || $[5] !== synced) {
|
|
27
|
+
t2 = () => {
|
|
28
|
+
if (draft === synced) return;
|
|
29
|
+
const timer = setTimeout(() => onCommit(draft), delay);
|
|
30
|
+
return () => clearTimeout(timer);
|
|
31
|
+
};
|
|
32
|
+
$[2] = delay;
|
|
33
|
+
$[3] = draft;
|
|
34
|
+
$[4] = onCommit;
|
|
35
|
+
$[5] = synced;
|
|
36
|
+
$[6] = t2;
|
|
37
|
+
} else t2 = $[6];
|
|
38
|
+
let t3;
|
|
39
|
+
if ($[7] !== delay || $[8] !== draft || $[9] !== synced) {
|
|
40
|
+
t3 = [
|
|
41
|
+
draft,
|
|
42
|
+
synced,
|
|
43
|
+
delay
|
|
44
|
+
];
|
|
45
|
+
$[7] = delay;
|
|
46
|
+
$[8] = draft;
|
|
47
|
+
$[9] = synced;
|
|
48
|
+
$[10] = t3;
|
|
49
|
+
} else t3 = $[10];
|
|
50
|
+
useEffect(t2, t3);
|
|
51
|
+
let t4;
|
|
52
|
+
if ($[11] !== commit || $[12] !== draft || $[13] !== synced) {
|
|
53
|
+
t4 = () => {
|
|
54
|
+
if (draft !== synced) commit(draft);
|
|
55
|
+
};
|
|
56
|
+
$[11] = commit;
|
|
57
|
+
$[12] = draft;
|
|
58
|
+
$[13] = synced;
|
|
59
|
+
$[14] = t4;
|
|
60
|
+
} else t4 = $[14];
|
|
61
|
+
let t5;
|
|
62
|
+
if ($[15] !== draft || $[16] !== t4) {
|
|
63
|
+
t5 = {
|
|
64
|
+
draft,
|
|
65
|
+
setDraft,
|
|
66
|
+
flush: t4
|
|
67
|
+
};
|
|
68
|
+
$[15] = draft;
|
|
69
|
+
$[16] = t4;
|
|
70
|
+
$[17] = t5;
|
|
71
|
+
} else t5 = $[17];
|
|
72
|
+
return t5;
|
|
73
|
+
}
|
|
74
|
+
//#endregion
|
|
75
|
+
export { useDraft };
|
|
76
|
+
|
|
77
|
+
//# sourceMappingURL=useDraft.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useDraft.js","names":["_c"],"sources":["../src/useDraft.ts"],"sourcesContent":["import { useEffect, useEffectEvent, useState } from 'react';\n\n/**\n * A text that is typed locally and committed after a pause: the list query changes once the user\n * stops typing, not on every key. A change of `value` from outside (a chip removed, the query\n * reset) replaces the draft.\n */\nexport function useDraft(\n value: string,\n commit: (value: string) => void,\n delay = 300,\n): { draft: string; setDraft: (draft: string) => void; flush: () => void } {\n const [draft, setDraft] = useState(value);\n const [synced, setSynced] = useState(value);\n if (value !== synced) {\n setSynced(value);\n setDraft(value);\n }\n const onCommit = useEffectEvent((next: string) => commit(next));\n useEffect(() => {\n if (draft === synced) {\n return undefined;\n }\n const timer = setTimeout(() => onCommit(draft), delay);\n return () => clearTimeout(timer);\n }, [draft, synced, delay]);\n return {\n draft,\n setDraft,\n flush: () => {\n if (draft !== synced) {\n commit(draft);\n }\n },\n };\n}\n"],"mappings":";;;;;;;;AAOA,SAAO,SAAA,OAAA,QAAA,IAAA;CAAA,MAAA,IAAAA,EAAA,EAAA;CAGH,MAAA,QAAA,OAAA,KAAA,IAAA,MAAA;CAEA,MAAA,CAAA,OAAA,YAA0B,SAAS,KAAK;CACxC,MAAA,CAAA,QAAA,aAA4B,SAAS,KAAK;CAC1C,IAAI,UAAU,QAAM;EAChB,UAAU,KAAK;EACf,SAAS,KAAK;CAAC;CAClB,IAAA;CAAA,IAAA,EAAA,OAAA,QAAA;EAC+B,MAAA,SAAkB,OAAO,IAAI;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAA9D,MAAA,WAAiB,eAAe,EAA8B;CAAE,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,SAAA,EAAA,OAAA,YAAA,EAAA,OAAA,QAAA;EACtD,WAAA;GACN,IAAI,UAAU,QAAM;GAGpB,MAAA,QAAc,iBAAiB,SAAS,KAAK,GAAG,KAAK;GAAE,aAC1C,aAAa,KAAK;EAAC;EACnC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,OAAA,SAAA,EAAA,OAAA,SAAA,EAAA,OAAA,QAAA;EAAE,KAAA;GAAC;GAAO;GAAQ;EAAK;EAAC,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,KAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CANzB,UAAU,IAMP,EAAsB;CAAC,IAAA;CAAA,IAAA,EAAA,QAAA,UAAA,EAAA,QAAA,SAAA,EAAA,QAAA,QAAA;EAIf,WAAA;GACH,IAAI,UAAU,QACV,OAAO,KAAK;EACf;EACJ,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,IAAA;CAAA,IAAA,EAAA,QAAA,SAAA,EAAA,QAAA,IAAA;EAPE,KAAA;GAAA;GAAA;GAAA,OAGI;EAKX;EAAC,EAAA,MAAA;EAAA,EAAA,MAAA;EAAA,EAAA,MAAA;CAAA,OAAA,KAAA,EAAA;CAAA,OARM;AAQN"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useListState.d.ts","sourceRoot":"","sources":["../src/useListState.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAErD,4FAA4F;AAC5F,wBAAgB,YAAY,CAAC,IAAI,EAAE,IAAI,GAAG,SAAS,CAElD"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useSyncExternalStore } from "react";
|
|
2
|
+
//#region src/useListState.ts
|
|
3
|
+
/** The state of a list created elsewhere (`createList()`, `useList()`), kept up to date. */
|
|
4
|
+
function useListState(list) {
|
|
5
|
+
return useSyncExternalStore(list.subscribe, list.getState, list.getState);
|
|
6
|
+
}
|
|
7
|
+
//#endregion
|
|
8
|
+
export { useListState };
|
|
9
|
+
|
|
10
|
+
//# sourceMappingURL=useListState.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"useListState.js","names":[],"sources":["../src/useListState.ts"],"sourcesContent":["import { useSyncExternalStore } from 'react';\n\nimport type { List, ListState } from '@panneau/core';\n\n/** The state of a list created elsewhere (`createList()`, `useList()`), kept up to date. */\nexport function useListState(list: List): ListState {\n return useSyncExternalStore(list.subscribe, list.getState, list.getState);\n}\n"],"mappings":";;;AAKA,SAAO,aAAA,MAAA;CAAA,OACI,qBAAqB,KAAI,WAAY,KAAI,UAAW,KAAI,QAAS;AAAC"}
|
package/dist/values.d.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Field, Option } from '@panneau/protocol';
|
|
2
|
+
import type { ListColumn, ListItem } from './types';
|
|
3
|
+
/**
|
|
4
|
+
* The value of a localized field in a locale: the locale (`fr-CA`), its language (`fr`), then the
|
|
5
|
+
* first filled locale. Other values are returned as they are.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getLocalizedValue(value: unknown, locale: string): unknown;
|
|
8
|
+
/** Whether a field's values are keyed by locale. */
|
|
9
|
+
export declare function isLocalized(field: Field | null | undefined): boolean;
|
|
10
|
+
/** The value of a column for an item: `item[id]`, in the locale for a localized field. */
|
|
11
|
+
export declare function getColumnValue(item: ListItem, column: ListColumn, locale: string): unknown;
|
|
12
|
+
/**
|
|
13
|
+
* A value as plain text: strings and numbers as they are, references by their label, localized
|
|
14
|
+
* values in the locale, lists joined with commas. For labels of items and for search.
|
|
15
|
+
*/
|
|
16
|
+
export declare function toText(value: unknown, locale: string): string;
|
|
17
|
+
/** The options of a field, or none. */
|
|
18
|
+
export declare function getFieldOptions(field: Field | null | undefined): readonly Option[];
|
|
19
|
+
/** The label of an option value, matched as a string (values from the URL are strings). */
|
|
20
|
+
export declare function getOptionLabel(options: readonly Option[], value: unknown): string | null;
|
|
21
|
+
//# sourceMappingURL=values.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.d.ts","sourceRoot":"","sources":["../src/values.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,KAAK,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAMpD;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAczE;AAED,oDAAoD;AACpD,wBAAgB,WAAW,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAEpE;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,GAAG,OAAO,CAG1F;AAED;;;GAGG;AACH,wBAAgB,MAAM,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAuB7D;AAED,uCAAuC;AACvC,wBAAgB,eAAe,CAAC,KAAK,EAAE,KAAK,GAAG,IAAI,GAAG,SAAS,GAAG,SAAS,MAAM,EAAE,CAElF;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAGxF"}
|
package/dist/values.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
//#region src/values.ts
|
|
2
|
+
function isRecord(value) {
|
|
3
|
+
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* The value of a localized field in a locale: the locale (`fr-CA`), its language (`fr`), then the
|
|
7
|
+
* first filled locale. Other values are returned as they are.
|
|
8
|
+
*/
|
|
9
|
+
function getLocalizedValue(value, locale) {
|
|
10
|
+
if (!isRecord(value)) return value;
|
|
11
|
+
const language = locale.split("-")[0] ?? locale;
|
|
12
|
+
const filled = (candidate) => candidate !== void 0 && candidate !== null && candidate !== "";
|
|
13
|
+
if (filled(value[locale])) return value[locale];
|
|
14
|
+
if (filled(value[language])) return value[language];
|
|
15
|
+
return Object.values(value).find(filled) ?? null;
|
|
16
|
+
}
|
|
17
|
+
/** Whether a field's values are keyed by locale. */
|
|
18
|
+
function isLocalized(field) {
|
|
19
|
+
return field?.localized === true;
|
|
20
|
+
}
|
|
21
|
+
/** The value of a column for an item: `item[id]`, in the locale for a localized field. */
|
|
22
|
+
function getColumnValue(item, column, locale) {
|
|
23
|
+
const value = item[column.field?.name ?? column.id];
|
|
24
|
+
return isLocalized(column.field) ? getLocalizedValue(value, locale) : value;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* A value as plain text: strings and numbers as they are, references by their label, localized
|
|
28
|
+
* values in the locale, lists joined with commas. For labels of items and for search.
|
|
29
|
+
*/
|
|
30
|
+
function toText(value, locale) {
|
|
31
|
+
if (value === null || value === void 0) return "";
|
|
32
|
+
if (typeof value === "string") return value;
|
|
33
|
+
if (typeof value === "number" || typeof value === "boolean") return String(value);
|
|
34
|
+
if (Array.isArray(value)) return value.map((entry) => toText(entry, locale)).filter((text) => text !== "").join(", ");
|
|
35
|
+
if (isRecord(value)) {
|
|
36
|
+
if (typeof value.label === "string") return value.label;
|
|
37
|
+
return toText(getLocalizedValue(value, locale), locale);
|
|
38
|
+
}
|
|
39
|
+
return "";
|
|
40
|
+
}
|
|
41
|
+
/** The options of a field, or none. */
|
|
42
|
+
function getFieldOptions(field) {
|
|
43
|
+
return field?.options ?? [];
|
|
44
|
+
}
|
|
45
|
+
/** The label of an option value, matched as a string (values from the URL are strings). */
|
|
46
|
+
function getOptionLabel(options, value) {
|
|
47
|
+
return options.find((candidate) => String(candidate.value) === String(value))?.label ?? null;
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export { getColumnValue, getFieldOptions, getLocalizedValue, getOptionLabel, isLocalized, toText };
|
|
51
|
+
|
|
52
|
+
//# sourceMappingURL=values.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"values.js","names":[],"sources":["../src/values.ts"],"sourcesContent":["import type { Field, Option } from '@panneau/protocol';\n\nimport type { ListColumn, ListItem } from './types';\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value);\n}\n\n/**\n * The value of a localized field in a locale: the locale (`fr-CA`), its language (`fr`), then the\n * first filled locale. Other values are returned as they are.\n */\nexport function getLocalizedValue(value: unknown, locale: string): unknown {\n if (!isRecord(value)) {\n return value;\n }\n const language = locale.split('-')[0] ?? locale;\n const filled = (candidate: unknown) =>\n candidate !== undefined && candidate !== null && candidate !== '';\n if (filled(value[locale])) {\n return value[locale];\n }\n if (filled(value[language])) {\n return value[language];\n }\n return Object.values(value).find(filled) ?? null;\n}\n\n/** Whether a field's values are keyed by locale. */\nexport function isLocalized(field: Field | null | undefined): boolean {\n return field?.localized === true;\n}\n\n/** The value of a column for an item: `item[id]`, in the locale for a localized field. */\nexport function getColumnValue(item: ListItem, column: ListColumn, locale: string): unknown {\n const value = item[column.field?.name ?? column.id];\n return isLocalized(column.field) ? getLocalizedValue(value, locale) : value;\n}\n\n/**\n * A value as plain text: strings and numbers as they are, references by their label, localized\n * values in the locale, lists joined with commas. For labels of items and for search.\n */\nexport function toText(value: unknown, locale: string): string {\n if (value === null || value === undefined) {\n return '';\n }\n if (typeof value === 'string') {\n return value;\n }\n if (typeof value === 'number' || typeof value === 'boolean') {\n return String(value);\n }\n if (Array.isArray(value)) {\n return value\n .map((entry) => toText(entry, locale))\n .filter((text) => text !== '')\n .join(', ');\n }\n if (isRecord(value)) {\n if (typeof value.label === 'string') {\n return value.label;\n }\n return toText(getLocalizedValue(value, locale), locale);\n }\n return '';\n}\n\n/** The options of a field, or none. */\nexport function getFieldOptions(field: Field | null | undefined): readonly Option[] {\n return field?.options ?? [];\n}\n\n/** The label of an option value, matched as a string (values from the URL are strings). */\nexport function getOptionLabel(options: readonly Option[], value: unknown): string | null {\n const option = options.find((candidate) => String(candidate.value) === String(value));\n return option?.label ?? null;\n}\n"],"mappings":";AAIA,SAAS,SAAS,OAAkD;CAChE,OAAO,UAAU,QAAQ,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK;AAC9E;;;;;AAMA,SAAgB,kBAAkB,OAAgB,QAAyB;CACvE,IAAI,CAAC,SAAS,KAAK,GACf,OAAO;CAEX,MAAM,WAAW,OAAO,MAAM,GAAG,CAAC,CAAC,MAAM;CACzC,MAAM,UAAU,cACZ,cAAc,KAAA,KAAa,cAAc,QAAQ,cAAc;CACnE,IAAI,OAAO,MAAM,OAAO,GACpB,OAAO,MAAM;CAEjB,IAAI,OAAO,MAAM,SAAS,GACtB,OAAO,MAAM;CAEjB,OAAO,OAAO,OAAO,KAAK,CAAC,CAAC,KAAK,MAAM,KAAK;AAChD;;AAGA,SAAgB,YAAY,OAA0C;CAClE,OAAO,OAAO,cAAc;AAChC;;AAGA,SAAgB,eAAe,MAAgB,QAAoB,QAAyB;CACxF,MAAM,QAAQ,KAAK,OAAO,OAAO,QAAQ,OAAO;CAChD,OAAO,YAAY,OAAO,KAAK,IAAI,kBAAkB,OAAO,MAAM,IAAI;AAC1E;;;;;AAMA,SAAgB,OAAO,OAAgB,QAAwB;CAC3D,IAAI,UAAU,QAAQ,UAAU,KAAA,GAC5B,OAAO;CAEX,IAAI,OAAO,UAAU,UACjB,OAAO;CAEX,IAAI,OAAO,UAAU,YAAY,OAAO,UAAU,WAC9C,OAAO,OAAO,KAAK;CAEvB,IAAI,MAAM,QAAQ,KAAK,GACnB,OAAO,MACF,KAAK,UAAU,OAAO,OAAO,MAAM,CAAC,CAAC,CACrC,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,KAAK,IAAI;CAElB,IAAI,SAAS,KAAK,GAAG;EACjB,IAAI,OAAO,MAAM,UAAU,UACvB,OAAO,MAAM;EAEjB,OAAO,OAAO,kBAAkB,OAAO,MAAM,GAAG,MAAM;CAC1D;CACA,OAAO;AACX;;AAGA,SAAgB,gBAAgB,OAAoD;CAChF,OAAO,OAAO,WAAW,CAAA;AAC7B;;AAGA,SAAgB,eAAe,SAA4B,OAA+B;CAEtF,OADe,QAAQ,MAAM,cAAc,OAAO,UAAU,KAAK,MAAM,OAAO,KAAK,CAC5E,CAAA,EAAQ,SAAS;AAC5B"}
|