@panneau/lists 5.0.0-alpha.12 → 5.0.0-alpha.14

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 (78) hide show
  1. package/README.md +13 -11
  2. package/dist/List.d.ts +1 -1
  3. package/dist/List.d.ts.map +1 -1
  4. package/dist/List.js +29 -50
  5. package/dist/List.js.map +1 -1
  6. package/dist/ListView.d.ts +34 -5
  7. package/dist/ListView.d.ts.map +1 -1
  8. package/dist/ListView.js +416 -359
  9. package/dist/ListView.js.map +1 -1
  10. package/dist/columns.d.ts +10 -0
  11. package/dist/columns.d.ts.map +1 -0
  12. package/dist/columns.js +25 -0
  13. package/dist/columns.js.map +1 -0
  14. package/dist/displays/Displays.css +12 -0
  15. package/dist/displays/Displays.module.js +6 -2
  16. package/dist/displays/Displays.module.js.map +1 -1
  17. package/dist/displays/displays.d.ts +11 -1
  18. package/dist/displays/displays.d.ts.map +1 -1
  19. package/dist/displays/displays.js +185 -22
  20. package/dist/displays/displays.js.map +1 -1
  21. package/dist/images.d.ts +6 -0
  22. package/dist/images.d.ts.map +1 -0
  23. package/dist/images.js +18 -0
  24. package/dist/images.js.map +1 -0
  25. package/dist/index.d.ts +5 -2
  26. package/dist/index.d.ts.map +1 -1
  27. package/dist/index.js +5 -2
  28. package/dist/inline/Inline.css +58 -0
  29. package/dist/inline/Inline.module.js +20 -0
  30. package/dist/inline/Inline.module.js.map +1 -0
  31. package/dist/inline/InlineCell.d.ts +27 -0
  32. package/dist/inline/InlineCell.d.ts.map +1 -0
  33. package/dist/inline/InlineCell.js +471 -0
  34. package/dist/inline/InlineCell.js.map +1 -0
  35. package/dist/inline/editable.d.ts +12 -0
  36. package/dist/inline/editable.d.ts.map +1 -0
  37. package/dist/inline/editable.js +29 -0
  38. package/dist/inline/editable.js.map +1 -0
  39. package/dist/layouts/CalendarLayout.css +153 -0
  40. package/dist/layouts/CalendarLayout.d.ts +9 -0
  41. package/dist/layouts/CalendarLayout.d.ts.map +1 -0
  42. package/dist/layouts/CalendarLayout.js +298 -0
  43. package/dist/layouts/CalendarLayout.js.map +1 -0
  44. package/dist/layouts/CalendarLayout.module.js +28 -0
  45. package/dist/layouts/CalendarLayout.module.js.map +1 -0
  46. package/dist/layouts/CardsLayout.js +1 -1
  47. package/dist/layouts/GalleryLayout.css +80 -0
  48. package/dist/layouts/GalleryLayout.d.ts +8 -0
  49. package/dist/layouts/GalleryLayout.d.ts.map +1 -0
  50. package/dist/layouts/GalleryLayout.js +129 -0
  51. package/dist/layouts/GalleryLayout.js.map +1 -0
  52. package/dist/layouts/GalleryLayout.module.js +26 -0
  53. package/dist/layouts/GalleryLayout.module.js.map +1 -0
  54. package/dist/layouts/TableLayout.d.ts +1 -1
  55. package/dist/layouts/TableLayout.d.ts.map +1 -1
  56. package/dist/layouts/TableLayout.js +44 -39
  57. package/dist/layouts/TableLayout.js.map +1 -1
  58. package/dist/layouts/builtIn.d.ts +1 -1
  59. package/dist/layouts/builtIn.d.ts.map +1 -1
  60. package/dist/layouts/builtIn.js +6 -2
  61. package/dist/layouts/builtIn.js.map +1 -1
  62. package/dist/toolbar/ColumnMenu.d.ts +17 -0
  63. package/dist/toolbar/ColumnMenu.d.ts.map +1 -0
  64. package/dist/toolbar/ColumnMenu.js +193 -0
  65. package/dist/toolbar/ColumnMenu.js.map +1 -0
  66. package/dist/toolbar/LayoutSwitch.d.ts.map +1 -1
  67. package/dist/toolbar/LayoutSwitch.js +73 -55
  68. package/dist/toolbar/LayoutSwitch.js.map +1 -1
  69. package/dist/toolbar/Toolbar.css +36 -0
  70. package/dist/toolbar/Toolbar.module.js +12 -2
  71. package/dist/toolbar/Toolbar.module.js.map +1 -1
  72. package/dist/types.d.ts +42 -0
  73. package/dist/types.d.ts.map +1 -1
  74. package/dist/values.d.ts +1 -0
  75. package/dist/values.d.ts.map +1 -1
  76. package/dist/values.js +1 -1
  77. package/dist/values.js.map +1 -1
  78. package/package.json +7 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ColumnMenu.js","names":["ArrowDown","ArrowUp","Columns3","Button","Checkbox","IconButton","Popover","PopoverTrigger","usePanneauIntl","messages","ListColumn","styles","ColumnMenuProps","columns","shown","onChange","ids","onReset","labelOf","column","label","id","ColumnMenu","t0","$","_c","intl","T0","T1","t1","t2","t3","t4","t5","t6","map","_temp","ordered","filter","column_0","includes","move","index","offset","next","splice","undefined","t7","formatMessage","columnList","column_1","index_0","indexOf","isShown","hideable","length","selected","id_0","columnLabel","columnMoves","moveColumnUp","moveColumnDown","t8","t9","t10","resetColumns","t11","t12","t13","t14","_c","styles"],"sources":["../../src/toolbar/ColumnMenu.tsx"],"sourcesContent":["import { ArrowDown, ArrowUp, Columns3 } from 'lucide-react';\n\nimport { Button, Checkbox, IconButton, Popover, PopoverTrigger, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport type { ListColumn } from '../types';\nimport styles from './Toolbar.module.css';\n\nexport interface ColumnMenuProps {\n /** Every column of the list, in the order of the definition. */\n columns: readonly ListColumn[];\n /** The columns shown, in their order. */\n shown: readonly ListColumn[];\n /** Shows these columns, by id, in this order. */\n onChange: (ids: string[]) => void;\n /** Back to the columns of the definition, or `null` while they are shown. */\n onReset: (() => void) | null;\n}\n\nfunction labelOf(column: ListColumn): string {\n return typeof column.label === 'string' ? column.label : column.id;\n}\n\n/**\n * A button that opens the columns of a list: a checkbox to show or hide each one, buttons to\n * move the shown ones, and a reset to the columns of the definition (decision 0042).\n */\nexport function ColumnMenu({ columns, shown, onChange, onReset }: ColumnMenuProps) {\n const intl = usePanneauIntl();\n const ids = shown.map((column) => column.id);\n // The shown columns first, in their order, then the others, where showing one adds it.\n const ordered = [...shown, ...columns.filter((column) => !shown.includes(column))];\n const move = (index: number, offset: number) => {\n const next = [...ids];\n const [id] = next.splice(index, 1);\n if (id !== undefined) {\n next.splice(index + offset, 0, id);\n onChange(next);\n }\n };\n return (\n <PopoverTrigger>\n <Button icon={Columns3}>{intl.formatMessage(messages.columns)}</Button>\n <Popover placement=\"bottom end\" aria-label={intl.formatMessage(messages.columns)}>\n <div className={styles.columns}>\n <ul className={styles.columnList}>\n {ordered.map((column) => {\n const index = ids.indexOf(column.id);\n const isShown = index !== -1;\n const label = labelOf(column);\n return (\n <li key={column.id} className={styles.column}>\n <Checkbox\n isSelected={isShown}\n // The last column shown stays: a list shows something.\n isDisabled={\n column.hideable === false ||\n (isShown && ids.length === 1)\n }\n onChange={(selected) =>\n onChange(\n selected\n ? [...ids, column.id]\n : ids.filter((id) => id !== column.id),\n )\n }\n className={styles.columnLabel}\n >\n {label}\n </Checkbox>\n {isShown ? (\n <span className={styles.columnMoves}>\n <IconButton\n icon={ArrowUp}\n size=\"sm\"\n label={intl.formatMessage(messages.moveColumnUp, {\n column: label,\n })}\n showTooltip={false}\n isDisabled={index === 0}\n onPress={() => move(index, -1)}\n />\n <IconButton\n icon={ArrowDown}\n size=\"sm\"\n label={intl.formatMessage(messages.moveColumnDown, {\n column: label,\n })}\n showTooltip={false}\n isDisabled={index === ids.length - 1}\n onPress={() => move(index, 1)}\n />\n </span>\n ) : null}\n </li>\n );\n })}\n </ul>\n <Button\n size=\"sm\"\n appearance=\"ghost\"\n isDisabled={onReset === null}\n onPress={() => onReset?.()}\n >\n {intl.formatMessage(messages.resetColumns)}\n </Button>\n </div>\n </Popover>\n </PopoverTrigger>\n );\n}\n"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"LayoutSwitch.d.ts","sourceRoot":"","sources":["../../src/toolbar/LayoutSwitch.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BAoC3E"}
1
+ {"version":3,"file":"LayoutSwitch.d.ts","sourceRoot":"","sources":["../../src/toolbar/LayoutSwitch.tsx"],"names":[],"mappings":"AAeA,MAAM,WAAW,iBAAiB;IAC9B,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;CACtC;AAED,+EAA+E;AAC/E,wBAAgB,YAAY,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,EAAE,iBAAiB,+BAsC3E"}
@@ -3,16 +3,18 @@ import Toolbar_module_default from "./Toolbar.module.js";
3
3
  import { c } from "react/compiler-runtime";
4
4
  import { Icon, Tooltip, usePanneauIntl } from "@panneau/ui";
5
5
  import { jsx } from "react/jsx-runtime";
6
- import { LayoutGrid, Rows3, Square } from "lucide-react";
6
+ import { CalendarDays, Images, LayoutGrid, Rows3, Square } from "lucide-react";
7
7
  import { ToggleButton, ToggleButtonGroup } from "react-aria-components";
8
8
  //#region src/toolbar/LayoutSwitch.tsx
9
9
  var ICONS = {
10
10
  table: Rows3,
11
- cards: LayoutGrid
11
+ cards: LayoutGrid,
12
+ gallery: Images,
13
+ calendar: CalendarDays
12
14
  };
13
15
  /** Buttons to show the items as a table, as cards, or in a plugin's layout. */
14
16
  function LayoutSwitch(t0) {
15
- const $ = c(23);
17
+ const $ = c(29);
16
18
  const { layouts, value, onChange } = t0;
17
19
  const intl = usePanneauIntl();
18
20
  let t1;
@@ -28,42 +30,58 @@ function LayoutSwitch(t0) {
28
30
  $[3] = t2;
29
31
  } else t2 = $[3];
30
32
  let t3;
31
- if ($[4] !== t1 || $[5] !== t2) {
32
- t3 = {
33
- table: t1,
34
- cards: t2
35
- };
36
- $[4] = t1;
37
- $[5] = t2;
38
- $[6] = t3;
39
- } else t3 = $[6];
40
- const labels = t3;
33
+ if ($[4] !== intl) {
34
+ t3 = intl.formatMessage(messages.layoutGallery);
35
+ $[4] = intl;
36
+ $[5] = t3;
37
+ } else t3 = $[5];
41
38
  let t4;
42
- if ($[7] !== intl) {
43
- t4 = intl.formatMessage(messages.layout);
44
- $[7] = intl;
45
- $[8] = t4;
46
- } else t4 = $[8];
39
+ if ($[6] !== intl) {
40
+ t4 = intl.formatMessage(messages.layoutCalendar);
41
+ $[6] = intl;
42
+ $[7] = t4;
43
+ } else t4 = $[7];
47
44
  let t5;
48
- if ($[9] !== value) {
49
- t5 = [value];
50
- $[9] = value;
51
- $[10] = t5;
52
- } else t5 = $[10];
45
+ if ($[8] !== t1 || $[9] !== t2 || $[10] !== t3 || $[11] !== t4) {
46
+ t5 = {
47
+ table: t1,
48
+ cards: t2,
49
+ gallery: t3,
50
+ calendar: t4
51
+ };
52
+ $[8] = t1;
53
+ $[9] = t2;
54
+ $[10] = t3;
55
+ $[11] = t4;
56
+ $[12] = t5;
57
+ } else t5 = $[12];
58
+ const labels = t5;
53
59
  let t6;
54
- if ($[11] !== onChange) {
55
- t6 = (keys) => {
60
+ if ($[13] !== intl) {
61
+ t6 = intl.formatMessage(messages.layout);
62
+ $[13] = intl;
63
+ $[14] = t6;
64
+ } else t6 = $[14];
65
+ let t7;
66
+ if ($[15] !== value) {
67
+ t7 = [value];
68
+ $[15] = value;
69
+ $[16] = t7;
70
+ } else t7 = $[16];
71
+ let t8;
72
+ if ($[17] !== onChange) {
73
+ t8 = (keys) => {
56
74
  const [next] = [...keys];
57
75
  if (next !== void 0) onChange(String(next));
58
76
  };
59
- $[11] = onChange;
60
- $[12] = t6;
61
- } else t6 = $[12];
62
- let t7;
63
- if ($[13] !== labels || $[14] !== layouts) {
64
- let t8;
65
- if ($[16] !== labels) {
66
- t8 = (layout) => {
77
+ $[17] = onChange;
78
+ $[18] = t8;
79
+ } else t8 = $[18];
80
+ let t9;
81
+ if ($[19] !== labels || $[20] !== layouts) {
82
+ let t10;
83
+ if ($[22] !== labels) {
84
+ t10 = (layout) => {
67
85
  const label = labels[layout] ?? layout;
68
86
  return /* @__PURE__ */ jsx(Tooltip, {
69
87
  content: label,
@@ -75,32 +93,32 @@ function LayoutSwitch(t0) {
75
93
  })
76
94
  }, layout);
77
95
  };
78
- $[16] = labels;
79
- $[17] = t8;
80
- } else t8 = $[17];
81
- t7 = layouts.map(t8);
82
- $[13] = labels;
83
- $[14] = layouts;
84
- $[15] = t7;
85
- } else t7 = $[15];
86
- let t8;
87
- if ($[18] !== t4 || $[19] !== t5 || $[20] !== t6 || $[21] !== t7) {
88
- t8 = /* @__PURE__ */ jsx(ToggleButtonGroup, {
89
- "aria-label": t4,
96
+ $[22] = labels;
97
+ $[23] = t10;
98
+ } else t10 = $[23];
99
+ t9 = layouts.map(t10);
100
+ $[19] = labels;
101
+ $[20] = layouts;
102
+ $[21] = t9;
103
+ } else t9 = $[21];
104
+ let t10;
105
+ if ($[24] !== t6 || $[25] !== t7 || $[26] !== t8 || $[27] !== t9) {
106
+ t10 = /* @__PURE__ */ jsx(ToggleButtonGroup, {
107
+ "aria-label": t6,
90
108
  selectionMode: "single",
91
109
  disallowEmptySelection: true,
92
- selectedKeys: t5,
93
- onSelectionChange: t6,
110
+ selectedKeys: t7,
111
+ onSelectionChange: t8,
94
112
  className: Toolbar_module_default.layouts,
95
- children: t7
113
+ children: t9
96
114
  });
97
- $[18] = t4;
98
- $[19] = t5;
99
- $[20] = t6;
100
- $[21] = t7;
101
- $[22] = t8;
102
- } else t8 = $[22];
103
- return t8;
115
+ $[24] = t6;
116
+ $[25] = t7;
117
+ $[26] = t8;
118
+ $[27] = t9;
119
+ $[28] = t10;
120
+ } else t10 = $[28];
121
+ return t10;
104
122
  }
105
123
  //#endregion
106
124
  export { LayoutSwitch };
@@ -1 +1 @@
1
- {"version":3,"file":"LayoutSwitch.js","names":["LayoutGrid","LucideIcon","Rows3","Square","ToggleButton","ToggleButtonGroup","Icon","Tooltip","usePanneauIntl","messages","styles","ICONS","Record","table","cards","LayoutSwitchProps","layouts","value","onChange","layout","LayoutSwitch","t0","$","_c","intl","t1","formatMessage","layoutTable","t2","layoutCards","t3","labels","t4","t5","t6","keys","next","undefined","String","t7","t8","label","layoutButton","map","_c","styles"],"sources":["../../src/toolbar/LayoutSwitch.tsx"],"sourcesContent":["import { LayoutGrid, type LucideIcon, Rows3, Square } from 'lucide-react';\nimport { ToggleButton, ToggleButtonGroup } from 'react-aria-components';\n\nimport { Icon, Tooltip, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport styles from './Toolbar.module.css';\n\nconst ICONS: Record<string, LucideIcon> = { table: Rows3, cards: LayoutGrid };\n\nexport interface LayoutSwitchProps {\n layouts: readonly string[];\n value: string;\n onChange: (layout: string) => void;\n}\n\n/** Buttons to show the items as a table, as cards, or in a plugin's layout. */\nexport function LayoutSwitch({ layouts, value, onChange }: LayoutSwitchProps) {\n const intl = usePanneauIntl();\n const labels: Record<string, string> = {\n table: intl.formatMessage(messages.layoutTable),\n cards: intl.formatMessage(messages.layoutCards),\n };\n return (\n <ToggleButtonGroup\n aria-label={intl.formatMessage(messages.layout)}\n selectionMode=\"single\"\n disallowEmptySelection\n selectedKeys={[value]}\n onSelectionChange={(keys) => {\n const [next] = [...keys];\n if (next !== undefined) {\n onChange(String(next));\n }\n }}\n className={styles.layouts}\n >\n {layouts.map((layout) => {\n const label = labels[layout] ?? layout;\n return (\n <Tooltip key={layout} content={label}>\n <ToggleButton\n id={layout}\n aria-label={label}\n className={styles.layoutButton}\n >\n <Icon icon={ICONS[layout] ?? Square} />\n </ToggleButton>\n </Tooltip>\n );\n })}\n </ToggleButtonGroup>\n );\n}\n"],"mappings":";;;;;;;;AAQA,IAAMW,QAAoC;CAAEE,OAAOX;CAAOY,OAAOd;AAAW;;AAS5E,SAAOoB,aAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAsB,MAAA,EAAAP,SAAAC,OAAAC,aAAAG;CACzB,MAAAG,OAAahB,eAAe;CAAE,IAAAiB;CAAA,IAAAH,EAAA,OAAAE,MAAA;EAEnBC,KAAAD,KAAIE,cAAejB,SAAQkB,WAAY;EAACL,EAAA,KAAAE;EAAAF,EAAA,KAAAG;CAAA,OAAAA,KAAAH,EAAA;CAAA,IAAAM;CAAA,IAAAN,EAAA,OAAAE,MAAA;EACxCI,KAAAJ,KAAIE,cAAejB,SAAQoB,WAAY;EAACP,EAAA,KAAAE;EAAAF,EAAA,KAAAM;CAAA,OAAAA,KAAAN,EAAA;CAAA,IAAAQ;CAAA,IAAAR,EAAA,OAAAG,MAAAH,EAAA,OAAAM,IAAA;EAFZE,KAAA;GAAAjB,OAC5BY;GAAwCX,OACxCc;EACX;EAACN,EAAA,KAAAG;EAAAH,EAAA,KAAAM;EAAAN,EAAA,KAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAHD,MAAAS,SAAuCD;CAGrC,IAAAE;CAAA,IAAAV,EAAA,OAAAE,MAAA;EAGkBQ,KAAAR,KAAIE,cAAejB,SAAQU,MAAO;EAACG,EAAA,KAAAE;EAAAF,EAAA,KAAAU;CAAA,OAAAA,KAAAV,EAAA;CAAA,IAAAW;CAAA,IAAAX,EAAA,OAAAL,OAAA;EAGjCgB,KAAA,CAAChB,KAAK;EAACK,EAAA,KAAAL;EAAAK,EAAA,MAAAW;CAAA,OAAAA,KAAAX,EAAA;CAAA,IAAAY;CAAA,IAAAZ,EAAA,QAAAJ,UAAA;EACFgB,MAAAC,SAAA;GACf,MAAA,CAAAC,QAAe,CAAA,GAAID,IAAI;GACvB,IAAIC,SAASC,KAAAA,GACTnB,SAASoB,OAAOF,IAAI,CAAC;EACxB;EACJd,EAAA,MAAAJ;EAAAI,EAAA,MAAAY;CAAA,OAAAA,KAAAZ,EAAA;CAAA,IAAAiB;CAAA,IAAAjB,EAAA,QAAAS,UAAAT,EAAA,QAAAN,SAAA;EAAA,IAAAwB;EAAA,IAAAlB,EAAA,QAAAS,QAAA;GAGYS,MAAArB,WAAA;IACT,MAAAsB,QAAcV,OAAOZ,WAAPA;IAAyB,OAEnC,oBAAC,SAAD;KAA+BsB,SAAAA;KAC3B,UAAA,oBAAC,cAAD;MACQtB,IAAAA;MACQsB,cAAAA;MACD,WAAA/B,uBAAMgC;MAEjB,UAAA,oBAAC,MAAD,EAAY,MAAA/B,MAAMQ,WAANhB,OAAuB,CAAA;KAL1B,CAAA;IADT,GAAMgB,MAAN;GAQE;GAEjBG,EAAA,MAAAS;GAAAT,EAAA,MAAAkB;EAAA,OAAAA,KAAAlB,EAAA;EAbAiB,KAAAvB,QAAO2B,IAAKH,EAaZ;EAAClB,EAAA,MAAAS;EAAAT,EAAA,MAAAN;EAAAM,EAAA,MAAAiB;CAAA,OAAAA,KAAAjB,EAAA;CAAA,IAAAkB;CAAA,IAAAlB,EAAA,QAAAU,MAAAV,EAAA,QAAAW,MAAAX,EAAA,QAAAY,MAAAZ,EAAA,QAAAiB,IAAA;EA1BNC,KAAA,oBAAC,mBAAD;GACgB,cAAAR;GACE,eAAA;GACd,wBAAA;GACc,cAAAC;GACK,mBAAAC;GAMR,WAAAxB,uBAAMM;GAEhBuB,UAAAA;EAba,CAAA;EA2BEjB,EAAA,MAAAU;EAAAV,EAAA,MAAAW;EAAAX,EAAA,MAAAY;EAAAZ,EAAA,MAAAiB;EAAAjB,EAAA,MAAAkB;CAAA,OAAAA,KAAAlB,EAAA;CAAA,OA3BpBkB;AA2BoB"}
1
+ {"version":3,"file":"LayoutSwitch.js","names":["CalendarDays","Images","LayoutGrid","LucideIcon","Rows3","Square","ToggleButton","ToggleButtonGroup","Icon","Tooltip","usePanneauIntl","messages","styles","ICONS","Record","table","cards","gallery","calendar","LayoutSwitchProps","layouts","value","onChange","layout","LayoutSwitch","t0","$","_c","intl","t1","formatMessage","layoutTable","t2","layoutCards","t3","layoutGallery","t4","layoutCalendar","t5","labels","t6","t7","t8","keys","next","undefined","String","t9","t10","label","layoutButton","map","_c","styles"],"sources":["../../src/toolbar/LayoutSwitch.tsx"],"sourcesContent":["import { CalendarDays, Images, LayoutGrid, type LucideIcon, Rows3, Square } from 'lucide-react';\nimport { ToggleButton, ToggleButtonGroup } from 'react-aria-components';\n\nimport { Icon, Tooltip, usePanneauIntl } from '@panneau/ui';\n\nimport { messages } from '../messages';\nimport styles from './Toolbar.module.css';\n\nconst ICONS: Record<string, LucideIcon> = {\n table: Rows3,\n cards: LayoutGrid,\n gallery: Images,\n calendar: CalendarDays,\n};\n\nexport interface LayoutSwitchProps {\n layouts: readonly string[];\n value: string;\n onChange: (layout: string) => void;\n}\n\n/** Buttons to show the items as a table, as cards, or in a plugin's layout. */\nexport function LayoutSwitch({ layouts, value, onChange }: LayoutSwitchProps) {\n const intl = usePanneauIntl();\n const labels: Record<string, string> = {\n table: intl.formatMessage(messages.layoutTable),\n cards: intl.formatMessage(messages.layoutCards),\n gallery: intl.formatMessage(messages.layoutGallery),\n calendar: intl.formatMessage(messages.layoutCalendar),\n };\n return (\n <ToggleButtonGroup\n aria-label={intl.formatMessage(messages.layout)}\n selectionMode=\"single\"\n disallowEmptySelection\n selectedKeys={[value]}\n onSelectionChange={(keys) => {\n const [next] = [...keys];\n if (next !== undefined) {\n onChange(String(next));\n }\n }}\n className={styles.layouts}\n >\n {layouts.map((layout) => {\n const label = labels[layout] ?? layout;\n return (\n <Tooltip key={layout} content={label}>\n <ToggleButton\n id={layout}\n aria-label={label}\n className={styles.layoutButton}\n >\n <Icon icon={ICONS[layout] ?? Square} />\n </ToggleButton>\n </Tooltip>\n );\n })}\n </ToggleButtonGroup>\n );\n}\n"],"mappings":"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"}
@@ -70,3 +70,39 @@
70
70
  width: 100%;
71
71
  }
72
72
  }
73
+
74
+ .panneau-toolbar-columns {
75
+ display: flex;
76
+ flex-direction: column;
77
+ align-items: flex-start;
78
+ gap: var(--panneau-space-2);
79
+ min-width: 14rem;
80
+ max-height: 24rem;
81
+ overflow-y: auto;
82
+ }
83
+
84
+ .panneau-toolbar-column-list {
85
+ display: flex;
86
+ flex-direction: column;
87
+ align-self: stretch;
88
+ gap: var(--panneau-space-1);
89
+ margin: 0;
90
+ padding: 0;
91
+ list-style: none;
92
+ }
93
+
94
+ .panneau-toolbar-column {
95
+ display: flex;
96
+ align-items: center;
97
+ justify-content: space-between;
98
+ gap: var(--panneau-space-2);
99
+ min-height: var(--panneau-control-height-sm);
100
+ }
101
+
102
+ .panneau-toolbar-column-label {
103
+ flex: 1;
104
+ }
105
+
106
+ .panneau-toolbar-column-moves {
107
+ display: inline-flex;
108
+ }
@@ -7,6 +7,11 @@ var perPage = "panneau-toolbar-per-page";
7
7
  var layouts = "panneau-toolbar-layouts";
8
8
  var layoutButton = "panneau-toolbar-layout-button";
9
9
  var sort = "panneau-toolbar-sort";
10
+ var columns = "panneau-toolbar-columns";
11
+ var columnList = "panneau-toolbar-column-list";
12
+ var column = "panneau-toolbar-column";
13
+ var columnLabel = "panneau-toolbar-column-label";
14
+ var columnMoves = "panneau-toolbar-column-moves";
10
15
  var Toolbar_module_default = {
11
16
  search,
12
17
  pagination,
@@ -14,9 +19,14 @@ var Toolbar_module_default = {
14
19
  perPage,
15
20
  layouts,
16
21
  layoutButton,
17
- sort
22
+ sort,
23
+ columns,
24
+ columnList,
25
+ column,
26
+ columnLabel,
27
+ columnMoves
18
28
  };
19
29
  //#endregion
20
- export { Toolbar_module_default as default, layoutButton, layouts, pages, pagination, perPage, search, sort };
30
+ export { column, columnLabel, columnList, columnMoves, columns, Toolbar_module_default as default, layoutButton, layouts, pages, pagination, perPage, search, sort };
21
31
 
22
32
  //# sourceMappingURL=Toolbar.module.js.map
@@ -1 +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":""}
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\n.columns {\n display: flex;\n flex-direction: column;\n align-items: flex-start;\n gap: var(--panneau-space-2);\n min-width: 14rem;\n max-height: 24rem;\n overflow-y: auto;\n}\n\n.columnList {\n display: flex;\n flex-direction: column;\n align-self: stretch;\n gap: var(--panneau-space-1);\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.column {\n display: flex;\n align-items: center;\n justify-content: space-between;\n gap: var(--panneau-space-2);\n min-height: var(--panneau-control-height-sm);\n}\n\n.columnLabel {\n flex: 1;\n}\n\n.columnMoves {\n display: inline-flex;\n}\n"],"mappings":""}
package/dist/types.d.ts CHANGED
@@ -28,6 +28,10 @@ export interface ListColumn {
28
28
  sortable?: boolean;
29
29
  width?: number | string;
30
30
  align?: 'start' | 'center' | 'end';
31
+ /** Not shown until the user shows it, from the columns of the list (decision 0042). */
32
+ hidden?: boolean;
33
+ /** `false`: always shown. The user can move it, not hide it. */
34
+ hideable?: boolean;
31
35
  /** Renders the cell, instead of a display. */
32
36
  render?: (item: ListItem) => ReactNode;
33
37
  }
@@ -72,6 +76,20 @@ export type ListActionPreviewer = (event: ListActionEvent) => Promise<ListAction
72
76
  * cancels its parameters). `useActionRunner()` of `@panneau/actions` is such a handler.
73
77
  */
74
78
  export type ListActionHandler = (event: ListActionEvent) => unknown;
79
+ /** A value changed in place, in a cell of the list (decision 0043). */
80
+ export interface ListInlineEditEvent {
81
+ /** The item, with the version the value was edited from. */
82
+ item: ListItem;
83
+ /** The field the cell edits. */
84
+ field: Field;
85
+ value: unknown;
86
+ }
87
+ /**
88
+ * Saves one field of an item, changed in place, and resolves with the updated item. It rejects
89
+ * with a problem, or an error with a `problem` (as the errors of `@panneau/data`): a `422` shows
90
+ * its messages on the cell, and a `412` with the `current` item offers to keep it or save over it.
91
+ */
92
+ export type ListInlineEditHandler = (event: ListInlineEditEvent) => Promise<ListItem>;
75
93
  /** Props of a filter control. */
76
94
  export interface FilterControlProps {
77
95
  filter: Filter;
@@ -90,6 +108,21 @@ export interface FilterControlProps {
90
108
  }
91
109
  /** A filter control, by filter type (`select`, `date`). */
92
110
  export type FilterEntry = ComponentType<FilterControlProps>;
111
+ /** What the `calendar` layout shows: the month of its items, and how to change it (decision 0044). */
112
+ export interface ListCalendarProps {
113
+ /** The `date` or `datetime` field each item is shown on the day of. */
114
+ field: string;
115
+ /** The month shown (`2026-11`). */
116
+ month: string;
117
+ onMonthChange: (month: string) => void;
118
+ /**
119
+ * When the month has more items than the list got: how many match (`null` when the backend
120
+ * doesn't count them).
121
+ */
122
+ more: {
123
+ total: number | null;
124
+ } | null;
125
+ }
93
126
  /** Props of a list layout: renders the items of the current page. */
94
127
  export interface ListLayoutProps {
95
128
  items: readonly ListItem[];
@@ -115,6 +148,15 @@ export interface ListLayoutProps {
115
148
  label: string;
116
149
  /** The checkbox that selects the page, for layouts that show it in a header. */
117
150
  pageSelection: ReactNode;
151
+ /** The URL of the image of an item (`itemImage` of the resource), for the gallery. */
152
+ getItemImage?: ((item: ListItem) => string | null) | undefined;
153
+ /** The month of the calendar, in the `calendar` layout. */
154
+ calendar?: ListCalendarProps | undefined;
155
+ /**
156
+ * Wraps the content of a cell (its value, or the title's link): a column that edits its
157
+ * field in place does it there (decision 0043). Without it, the content is the cell.
158
+ */
159
+ renderCell?: ((item: ListItem, column: ListColumn, content: ReactNode) => ReactNode) | undefined;
118
160
  }
119
161
  /** A list layout, by id (`table`, `cards`). */
120
162
  export type ListLayoutEntry = ComponentType<ListLayoutProps>;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/values.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { Field, Option } from '@panneau/protocol';
2
2
  import type { ListColumn, ListItem } from './types.js';
3
+ export declare function isRecord(value: unknown): value is Record<string, unknown>;
3
4
  /**
4
5
  * The value of a localized field in a locale: the locale (`fr-CA`), its language (`fr`), then the
5
6
  * first filled locale. Other values are returned as they are.
@@ -1 +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,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAExF"}
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;AAEpD,wBAAgB,QAAQ,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzE;AAED;;;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,oFAAoF;AACpF,wBAAgB,UAAU,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEzF;AAED,2FAA2F;AAC3F,wBAAgB,cAAc,CAAC,OAAO,EAAE,SAAS,MAAM,EAAE,EAAE,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAExF"}
package/dist/values.js CHANGED
@@ -51,6 +51,6 @@ function getOptionLabel(options, value) {
51
51
  return findOption(options, value)?.label ?? null;
52
52
  }
53
53
  //#endregion
54
- export { findOption, getColumnValue, getFieldOptions, getLocalizedValue, getOptionLabel, isLocalized, toText };
54
+ export { findOption, getColumnValue, getFieldOptions, getLocalizedValue, getOptionLabel, isLocalized, isRecord, toText };
55
55
 
56
56
  //# sourceMappingURL=values.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"values.js","names":["Field","Option","ListColumn","ListItem","isRecord","value","Record","Array","isArray","getLocalizedValue","locale","language","split","filled","candidate","undefined","Object","values","find","isLocalized","field","localized","getColumnValue","item","column","name","id","toText","String","map","entry","filter","text","join","label","getFieldOptions","options","findOption","getOptionLabel"],"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 option of a value, matched as a string (values from the URL are strings). */\nexport function findOption(options: readonly Option[], value: unknown): Option | undefined {\n return options.find((candidate) => String(candidate.value) === String(value));\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 return findOption(options, value)?.label ?? null;\n}\n"],"mappings":";AAIA,SAASI,SAASC,OAAkD;CAChE,OAAOA,UAAU,QAAQ,OAAOA,UAAU,YAAY,CAACE,MAAMC,QAAQH,KAAK;AAC9E;;;;;AAMA,SAAgBI,kBAAkBJ,OAAgBK,QAAyB;CACvE,IAAI,CAACN,SAASC,KAAK,GACf,OAAOA;CAEX,MAAMM,WAAWD,OAAOE,MAAM,GAAG,CAAC,CAAC,MAAMF;CACzC,MAAMG,UAAUC,cACZA,cAAcC,KAAAA,KAAaD,cAAc,QAAQA,cAAc;CACnE,IAAID,OAAOR,MAAMK,OAAO,GACpB,OAAOL,MAAMK;CAEjB,IAAIG,OAAOR,MAAMM,SAAS,GACtB,OAAON,MAAMM;CAEjB,OAAOK,OAAOC,OAAOZ,KAAK,CAAC,CAACa,KAAKL,MAAM,KAAK;AAChD;;AAGA,SAAgBM,YAAYC,OAA0C;CAClE,OAAOA,OAAOC,cAAc;AAChC;;AAGA,SAAgBC,eAAeC,MAAgBC,QAAoBd,QAAyB;CACxF,MAAML,QAAQkB,KAAKC,OAAOJ,OAAOK,QAAQD,OAAOE;CAChD,OAAOP,YAAYK,OAAOJ,KAAK,IAAIX,kBAAkBJ,OAAOK,MAAM,IAAIL;AAC1E;;;;;AAMA,SAAgBsB,OAAOtB,OAAgBK,QAAwB;CAC3D,IAAIL,UAAU,QAAQA,UAAUU,KAAAA,GAC5B,OAAO;CAEX,IAAI,OAAOV,UAAU,UACjB,OAAOA;CAEX,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAC9C,OAAOuB,OAAOvB,KAAK;CAEvB,IAAIE,MAAMC,QAAQH,KAAK,GACnB,OAAOA,MACFwB,KAAKC,UAAUH,OAAOG,OAAOpB,MAAM,CAAC,CAAC,CACrCqB,QAAQC,SAASA,SAAS,EAAE,CAAC,CAC7BC,KAAK,IAAI;CAElB,IAAI7B,SAASC,KAAK,GAAG;EACjB,IAAI,OAAOA,MAAM6B,UAAU,UACvB,OAAO7B,MAAM6B;EAEjB,OAAOP,OAAOlB,kBAAkBJ,OAAOK,MAAM,GAAGA,MAAM;CAC1D;CACA,OAAO;AACX;;AAGA,SAAgByB,gBAAgBf,OAAoD;CAChF,OAAOA,OAAOgB,WAAW,CAAA;AAC7B;;AAGA,SAAgBC,WAAWD,SAA4B/B,OAAoC;CACvF,OAAO+B,QAAQlB,MAAMJ,cAAcc,OAAOd,UAAUT,KAAK,MAAMuB,OAAOvB,KAAK,CAAC;AAChF;;AAGA,SAAgBiC,eAAeF,SAA4B/B,OAA+B;CACtF,OAAOgC,WAAWD,SAAS/B,KAAK,CAAC,EAAE6B,SAAS;AAChD"}
1
+ {"version":3,"file":"values.js","names":["Field","Option","ListColumn","ListItem","isRecord","value","Record","Array","isArray","getLocalizedValue","locale","language","split","filled","candidate","undefined","Object","values","find","isLocalized","field","localized","getColumnValue","item","column","name","id","toText","String","map","entry","filter","text","join","label","getFieldOptions","options","findOption","getOptionLabel"],"sources":["../src/values.ts"],"sourcesContent":["import type { Field, Option } from '@panneau/protocol';\n\nimport type { ListColumn, ListItem } from './types';\n\nexport function 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 option of a value, matched as a string (values from the URL are strings). */\nexport function findOption(options: readonly Option[], value: unknown): Option | undefined {\n return options.find((candidate) => String(candidate.value) === String(value));\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 return findOption(options, value)?.label ?? null;\n}\n"],"mappings":";AAIA,SAAgBI,SAASC,OAAkD;CACvE,OAAOA,UAAU,QAAQ,OAAOA,UAAU,YAAY,CAACE,MAAMC,QAAQH,KAAK;AAC9E;;;;;AAMA,SAAgBI,kBAAkBJ,OAAgBK,QAAyB;CACvE,IAAI,CAACN,SAASC,KAAK,GACf,OAAOA;CAEX,MAAMM,WAAWD,OAAOE,MAAM,GAAG,CAAC,CAAC,MAAMF;CACzC,MAAMG,UAAUC,cACZA,cAAcC,KAAAA,KAAaD,cAAc,QAAQA,cAAc;CACnE,IAAID,OAAOR,MAAMK,OAAO,GACpB,OAAOL,MAAMK;CAEjB,IAAIG,OAAOR,MAAMM,SAAS,GACtB,OAAON,MAAMM;CAEjB,OAAOK,OAAOC,OAAOZ,KAAK,CAAC,CAACa,KAAKL,MAAM,KAAK;AAChD;;AAGA,SAAgBM,YAAYC,OAA0C;CAClE,OAAOA,OAAOC,cAAc;AAChC;;AAGA,SAAgBC,eAAeC,MAAgBC,QAAoBd,QAAyB;CACxF,MAAML,QAAQkB,KAAKC,OAAOJ,OAAOK,QAAQD,OAAOE;CAChD,OAAOP,YAAYK,OAAOJ,KAAK,IAAIX,kBAAkBJ,OAAOK,MAAM,IAAIL;AAC1E;;;;;AAMA,SAAgBsB,OAAOtB,OAAgBK,QAAwB;CAC3D,IAAIL,UAAU,QAAQA,UAAUU,KAAAA,GAC5B,OAAO;CAEX,IAAI,OAAOV,UAAU,UACjB,OAAOA;CAEX,IAAI,OAAOA,UAAU,YAAY,OAAOA,UAAU,WAC9C,OAAOuB,OAAOvB,KAAK;CAEvB,IAAIE,MAAMC,QAAQH,KAAK,GACnB,OAAOA,MACFwB,KAAKC,UAAUH,OAAOG,OAAOpB,MAAM,CAAC,CAAC,CACrCqB,QAAQC,SAASA,SAAS,EAAE,CAAC,CAC7BC,KAAK,IAAI;CAElB,IAAI7B,SAASC,KAAK,GAAG;EACjB,IAAI,OAAOA,MAAM6B,UAAU,UACvB,OAAO7B,MAAM6B;EAEjB,OAAOP,OAAOlB,kBAAkBJ,OAAOK,MAAM,GAAGA,MAAM;CAC1D;CACA,OAAO;AACX;;AAGA,SAAgByB,gBAAgBf,OAAoD;CAChF,OAAOA,OAAOgB,WAAW,CAAA;AAC7B;;AAGA,SAAgBC,WAAWD,SAA4B/B,OAAoC;CACvF,OAAO+B,QAAQlB,MAAMJ,cAAcc,OAAOd,UAAUT,KAAK,MAAMuB,OAAOvB,KAAK,CAAC;AAChF;;AAGA,SAAgBiC,eAAeF,SAA4B/B,OAA+B;CACtF,OAAOgC,WAAWD,SAAS/B,KAAK,CAAC,EAAE6B,SAAS;AAChD"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panneau/lists",
3
- "version": "5.0.0-alpha.12",
3
+ "version": "5.0.0-alpha.14",
4
4
  "description": "Lists of Panneau: columns with displays, table and cards layouts, sorting, filters, search, pagination, selection and actions, driven by the list state of @panneau/core.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -37,14 +37,14 @@
37
37
  "react-intl": "^12.0.0"
38
38
  },
39
39
  "dependencies": {
40
- "@panneau/core": "5.0.0-alpha.12",
41
- "@panneau/fields": "5.0.0-alpha.12",
42
- "@panneau/intl": "5.0.0-alpha.12",
43
- "@panneau/protocol": "5.0.0-alpha.12",
44
- "@panneau/ui": "5.0.0-alpha.12",
40
+ "@panneau/core": "5.0.0-alpha.14",
41
+ "@panneau/fields": "5.0.0-alpha.14",
42
+ "@panneau/intl": "5.0.0-alpha.14",
43
+ "@panneau/protocol": "5.0.0-alpha.14",
44
+ "@panneau/ui": "5.0.0-alpha.14",
45
45
  "lucide-react": "^1.57.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@panneau/data": "5.0.0-alpha.12"
48
+ "@panneau/data": "5.0.0-alpha.14"
49
49
  }
50
50
  }