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

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.
@@ -24,6 +24,17 @@
24
24
  overflow-wrap: anywhere;
25
25
  }
26
26
 
27
+ /* A group: its label over its values, which are indented. */
28
+ .panneau-item-details-group > .panneau-item-details-label {
29
+ color: var(--panneau-color-text);
30
+ font-weight: var(--panneau-font-weight-medium);
31
+ }
32
+
33
+ .panneau-item-details-nested {
34
+ padding-inline-start: var(--panneau-space-3);
35
+ border-inline-start: var(--panneau-border-width) solid var(--panneau-color-border);
36
+ }
37
+
27
38
  /* Wide enough: the label and its value side by side. */
28
39
  @container panneau-item-details (min-width: 30rem) {
29
40
  .panneau-item-details-entry {
@@ -31,4 +42,9 @@
31
42
  grid-template-columns: minmax(8rem, 30%) minmax(0, 1fr);
32
43
  gap: var(--panneau-space-3);
33
44
  }
45
+
46
+ .panneau-item-details-group {
47
+ display: flex;
48
+ gap: var(--panneau-space-2);
49
+ }
34
50
  }
@@ -1,9 +1,17 @@
1
1
  import type { DisplayEntry, ListColumn, ListItem } from './types.js';
2
+ /** A value of the details, or a group of values under its label. */
3
+ export interface ItemDetailsColumn extends ListColumn {
4
+ /**
5
+ * The values of a group (a `group` field): read in the value of the column, an object, and
6
+ * listed under its label.
7
+ */
8
+ columns?: readonly ItemDetailsColumn[];
9
+ }
2
10
  export interface ItemDetailsProps {
3
11
  /** The item. `undefined` while it loads: the labels, with a skeleton of each value. */
4
12
  item: ListItem | undefined;
5
13
  /** The values to show, with their label and display, in order. */
6
- columns: readonly ListColumn[];
14
+ columns: readonly ItemDetailsColumn[];
7
15
  /** Displays by name, over the built-in ones and those of the plugins. */
8
16
  displays?: Readonly<Record<string, DisplayEntry>>;
9
17
  'aria-label'?: string;
@@ -11,8 +19,9 @@ export interface ItemDetailsProps {
11
19
  }
12
20
  /**
13
21
  * The values of one item, each with its label, shown with the displays of the lists: for the
14
- * details of an item next to its list, or anywhere a read-only view of it is needed. While the
15
- * item loads, it draws the labels with a skeleton of each value (decision 0034).
22
+ * details of an item next to its list, or anywhere a read-only view of it is needed. A column with
23
+ * `columns` is a group, whose values are listed under its label. While the item loads, it draws
24
+ * the labels with a skeleton of each value (decision 0034).
16
25
  */
17
26
  export declare function ItemDetails({ item, columns, displays, 'aria-label': ariaLabel, className, }: ItemDetailsProps): import("react").JSX.Element;
18
27
  //# sourceMappingURL=ItemDetails.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemDetails.d.ts","sourceRoot":"","sources":["../src/ItemDetails.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAMlE,MAAM,WAAW,gBAAgB;IAC7B,uFAAuF;IACvF,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,kEAAkE;IAClE,OAAO,EAAE,SAAS,UAAU,EAAE,CAAC;IAC/B,yEAAyE;IACzE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EACxB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,YAAY,EAAE,SAAS,EACvB,SAAS,GACZ,EAAE,gBAAgB,+BA6BlB"}
1
+ {"version":3,"file":"ItemDetails.d.ts","sourceRoot":"","sources":["../src/ItemDetails.tsx"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,YAAY,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAOlE,oEAAoE;AACpE,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACjD;;;OAGG;IACH,OAAO,CAAC,EAAE,SAAS,iBAAiB,EAAE,CAAC;CAC1C;AAED,MAAM,WAAW,gBAAgB;IAC7B,uFAAuF;IACvF,IAAI,EAAE,QAAQ,GAAG,SAAS,CAAC;IAC3B,kEAAkE;IAClE,OAAO,EAAE,SAAS,iBAAiB,EAAE,CAAC;IACtC,yEAAyE;IACzE,QAAQ,CAAC,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC,CAAC;IAClD,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,CAAC,EAAE,MAAM,CAAC;CACtB;AAMD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,EACxB,IAAI,EACJ,OAAO,EACP,QAAQ,EACR,YAAY,EAAE,SAAS,EACvB,SAAS,GACZ,EAAE,gBAAgB,+BA0DlB"}
@@ -1,4 +1,5 @@
1
1
  import { messages } from "./messages.js";
2
+ import { getColumnValue } from "./values.js";
2
3
  import { cx } from "./cx.js";
3
4
  import ItemDetails_module_default from "./ItemDetails.module.js";
4
5
  import { useRenderValue } from "./useRenderValue.js";
@@ -14,87 +15,116 @@ var WIDTHS = [
14
15
  "30%",
15
16
  "65%"
16
17
  ];
18
+ function isRecord(value) {
19
+ return value !== null && typeof value === "object" && !Array.isArray(value);
20
+ }
17
21
  /**
18
22
  * The values of one item, each with its label, shown with the displays of the lists: for the
19
- * details of an item next to its list, or anywhere a read-only view of it is needed. While the
20
- * item loads, it draws the labels with a skeleton of each value (decision 0034).
23
+ * details of an item next to its list, or anywhere a read-only view of it is needed. A column with
24
+ * `columns` is a group, whose values are listed under its label. While the item loads, it draws
25
+ * the labels with a skeleton of each value (decision 0034).
21
26
  */
22
27
  function ItemDetails(t0) {
23
- const $ = c(20);
28
+ const $ = c(22);
24
29
  const { item, columns, displays, "aria-label": ariaLabel, className } = t0;
25
30
  const intl = usePanneauIntl();
26
31
  const renderValue = useRenderValue(displays);
27
32
  let t1;
28
- if ($[0] !== className) {
29
- t1 = cx(ItemDetails_module_default.details, className);
30
- $[0] = className;
31
- $[1] = t1;
32
- } else t1 = $[1];
33
33
  let t2;
34
- if ($[2] !== columns || $[3] !== item || $[4] !== renderValue) {
35
- let t3;
36
- if ($[6] !== item || $[7] !== renderValue) {
37
- t3 = (column, index) => /* @__PURE__ */ jsxs("div", {
34
+ let t3;
35
+ if ($[0] !== ariaLabel || $[1] !== className || $[2] !== columns || $[3] !== intl || $[4] !== item || $[5] !== renderValue) {
36
+ const renderEntries = (entryItem, entryColumns) => entryColumns.map((column, index) => {
37
+ const label = /* @__PURE__ */ jsx("dt", {
38
+ className: ItemDetails_module_default.label,
39
+ children: column.label ?? column.id
40
+ });
41
+ if (column.columns !== void 0) {
42
+ const value = entryItem !== void 0 ? getColumnValue(entryItem, column, intl.locale) : void 0;
43
+ const groupItem = entryItem !== void 0 ? {
44
+ ...isRecord(value) ? value : {},
45
+ id: entryItem.id
46
+ } : void 0;
47
+ return /* @__PURE__ */ jsxs("div", {
48
+ className: cx(ItemDetails_module_default.entry, ItemDetails_module_default.group),
49
+ children: [label, /* @__PURE__ */ jsx("dd", {
50
+ className: ItemDetails_module_default.value,
51
+ children: /* @__PURE__ */ jsx("dl", {
52
+ className: cx(ItemDetails_module_default.details, ItemDetails_module_default.nested),
53
+ children: renderEntries(groupItem, column.columns)
54
+ })
55
+ })]
56
+ }, column.id);
57
+ }
58
+ return /* @__PURE__ */ jsxs("div", {
38
59
  className: ItemDetails_module_default.entry,
39
- children: [/* @__PURE__ */ jsx("dt", {
40
- className: ItemDetails_module_default.label,
41
- children: column.label ?? column.id
42
- }), /* @__PURE__ */ jsx("dd", {
60
+ children: [label, /* @__PURE__ */ jsx("dd", {
43
61
  className: ItemDetails_module_default.value,
44
- children: item !== void 0 ? renderValue(item, column) : /* @__PURE__ */ jsx(Skeleton, { width: WIDTHS[index % WIDTHS.length] })
62
+ children: entryItem !== void 0 ? renderValue(entryItem, column) : /* @__PURE__ */ jsx(Skeleton, { width: WIDTHS[index % WIDTHS.length] })
45
63
  })]
46
64
  }, column.id);
47
- $[6] = item;
48
- $[7] = renderValue;
49
- $[8] = t3;
50
- } else t3 = $[8];
51
- t2 = columns.map(t3);
65
+ });
66
+ t1 = ariaLabel;
67
+ if ($[9] !== className) {
68
+ t2 = cx(ItemDetails_module_default.details, className);
69
+ $[9] = className;
70
+ $[10] = t2;
71
+ } else t2 = $[10];
72
+ t3 = renderEntries(item, columns);
73
+ $[0] = ariaLabel;
74
+ $[1] = className;
52
75
  $[2] = columns;
53
- $[3] = item;
54
- $[4] = renderValue;
55
- $[5] = t2;
56
- } else t2 = $[5];
57
- let t3;
58
- if ($[9] !== ariaLabel || $[10] !== t1 || $[11] !== t2) {
59
- t3 = /* @__PURE__ */ jsx("dl", {
60
- "aria-label": ariaLabel,
61
- className: t1,
62
- children: t2
76
+ $[3] = intl;
77
+ $[4] = item;
78
+ $[5] = renderValue;
79
+ $[6] = t1;
80
+ $[7] = t2;
81
+ $[8] = t3;
82
+ } else {
83
+ t1 = $[6];
84
+ t2 = $[7];
85
+ t3 = $[8];
86
+ }
87
+ let t4;
88
+ if ($[11] !== t1 || $[12] !== t2 || $[13] !== t3) {
89
+ t4 = /* @__PURE__ */ jsx("dl", {
90
+ "aria-label": t1,
91
+ className: t2,
92
+ children: t3
63
93
  });
64
- $[9] = ariaLabel;
65
- $[10] = t1;
66
- $[11] = t2;
67
- $[12] = t3;
68
- } else t3 = $[12];
69
- const details = t3;
94
+ $[11] = t1;
95
+ $[12] = t2;
96
+ $[13] = t3;
97
+ $[14] = t4;
98
+ } else t4 = $[14];
99
+ const details = t4;
70
100
  if (item === void 0) {
71
- let t4;
72
- if ($[13] !== intl) {
73
- t4 = intl.formatMessage(messages.loadingItem);
74
- $[13] = intl;
75
- $[14] = t4;
76
- } else t4 = $[14];
77
101
  let t5;
78
- if ($[15] !== details) {
79
- t5 = /* @__PURE__ */ jsx("div", {
102
+ if ($[15] !== intl) {
103
+ t5 = intl.formatMessage(messages.loadingItem);
104
+ $[15] = intl;
105
+ $[16] = t5;
106
+ } else t5 = $[16];
107
+ let t6;
108
+ if ($[17] !== details) {
109
+ t6 = /* @__PURE__ */ jsx("div", {
80
110
  inert: true,
81
111
  "aria-hidden": "true",
82
112
  children: details
83
113
  });
84
- $[15] = details;
85
- $[16] = t5;
86
- } else t5 = $[16];
87
- let t6;
88
- if ($[17] !== t4 || $[18] !== t5) {
89
- t6 = /* @__PURE__ */ jsx(LoadingRegion, {
90
- label: t4,
91
- children: t5
114
+ $[17] = details;
115
+ $[18] = t6;
116
+ } else t6 = $[18];
117
+ let t7;
118
+ if ($[19] !== t5 || $[20] !== t6) {
119
+ t7 = /* @__PURE__ */ jsx(LoadingRegion, {
120
+ label: t5,
121
+ children: t6
92
122
  });
93
- $[17] = t4;
94
- $[18] = t5;
95
- $[19] = t6;
96
- } else t6 = $[19];
97
- return t6;
123
+ $[19] = t5;
124
+ $[20] = t6;
125
+ $[21] = t7;
126
+ } else t7 = $[21];
127
+ return t7;
98
128
  }
99
129
  return details;
100
130
  }
@@ -1 +1 @@
1
- {"version":3,"file":"ItemDetails.js","names":["LoadingRegion","Skeleton","usePanneauIntl","styles","cx","messages","DisplayEntry","ListColumn","ListItem","useRenderValue","WIDTHS","ItemDetailsProps","item","columns","displays","Readonly","Record","className","ItemDetails","t0","$","_c","ariaLabel","intl","renderValue","t1","details","t2","t3","column","index","id","entry","label","value","undefined","length","map","t4","formatMessage","loadingItem","t5","t6","_c","styles"],"sources":["../src/ItemDetails.tsx"],"sourcesContent":["import { LoadingRegion, Skeleton, usePanneauIntl } from '@panneau/ui';\n\nimport styles from './ItemDetails.module.css';\nimport { cx } from './cx';\nimport { messages } from './messages';\nimport type { DisplayEntry, ListColumn, ListItem } from './types';\nimport { useRenderValue } from './useRenderValue';\n\n/** Widths of the values of a skeleton, varied so they read as text. */\nconst WIDTHS = ['70%', '40%', '55%', '30%', '65%'];\n\nexport interface ItemDetailsProps {\n /** The item. `undefined` while it loads: the labels, with a skeleton of each value. */\n item: ListItem | undefined;\n /** The values to show, with their label and display, in order. */\n columns: readonly ListColumn[];\n /** Displays by name, over the built-in ones and those of the plugins. */\n displays?: Readonly<Record<string, DisplayEntry>>;\n 'aria-label'?: string;\n className?: string;\n}\n\n/**\n * The values of one item, each with its label, shown with the displays of the lists: for the\n * details of an item next to its list, or anywhere a read-only view of it is needed. While the\n * item loads, it draws the labels with a skeleton of each value (decision 0034).\n */\nexport function ItemDetails({\n item,\n columns,\n displays,\n 'aria-label': ariaLabel,\n className,\n}: ItemDetailsProps) {\n const intl = usePanneauIntl();\n const renderValue = useRenderValue(displays);\n const details = (\n <dl aria-label={ariaLabel} className={cx(styles.details, className)}>\n {columns.map((column, index) => (\n <div key={column.id} className={styles.entry}>\n <dt className={styles.label}>{column.label ?? column.id}</dt>\n <dd className={styles.value}>\n {item !== undefined ? (\n renderValue(item, column)\n ) : (\n <Skeleton width={WIDTHS[index % WIDTHS.length]} />\n )}\n </dd>\n </div>\n ))}\n </dl>\n );\n if (item === undefined) {\n return (\n <LoadingRegion label={intl.formatMessage(messages.loadingItem)}>\n <div inert aria-hidden=\"true\">\n {details}\n </div>\n </LoadingRegion>\n );\n }\n return details;\n}\n"],"mappings":";;;;;;;;;AASA,IAAMU,SAAS;CAAC;CAAO;CAAO;CAAO;CAAO;AAAK;;;;;;AAkBjD,SAAOQ,YAAAC,IAAA;CAAA,MAAAC,IAAAC,EAAA,EAAA;CAAqB,MAAA,EAAAT,MAAAC,SAAAC,UAAA,cAAAQ,WAAAL,cAAAE;CAOxB,MAAAI,OAAarB,eAAe;CAC5B,MAAAsB,cAAoBf,eAAeK,QAAQ;CAAE,IAAAW;CAAA,IAAAL,EAAA,OAAAH,WAAA;EAEHQ,KAAArB,GAAGD,2BAAMuB,SAAUT,SAAS;EAACG,EAAA,KAAAH;EAAAG,EAAA,KAAAK;CAAA,OAAAA,KAAAL,EAAA;CAAA,IAAAO;CAAA,IAAAP,EAAA,OAAAP,WAAAO,EAAA,OAAAR,QAAAQ,EAAA,OAAAI,aAAA;EAAA,IAAAI;EAAA,IAAAR,EAAA,OAAAR,QAAAQ,EAAA,OAAAI,aAAA;GAClDI,MAAAC,QAAAC,UACT,qBAAA,OAAA;IAAgC,WAAA3B,2BAAM6B;IAAtC,UAAA,CACI,oBAAA,MAAA;KAAe,WAAA7B,2BAAM8B;KAASJ,UAAAA,OAAMI,SAAUJ,OAAME;IAAS,CAAA,GAC7D,oBAAA,MAAA;KAAe,WAAA5B,2BAAM+B;KAChBtB,UAAAA,SAASuB,KAAAA,IACNX,YAAYZ,MAAMiB,MAGtB,IADI,oBAAC,UAAD,EAAiB,OAAAnB,OAAOoB,QAAQpB,OAAM0B,QAAQ,CAAA;IAEjD,CAAA,CACH;GATIP,GAAAA,OAAME,EASV;GACTX,EAAA,KAAAR;GAAAQ,EAAA,KAAAI;GAAAJ,EAAA,KAAAQ;EAAA,OAAAA,KAAAR,EAAA;EAXAO,KAAAd,QAAOwB,IAAKT,EAWZ;EAACR,EAAA,KAAAP;EAAAO,EAAA,KAAAR;EAAAQ,EAAA,KAAAI;EAAAJ,EAAA,KAAAO;CAAA,OAAAA,KAAAP,EAAA;CAAA,IAAAQ;CAAA,IAAAR,EAAA,OAAAE,aAAAF,EAAA,QAAAK,MAAAL,EAAA,QAAAO,IAAA;EAZNC,KAAA,oBAAA,MAAA;GAAgBN,cAAAA;GAAsB,WAAAG;GACjCE,UAAAA;EAYA,CAAA;EAAAP,EAAA,KAAAE;EAAAF,EAAA,MAAAK;EAAAL,EAAA,MAAAO;EAAAP,EAAA,MAAAQ;CAAA,OAAAA,KAAAR,EAAA;CAdT,MAAAM,UACIE;CAeJ,IAAIhB,SAASuB,KAAAA,GAAS;EAAA,IAAAG;EAAA,IAAAlB,EAAA,QAAAG,MAAA;GAEQe,KAAAf,KAAIgB,cAAelC,SAAQmC,WAAY;GAACpB,EAAA,MAAAG;GAAAH,EAAA,MAAAkB;EAAA,OAAAA,KAAAlB,EAAA;EAAA,IAAAqB;EAAA,IAAArB,EAAA,QAAAM,SAAA;GAC1De,KAAA,oBAAA,OAAA;IAAK,OAAA;IAAkB,eAAA;IAClBf,UAAAA;GACC,CAAA;GAAAN,EAAA,MAAAM;GAAAN,EAAA,MAAAqB;EAAA,OAAAA,KAAArB,EAAA;EAAA,IAAAsB;EAAA,IAAAtB,EAAA,QAAAkB,MAAAlB,EAAA,QAAAqB,IAAA;GAHVC,KAAA,oBAAC,eAAD;IAAsB,OAAAJ;IAClBG,UAAAA;GADU,CAAA;GAIErB,EAAA,MAAAkB;GAAAlB,EAAA,MAAAqB;GAAArB,EAAA,MAAAsB;EAAA,OAAAA,KAAAtB,EAAA;EAAA,OAJhBsB;CAIgB;CAEvB,OACMhB;AAAO"}
1
+ {"version":3,"file":"ItemDetails.js","names":["LoadingRegion","Skeleton","usePanneauIntl","styles","cx","messages","DisplayEntry","ListColumn","ListItem","useRenderValue","getColumnValue","WIDTHS","ItemDetailsColumn","columns","ItemDetailsProps","item","displays","Readonly","Record","className","isRecord","value","Array","isArray","ItemDetails","t0","$","_c","ariaLabel","intl","renderValue","t1","t2","t3","renderEntries","entryItem","entryColumns","map","column","index","label","id","undefined","locale","groupItem","entry","group","details","nested","length","t4","t5","formatMessage","loadingItem","t6","t7","_c","styles"],"sources":["../src/ItemDetails.tsx"],"sourcesContent":["import { LoadingRegion, Skeleton, usePanneauIntl } from '@panneau/ui';\n\nimport styles from './ItemDetails.module.css';\nimport { cx } from './cx';\nimport { messages } from './messages';\nimport type { DisplayEntry, ListColumn, ListItem } from './types';\nimport { useRenderValue } from './useRenderValue';\nimport { getColumnValue } from './values';\n\n/** Widths of the values of a skeleton, varied so they read as text. */\nconst WIDTHS = ['70%', '40%', '55%', '30%', '65%'];\n\n/** A value of the details, or a group of values under its label. */\nexport interface ItemDetailsColumn extends ListColumn {\n /**\n * The values of a group (a `group` field): read in the value of the column, an object, and\n * listed under its label.\n */\n columns?: readonly ItemDetailsColumn[];\n}\n\nexport interface ItemDetailsProps {\n /** The item. `undefined` while it loads: the labels, with a skeleton of each value. */\n item: ListItem | undefined;\n /** The values to show, with their label and display, in order. */\n columns: readonly ItemDetailsColumn[];\n /** Displays by name, over the built-in ones and those of the plugins. */\n displays?: Readonly<Record<string, DisplayEntry>>;\n 'aria-label'?: string;\n className?: string;\n}\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 values of one item, each with its label, shown with the displays of the lists: for the\n * details of an item next to its list, or anywhere a read-only view of it is needed. A column with\n * `columns` is a group, whose values are listed under its label. While the item loads, it draws\n * the labels with a skeleton of each value (decision 0034).\n */\nexport function ItemDetails({\n item,\n columns,\n displays,\n 'aria-label': ariaLabel,\n className,\n}: ItemDetailsProps) {\n const intl = usePanneauIntl();\n const renderValue = useRenderValue(displays);\n const renderEntries = (\n entryItem: ListItem | undefined,\n entryColumns: readonly ItemDetailsColumn[],\n ) =>\n entryColumns.map((column, index) => {\n const label = <dt className={styles.label}>{column.label ?? column.id}</dt>;\n if (column.columns !== undefined) {\n // The values of a group are those of an item made of the value of the column.\n const value =\n entryItem !== undefined\n ? getColumnValue(entryItem, column, intl.locale)\n : undefined;\n const groupItem =\n entryItem !== undefined\n ? { ...(isRecord(value) ? value : {}), id: entryItem.id }\n : undefined;\n return (\n <div key={column.id} className={cx(styles.entry, styles.group)}>\n {label}\n <dd className={styles.value}>\n <dl className={cx(styles.details, styles.nested)}>\n {renderEntries(groupItem, column.columns)}\n </dl>\n </dd>\n </div>\n );\n }\n return (\n <div key={column.id} className={styles.entry}>\n {label}\n <dd className={styles.value}>\n {entryItem !== undefined ? (\n renderValue(entryItem, column)\n ) : (\n <Skeleton width={WIDTHS[index % WIDTHS.length]} />\n )}\n </dd>\n </div>\n );\n });\n const details = (\n <dl aria-label={ariaLabel} className={cx(styles.details, className)}>\n {renderEntries(item, columns)}\n </dl>\n );\n if (item === undefined) {\n return (\n <LoadingRegion label={intl.formatMessage(messages.loadingItem)}>\n <div inert aria-hidden=\"true\">\n {details}\n </div>\n </LoadingRegion>\n );\n }\n return details;\n}\n"],"mappings":"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"}
@@ -4,13 +4,17 @@ var details = "panneau-item-details-details";
4
4
  var entry = "panneau-item-details-entry";
5
5
  var label = "panneau-item-details-label";
6
6
  var value = "panneau-item-details-value";
7
+ var group = "panneau-item-details-group";
8
+ var nested = "panneau-item-details-nested";
7
9
  var ItemDetails_module_default = {
8
10
  details,
9
11
  entry,
10
12
  label,
11
- value
13
+ value,
14
+ group,
15
+ nested
12
16
  };
13
17
  //#endregion
14
- export { ItemDetails_module_default as default, details, entry, label, value };
18
+ export { ItemDetails_module_default as default, details, entry, group, label, nested, value };
15
19
 
16
20
  //# sourceMappingURL=ItemDetails.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ItemDetails.module.js","names":[],"sources":["../src/ItemDetails.module.css"],"sourcesContent":[".details {\n container: panneau-item-details / inline-size;\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-3);\n margin: 0;\n}\n\n.entry {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-1);\n min-width: 0;\n}\n\n.label {\n color: var(--panneau-color-text-muted);\n font-size: var(--panneau-font-size-sm);\n}\n\n.value {\n min-width: 0;\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n/* Wide enough: the label and its value side by side. */\n@container panneau-item-details (min-width: 30rem) {\n .entry {\n display: grid;\n grid-template-columns: minmax(8rem, 30%) minmax(0, 1fr);\n gap: var(--panneau-space-3);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"ItemDetails.module.js","names":[],"sources":["../src/ItemDetails.module.css"],"sourcesContent":[".details {\n container: panneau-item-details / inline-size;\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-3);\n margin: 0;\n}\n\n.entry {\n display: flex;\n flex-direction: column;\n gap: var(--panneau-space-1);\n min-width: 0;\n}\n\n.label {\n color: var(--panneau-color-text-muted);\n font-size: var(--panneau-font-size-sm);\n}\n\n.value {\n min-width: 0;\n margin: 0;\n overflow-wrap: anywhere;\n}\n\n/* A group: its label over its values, which are indented. */\n.group > .label {\n color: var(--panneau-color-text);\n font-weight: var(--panneau-font-weight-medium);\n}\n\n.nested {\n padding-inline-start: var(--panneau-space-3);\n border-inline-start: var(--panneau-border-width) solid var(--panneau-color-border);\n}\n\n/* Wide enough: the label and its value side by side. */\n@container panneau-item-details (min-width: 30rem) {\n .entry {\n display: grid;\n grid-template-columns: minmax(8rem, 30%) minmax(0, 1fr);\n gap: var(--panneau-space-3);\n }\n\n .group {\n display: flex;\n gap: var(--panneau-space-2);\n }\n}\n"],"mappings":""}
@@ -1 +1 @@
1
- {"version":3,"file":"ActionButton.d.ts","sourceRoot":"","sources":["../../src/actions/ActionButton.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAKhD,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,iGAAiG;IACjG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,EACzB,MAAM,EACN,KAAK,EACL,IAAI,EACJ,OAAO,EACP,SAAiB,EACjB,UAAkB,EAClB,IAAW,EACX,YAAY,EAAE,SAAS,GAC1B,EAAE,iBAAiB,+BA6BnB"}
1
+ {"version":3,"file":"ActionButton.d.ts","sourceRoot":"","sources":["../../src/actions/ActionButton.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAGhD,OAAO,EAAE,KAAK,WAAW,EAAiB,MAAM,SAAS,CAAC;AAE1D,MAAM,WAAW,iBAAiB;IAC9B,MAAM,EAAE,MAAM,CAAC;IACf,8DAA8D;IAC9D,KAAK,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAChC,iGAAiG;IACjG,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,OAAO,EAAE,MAAM,IAAI,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,IAAI,GAAG,IAAI,CAAC;IACnB,iFAAiF;IACjF,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAOD,0EAA0E;AAC1E,wBAAgB,YAAY,CAAC,EACzB,MAAM,EACN,KAAK,EACL,IAAI,EACJ,OAAO,EACP,SAAiB,EACjB,UAAkB,EAClB,IAAW,EACX,YAAY,EAAE,SAAS,GAC1B,EAAE,iBAAiB,+BAiCnB"}
@@ -1,15 +1,16 @@
1
- import Actions_module_default from "./Actions.module.js";
2
1
  import { getActionIcon } from "./icons.js";
3
- import { cx } from "../cx.js";
4
2
  import { c } from "react/compiler-runtime";
5
3
  import { getActionLabel } from "@panneau/intl";
6
- import { Button, Icon, usePanneauIntl } from "@panneau/ui";
7
- import { jsx, jsxs } from "react/jsx-runtime";
8
- import { Link } from "react-aria-components";
4
+ import { Button, LinkButton, usePanneauIntl } from "@panneau/ui";
5
+ import { jsx } from "react/jsx-runtime";
9
6
  //#region src/actions/ActionButton.tsx
7
+ /** Whether a link leaves the admin: it opens in a new tab. */
8
+ function isExternal(href) {
9
+ return /^https?:\/\//.test(href);
10
+ }
10
11
  /** An action as a button, or as a link for a `link` action with a URL. */
11
12
  function ActionButton(t0) {
12
- const $ = c(27);
13
+ const $ = c(29);
13
14
  const { action, icons, href, onPress, isPending: t1, isDisabled: t2, size: t3, "aria-label": ariaLabel } = t0;
14
15
  const isPending = t1 === void 0 ? false : t1;
15
16
  const isDisabled = t2 === void 0 ? false : t2;
@@ -31,70 +32,71 @@ function ActionButton(t0) {
31
32
  $[5] = t5;
32
33
  } else t5 = $[5];
33
34
  const label = t5;
35
+ const variant = action.destructive === true ? "danger" : size === "sm" ? "ghost" : "secondary";
34
36
  if (href !== null) {
35
- const t6 = size === "md" && Actions_module_default.linkMd;
37
+ let t6;
38
+ if ($[6] !== icon) {
39
+ t6 = icon !== void 0 ? { icon } : {};
40
+ $[6] = icon;
41
+ $[7] = t6;
42
+ } else t6 = $[7];
36
43
  let t7;
37
- if ($[6] !== t6) {
38
- t7 = cx(Actions_module_default.link, t6);
39
- $[6] = t6;
40
- $[7] = t7;
41
- } else t7 = $[7];
44
+ if ($[8] !== href) {
45
+ t7 = isExternal(href);
46
+ $[8] = href;
47
+ $[9] = t7;
48
+ } else t7 = $[9];
42
49
  let t8;
43
- if ($[8] !== icon) {
44
- t8 = icon !== void 0 ? /* @__PURE__ */ jsx(Icon, {
45
- icon,
46
- size: "sm"
47
- }) : null;
48
- $[8] = icon;
49
- $[9] = t8;
50
- } else t8 = $[9];
51
- let t9;
52
- if ($[10] !== ariaLabel || $[11] !== href || $[12] !== label || $[13] !== t7 || $[14] !== t8) {
53
- t9 = /* @__PURE__ */ jsxs(Link, {
50
+ if ($[10] !== ariaLabel || $[11] !== href || $[12] !== label || $[13] !== size || $[14] !== t6 || $[15] !== t7 || $[16] !== variant) {
51
+ t8 = /* @__PURE__ */ jsx(LinkButton, {
54
52
  href,
53
+ size,
54
+ variant,
55
+ ...t6,
56
+ external: t7,
55
57
  "aria-label": ariaLabel,
56
- className: t7,
57
- children: [t8, label]
58
+ children: label
58
59
  });
59
60
  $[10] = ariaLabel;
60
61
  $[11] = href;
61
62
  $[12] = label;
62
- $[13] = t7;
63
- $[14] = t8;
64
- $[15] = t9;
65
- } else t9 = $[15];
66
- return t9;
63
+ $[13] = size;
64
+ $[14] = t6;
65
+ $[15] = t7;
66
+ $[16] = variant;
67
+ $[17] = t8;
68
+ } else t8 = $[17];
69
+ return t8;
67
70
  }
68
- const t6 = action.destructive === true ? "danger" : size === "sm" ? "ghost" : "secondary";
71
+ let t6;
72
+ if ($[18] !== icon) {
73
+ t6 = icon !== void 0 ? { icon } : {};
74
+ $[18] = icon;
75
+ $[19] = t6;
76
+ } else t6 = $[19];
69
77
  let t7;
70
- if ($[16] !== icon) {
71
- t7 = icon !== void 0 ? { icon } : {};
72
- $[16] = icon;
73
- $[17] = t7;
74
- } else t7 = $[17];
75
- let t8;
76
- if ($[18] !== ariaLabel || $[19] !== isDisabled || $[20] !== isPending || $[21] !== label || $[22] !== onPress || $[23] !== size || $[24] !== t6 || $[25] !== t7) {
77
- t8 = /* @__PURE__ */ jsx(Button, {
78
+ if ($[20] !== ariaLabel || $[21] !== isDisabled || $[22] !== isPending || $[23] !== label || $[24] !== onPress || $[25] !== size || $[26] !== t6 || $[27] !== variant) {
79
+ t7 = /* @__PURE__ */ jsx(Button, {
78
80
  size,
79
- variant: t6,
80
- ...t7,
81
+ variant,
82
+ ...t6,
81
83
  isPending,
82
84
  isDisabled,
83
85
  "aria-label": ariaLabel,
84
86
  onPress,
85
87
  children: label
86
88
  });
87
- $[18] = ariaLabel;
88
- $[19] = isDisabled;
89
- $[20] = isPending;
90
- $[21] = label;
91
- $[22] = onPress;
92
- $[23] = size;
93
- $[24] = t6;
94
- $[25] = t7;
95
- $[26] = t8;
96
- } else t8 = $[26];
97
- return t8;
89
+ $[20] = ariaLabel;
90
+ $[21] = isDisabled;
91
+ $[22] = isPending;
92
+ $[23] = label;
93
+ $[24] = onPress;
94
+ $[25] = size;
95
+ $[26] = t6;
96
+ $[27] = variant;
97
+ $[28] = t7;
98
+ } else t7 = $[28];
99
+ return t7;
98
100
  }
99
101
  //#endregion
100
102
  export { ActionButton };
@@ -1 +1 @@
1
- {"version":3,"file":"ActionButton.js","names":["Link","getActionLabel","Action","Button","Icon","usePanneauIntl","cx","styles","ActionIcons","getActionIcon","ActionButtonProps","action","icons","href","onPress","isPending","isDisabled","size","ActionButton","t0","$","_c","t1","t2","t3","ariaLabel","undefined","intl","t4","icon","t5","label","t6","linkMd","t7","link","t8","t9","destructive","_c","styles"],"sources":["../../src/actions/ActionButton.tsx"],"sourcesContent":["import { Link } from 'react-aria-components';\n\nimport { getActionLabel } from '@panneau/intl';\nimport type { Action } from '@panneau/protocol';\nimport { Button, Icon, usePanneauIntl } from '@panneau/ui';\n\nimport { cx } from '../cx';\nimport styles from './Actions.module.css';\nimport { type ActionIcons, getActionIcon } from './icons';\n\nexport interface ActionButtonProps {\n action: Action;\n /** Icons of actions by id, over the icon the action names. */\n icons?: ActionIcons | undefined;\n /** The link of a `link` action. Links go through React Aria, so an app's router handles them. */\n href: string | null;\n onPress: () => void;\n isPending?: boolean;\n isDisabled?: boolean;\n size?: 'sm' | 'md';\n /** Accessible label, when the label alone isn't enough (`Edit Ada Lovelace`). */\n 'aria-label'?: string;\n}\n\n/** An action as a button, or as a link for a `link` action with a URL. */\nexport function ActionButton({\n action,\n icons,\n href,\n onPress,\n isPending = false,\n isDisabled = false,\n size = 'sm',\n 'aria-label': ariaLabel,\n}: ActionButtonProps) {\n const intl = usePanneauIntl();\n const icon = getActionIcon(action, icons);\n const label = getActionLabel(action, intl);\n if (href !== null) {\n return (\n <Link\n href={href}\n aria-label={ariaLabel}\n className={cx(styles.link, size === 'md' && styles.linkMd)}\n >\n {icon !== undefined ? <Icon icon={icon} size=\"sm\" /> : null}\n {label}\n </Link>\n );\n }\n return (\n <Button\n size={size}\n variant={action.destructive === true ? 'danger' : size === 'sm' ? 'ghost' : 'secondary'}\n {...(icon !== undefined ? { icon } : {})}\n isPending={isPending}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n onPress={onPress}\n >\n {label}\n </Button>\n );\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"ActionButton.js","names":["getActionLabel","Action","Button","LinkButton","usePanneauIntl","ActionIcons","getActionIcon","ActionButtonProps","action","icons","href","onPress","isPending","isDisabled","size","isExternal","test","ActionButton","t0","$","_c","t1","t2","t3","ariaLabel","undefined","intl","t4","icon","t5","label","variant","destructive","t6","t7","t8","_c"],"sources":["../../src/actions/ActionButton.tsx"],"sourcesContent":["import { getActionLabel } from '@panneau/intl';\nimport type { Action } from '@panneau/protocol';\nimport { Button, LinkButton, usePanneauIntl } from '@panneau/ui';\n\nimport { type ActionIcons, getActionIcon } from './icons';\n\nexport interface ActionButtonProps {\n action: Action;\n /** Icons of actions by id, over the icon the action names. */\n icons?: ActionIcons | undefined;\n /** The link of a `link` action. Links go through React Aria, so an app's router handles them. */\n href: string | null;\n onPress: () => void;\n isPending?: boolean;\n isDisabled?: boolean;\n size?: 'sm' | 'md';\n /** Accessible label, when the label alone isn't enough (`Edit Ada Lovelace`). */\n 'aria-label'?: string;\n}\n\n/** Whether a link leaves the admin: it opens in a new tab. */\nfunction isExternal(href: string): boolean {\n return /^https?:\\/\\//.test(href);\n}\n\n/** An action as a button, or as a link for a `link` action with a URL. */\nexport function ActionButton({\n action,\n icons,\n href,\n onPress,\n isPending = false,\n isDisabled = false,\n size = 'sm',\n 'aria-label': ariaLabel,\n}: ActionButtonProps) {\n const intl = usePanneauIntl();\n const icon = getActionIcon(action, icons);\n const label = getActionLabel(action, intl);\n // Small actions sit in rows, as ghost buttons; others beside the buttons of a toolbar.\n const variant = action.destructive === true ? 'danger' : size === 'sm' ? 'ghost' : 'secondary';\n if (href !== null) {\n return (\n <LinkButton\n href={href}\n size={size}\n variant={variant}\n {...(icon !== undefined ? { icon } : {})}\n external={isExternal(href)}\n aria-label={ariaLabel}\n >\n {label}\n </LinkButton>\n );\n }\n return (\n <Button\n size={size}\n variant={variant}\n {...(icon !== undefined ? { icon } : {})}\n isPending={isPending}\n isDisabled={isDisabled}\n aria-label={ariaLabel}\n onPress={onPress}\n >\n {label}\n </Button>\n );\n}\n"],"mappings":"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"}
@@ -1,9 +1,10 @@
1
+ /* The actions of a row wrap where they don't fit, in a narrow list or a card. */
1
2
  .panneau-actions-row {
2
3
  display: inline-flex;
3
- flex-wrap: nowrap;
4
+ flex-wrap: wrap;
5
+ max-width: 100%;
4
6
  align-items: center;
5
- justify-content: flex-end;
6
- gap: var(--panneau-space-1);
7
+ gap: var(--panneau-space-2);
7
8
  }
8
9
 
9
10
  .panneau-actions-toolbar {
@@ -13,41 +14,6 @@
13
14
  gap: var(--panneau-space-2);
14
15
  }
15
16
 
16
- /* A link that looks like a small ghost button (link actions: show, edit). */
17
- .panneau-actions-link {
18
- display: inline-flex;
19
- align-items: center;
20
- gap: var(--panneau-space-1);
21
- height: var(--panneau-control-height-sm);
22
- padding: 0 var(--panneau-space-2);
23
- font-size: var(--panneau-font-size-sm);
24
- font-weight: var(--panneau-font-weight-medium);
25
- color: var(--panneau-color-text);
26
- text-decoration: none;
27
- white-space: nowrap;
28
- border-radius: var(--panneau-radius-md);
29
- cursor: pointer;
30
- }
31
-
32
- .panneau-actions-link[data-hovered] {
33
- background-color: var(--panneau-color-hover);
34
- }
35
-
36
- .panneau-actions-link[data-pressed] {
37
- background-color: var(--panneau-color-pressed);
38
- }
39
-
40
- .panneau-actions-link[data-focus-visible] {
41
- outline: var(--panneau-focus-width) solid var(--panneau-color-focus);
42
- outline-offset: 1px;
43
- }
44
-
45
- .panneau-actions-link-md {
46
- height: var(--panneau-control-height);
47
- padding: 0 var(--panneau-space-3);
48
- font-size: var(--panneau-font-size-control);
49
- }
50
-
51
17
  .panneau-actions-message {
52
18
  margin: 0;
53
19
  }
@@ -2,19 +2,15 @@ import "./Actions.css";
2
2
  //#region src/actions/Actions.module.css
3
3
  var row = "panneau-actions-row";
4
4
  var toolbar = "panneau-actions-toolbar";
5
- var link = "panneau-actions-link";
6
- var linkMd = "panneau-actions-link-md";
7
5
  var message = "panneau-actions-message";
8
6
  var skipped = "panneau-actions-skipped";
9
7
  var Actions_module_default = {
10
8
  row,
11
9
  toolbar,
12
- link,
13
- linkMd,
14
10
  message,
15
11
  skipped
16
12
  };
17
13
  //#endregion
18
- export { Actions_module_default as default, link, linkMd, message, row, skipped, toolbar };
14
+ export { Actions_module_default as default, message, row, skipped, toolbar };
19
15
 
20
16
  //# sourceMappingURL=Actions.module.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Actions.module.js","names":[],"sources":["../../src/actions/Actions.module.css"],"sourcesContent":[".row {\n display: inline-flex;\n flex-wrap: nowrap;\n align-items: center;\n justify-content: flex-end;\n gap: var(--panneau-space-1);\n}\n\n.toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n/* A link that looks like a small ghost button (link actions: show, edit). */\n.link {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-1);\n height: var(--panneau-control-height-sm);\n padding: 0 var(--panneau-space-2);\n font-size: var(--panneau-font-size-sm);\n font-weight: var(--panneau-font-weight-medium);\n color: var(--panneau-color-text);\n text-decoration: none;\n white-space: nowrap;\n border-radius: var(--panneau-radius-md);\n cursor: pointer;\n}\n\n.link[data-hovered] {\n background-color: var(--panneau-color-hover);\n}\n\n.link[data-pressed] {\n background-color: var(--panneau-color-pressed);\n}\n\n.link[data-focus-visible] {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n.linkMd {\n height: var(--panneau-control-height);\n padding: 0 var(--panneau-space-3);\n font-size: var(--panneau-font-size-control);\n}\n\n.message {\n margin: 0;\n}\n\n.skipped {\n margin: var(--panneau-space-2) 0 0;\n color: var(--panneau-color-warning);\n}\n"],"mappings":""}
1
+ {"version":3,"file":"Actions.module.js","names":[],"sources":["../../src/actions/Actions.module.css"],"sourcesContent":["/* The actions of a row wrap where they don't fit, in a narrow list or a card. */\n.row {\n display: inline-flex;\n flex-wrap: wrap;\n max-width: 100%;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.toolbar {\n display: flex;\n flex-wrap: wrap;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.message {\n margin: 0;\n}\n\n.skipped {\n margin: var(--panneau-space-2) 0 0;\n color: var(--panneau-color-warning);\n}\n"],"mappings":""}
package/dist/index.d.ts CHANGED
@@ -6,7 +6,7 @@ export { DateFilter, DateRangeFilter, RelationFilter, SelectFilter, TextFilter,
6
6
  export { CardsLayout } from './layouts/CardsLayout.js';
7
7
  export { TableLayout } from './layouts/TableLayout.js';
8
8
  export { builtInLayouts } from './layouts/builtIn.js';
9
- export { ItemDetails, type ItemDetailsProps } from './ItemDetails.js';
9
+ export { ItemDetails, type ItemDetailsColumn, type ItemDetailsProps } from './ItemDetails.js';
10
10
  export { List, type ListProps } from './List.js';
11
11
  export { ListView, type ListViewProps } from './ListView.js';
12
12
  export { listsPlugin } from './plugin.js';
@@ -1 +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,EACH,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,aAAa,EACb,WAAW,EACX,UAAU,EACV,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,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACnE,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,EACH,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,UAAU,EACV,KAAK,eAAe,EACpB,cAAc,GACjB,MAAM,sBAAsB,CAAC;AAC9B,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,iBAAiB,EACjB,mBAAmB,EACnB,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"}
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,EACH,aAAa,EACb,KAAK,kBAAkB,EACvB,KAAK,cAAc,GACtB,MAAM,yBAAyB,CAAC;AACjC,OAAO,EAAE,KAAK,WAAW,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAClE,OAAO,EACH,cAAc,EACd,YAAY,EACZ,WAAW,EACX,eAAe,EACf,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,WAAW,EACX,eAAe,EACf,YAAY,EACZ,aAAa,EACb,eAAe,EACf,eAAe,EACf,aAAa,EACb,WAAW,EACX,UAAU,EACV,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,WAAW,EAAE,KAAK,iBAAiB,EAAE,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC3F,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,EACH,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,UAAU,EACV,KAAK,eAAe,EACpB,cAAc,GACjB,MAAM,sBAAsB,CAAC;AAC9B,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,iBAAiB,EACjB,mBAAmB,EACnB,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"}
@@ -68,6 +68,11 @@
68
68
  white-space: nowrap;
69
69
  }
70
70
 
71
+ /* As narrow as the actions of the row on one line: they only wrap in a narrow list. */
72
+ .panneau-table-layout-table .panneau-table-layout-actions-cell > * {
73
+ flex-wrap: nowrap;
74
+ }
75
+
71
76
  .panneau-table-layout-sort {
72
77
  display: inline-flex;
73
78
  align-items: center;
@@ -161,6 +166,10 @@
161
166
  width: auto;
162
167
  }
163
168
 
169
+ .panneau-table-layout-table td.panneau-table-layout-actions-cell > * {
170
+ flex-wrap: wrap;
171
+ }
172
+
164
173
  .panneau-table-layout-table td.panneau-table-layout-check {
165
174
  position: absolute;
166
175
  top: var(--panneau-space-2);
@@ -1 +1 @@
1
- {"version":3,"file":"TableLayout.module.js","names":[],"sources":["../../src/layouts/TableLayout.module.css"],"sourcesContent":[".scroller {\n overflow-x: auto;\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-lg);\n background-color: var(--panneau-color-surface);\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--panneau-font-size-md);\n}\n\n.table th,\n.table td {\n padding: var(--panneau-row-padding-y) var(--panneau-space-3);\n text-align: start;\n vertical-align: middle;\n border-bottom: var(--panneau-border-width) solid var(--panneau-color-border);\n}\n\n.table th {\n font-size: var(--panneau-font-size-sm);\n font-weight: var(--panneau-font-weight-medium);\n color: var(--panneau-color-text-muted);\n white-space: nowrap;\n background-color: var(--panneau-color-surface-sunken);\n}\n\n/* The title stays readable in a narrow list, such as next to an item's details: the table\n * scrolls instead. */\n.table td.title {\n min-width: 12rem;\n}\n\n.table tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.table tbody tr[data-selected] {\n background-color: var(--panneau-color-accent-subtle);\n}\n\n/* The item shown next to the list: a bar on its first cell. */\n.table tbody tr[data-current] td:first-child {\n box-shadow: inset 3px 0 0 var(--panneau-color-accent);\n}\n\n.table tbody tr[data-current] {\n background-color: var(--panneau-color-hover);\n}\n\n.center {\n text-align: center !important;\n}\n\n.end {\n text-align: end !important;\n}\n\n.check {\n width: 1px;\n}\n\n.actionsCell {\n width: 1px;\n text-align: end !important;\n white-space: nowrap;\n}\n\n.sort {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-1);\n margin: calc(-1 * var(--panneau-space-1)) calc(-1 * var(--panneau-space-2));\n padding: var(--panneau-space-1) var(--panneau-space-2);\n font: inherit;\n color: inherit;\n background: none;\n border: 0;\n border-radius: var(--panneau-radius-sm);\n cursor: pointer;\n}\n\n.sort:hover {\n color: var(--panneau-color-text);\n background-color: var(--panneau-color-hover);\n}\n\n.sort:focus-visible {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n.sortIcon {\n opacity: 0.5;\n}\n\n.sorted .sortIcon {\n opacity: 1;\n}\n\n.cellLabel {\n display: none;\n}\n\n.visuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n/* Narrow lists (phones): each row is a block, with the label of each value next to it. */\n@container panneau-list (max-width: 40rem) {\n .scroller {\n overflow: visible;\n background: none;\n border: 0;\n }\n\n /* The labels of the cells replace the headers, and the list's sort select their buttons. */\n .table thead {\n display: none;\n }\n\n .table,\n .table tbody,\n .table tr,\n .table td {\n display: block;\n }\n\n .table tbody {\n display: grid;\n gap: var(--panneau-space-2);\n }\n\n .table tr {\n position: relative;\n padding: var(--panneau-space-2) 0;\n background-color: var(--panneau-color-surface);\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-lg);\n }\n\n .table td {\n display: grid;\n grid-template-columns: minmax(5rem, 35%) 1fr;\n gap: var(--panneau-space-2);\n padding: var(--panneau-space-1) var(--panneau-space-3);\n text-align: start !important;\n border: 0;\n }\n\n .table td.check,\n .table td.actionsCell {\n display: flex;\n width: auto;\n }\n\n .table td.check {\n position: absolute;\n top: var(--panneau-space-2);\n inset-inline-end: var(--panneau-space-2);\n padding: 0;\n }\n\n .table td.actionsCell {\n justify-content: flex-start;\n flex-wrap: wrap;\n padding-top: var(--panneau-space-2);\n }\n\n .table td.title {\n display: block;\n min-width: 0;\n padding-inline-end: var(--panneau-space-10);\n font-weight: var(--panneau-font-weight-medium);\n }\n\n .table td.title .cellLabel {\n display: none;\n }\n\n .cellLabel {\n display: block;\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n }\n}\n"],"mappings":""}
1
+ {"version":3,"file":"TableLayout.module.js","names":[],"sources":["../../src/layouts/TableLayout.module.css"],"sourcesContent":[".scroller {\n overflow-x: auto;\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-lg);\n background-color: var(--panneau-color-surface);\n}\n\n.table {\n width: 100%;\n border-collapse: collapse;\n font-size: var(--panneau-font-size-md);\n}\n\n.table th,\n.table td {\n padding: var(--panneau-row-padding-y) var(--panneau-space-3);\n text-align: start;\n vertical-align: middle;\n border-bottom: var(--panneau-border-width) solid var(--panneau-color-border);\n}\n\n.table th {\n font-size: var(--panneau-font-size-sm);\n font-weight: var(--panneau-font-weight-medium);\n color: var(--panneau-color-text-muted);\n white-space: nowrap;\n background-color: var(--panneau-color-surface-sunken);\n}\n\n/* The title stays readable in a narrow list, such as next to an item's details: the table\n * scrolls instead. */\n.table td.title {\n min-width: 12rem;\n}\n\n.table tbody tr:last-child td {\n border-bottom: 0;\n}\n\n.table tbody tr[data-selected] {\n background-color: var(--panneau-color-accent-subtle);\n}\n\n/* The item shown next to the list: a bar on its first cell. */\n.table tbody tr[data-current] td:first-child {\n box-shadow: inset 3px 0 0 var(--panneau-color-accent);\n}\n\n.table tbody tr[data-current] {\n background-color: var(--panneau-color-hover);\n}\n\n.center {\n text-align: center !important;\n}\n\n.end {\n text-align: end !important;\n}\n\n.check {\n width: 1px;\n}\n\n.actionsCell {\n width: 1px;\n text-align: end !important;\n white-space: nowrap;\n}\n\n/* As narrow as the actions of the row on one line: they only wrap in a narrow list. */\n.table .actionsCell > * {\n flex-wrap: nowrap;\n}\n\n.sort {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-1);\n margin: calc(-1 * var(--panneau-space-1)) calc(-1 * var(--panneau-space-2));\n padding: var(--panneau-space-1) var(--panneau-space-2);\n font: inherit;\n color: inherit;\n background: none;\n border: 0;\n border-radius: var(--panneau-radius-sm);\n cursor: pointer;\n}\n\n.sort:hover {\n color: var(--panneau-color-text);\n background-color: var(--panneau-color-hover);\n}\n\n.sort:focus-visible {\n outline: var(--panneau-focus-width) solid var(--panneau-color-focus);\n outline-offset: 1px;\n}\n\n.sortIcon {\n opacity: 0.5;\n}\n\n.sorted .sortIcon {\n opacity: 1;\n}\n\n.cellLabel {\n display: none;\n}\n\n.visuallyHidden {\n position: absolute;\n width: 1px;\n height: 1px;\n overflow: hidden;\n clip-path: inset(50%);\n white-space: nowrap;\n}\n\n/* Narrow lists (phones): each row is a block, with the label of each value next to it. */\n@container panneau-list (max-width: 40rem) {\n .scroller {\n overflow: visible;\n background: none;\n border: 0;\n }\n\n /* The labels of the cells replace the headers, and the list's sort select their buttons. */\n .table thead {\n display: none;\n }\n\n .table,\n .table tbody,\n .table tr,\n .table td {\n display: block;\n }\n\n .table tbody {\n display: grid;\n gap: var(--panneau-space-2);\n }\n\n .table tr {\n position: relative;\n padding: var(--panneau-space-2) 0;\n background-color: var(--panneau-color-surface);\n border: var(--panneau-border-width) solid var(--panneau-color-border);\n border-radius: var(--panneau-radius-lg);\n }\n\n .table td {\n display: grid;\n grid-template-columns: minmax(5rem, 35%) 1fr;\n gap: var(--panneau-space-2);\n padding: var(--panneau-space-1) var(--panneau-space-3);\n text-align: start !important;\n border: 0;\n }\n\n .table td.check,\n .table td.actionsCell {\n display: flex;\n width: auto;\n }\n\n .table td.actionsCell > * {\n flex-wrap: wrap;\n }\n\n .table td.check {\n position: absolute;\n top: var(--panneau-space-2);\n inset-inline-end: var(--panneau-space-2);\n padding: 0;\n }\n\n .table td.actionsCell {\n justify-content: flex-start;\n flex-wrap: wrap;\n padding-top: var(--panneau-space-2);\n }\n\n .table td.title {\n display: block;\n min-width: 0;\n padding-inline-end: var(--panneau-space-10);\n font-weight: var(--panneau-font-weight-medium);\n }\n\n .table td.title .cellLabel {\n display: none;\n }\n\n .cellLabel {\n display: block;\n font-size: var(--panneau-font-size-sm);\n color: var(--panneau-color-text-muted);\n }\n}\n"],"mappings":""}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@panneau/lists",
3
- "version": "5.0.0-alpha.10",
3
+ "version": "5.0.0-alpha.12",
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.10",
41
- "@panneau/fields": "5.0.0-alpha.10",
42
- "@panneau/intl": "5.0.0-alpha.10",
43
- "@panneau/protocol": "5.0.0-alpha.10",
44
- "@panneau/ui": "5.0.0-alpha.10",
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",
45
45
  "lucide-react": "^1.57.0"
46
46
  },
47
47
  "devDependencies": {
48
- "@panneau/data": "5.0.0-alpha.10"
48
+ "@panneau/data": "5.0.0-alpha.12"
49
49
  }
50
50
  }