@panneau/lists 5.0.0-alpha.16 → 5.0.0-alpha.17
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ListView.d.ts +7 -1
- package/dist/ListView.d.ts.map +1 -1
- package/dist/ListView.js +37 -31
- package/dist/ListView.js.map +1 -1
- package/dist/actions/ActionButton.d.ts +7 -1
- package/dist/actions/ActionButton.d.ts.map +1 -1
- package/dist/actions/ActionButton.js +74 -72
- package/dist/actions/ActionButton.js.map +1 -1
- package/dist/actions/Actions.css +12 -0
- package/dist/actions/Actions.module.js +6 -2
- package/dist/actions/Actions.module.js.map +1 -1
- package/dist/actions/RowActions.d.ts +21 -4
- package/dist/actions/RowActions.d.ts.map +1 -1
- package/dist/actions/RowActions.js +149 -84
- package/dist/actions/RowActions.js.map +1 -1
- package/dist/actions/fit.d.ts +25 -0
- package/dist/actions/fit.d.ts.map +1 -0
- package/dist/actions/fit.js +197 -0
- package/dist/actions/fit.js.map +1 -0
- package/dist/actions/icons.d.ts +5 -0
- package/dist/actions/icons.d.ts.map +1 -1
- package/dist/actions/icons.js +15 -1
- package/dist/actions/icons.js.map +1 -1
- package/dist/displays/Displays.css +6 -1
- package/dist/displays/Displays.module.js +4 -2
- package/dist/displays/Displays.module.js.map +1 -1
- package/dist/displays/displays.d.ts +3 -2
- package/dist/displays/displays.d.ts.map +1 -1
- package/dist/displays/displays.js +91 -39
- package/dist/displays/displays.js.map +1 -1
- package/dist/layouts/CardsLayout.d.ts.map +1 -1
- package/dist/layouts/CardsLayout.js +90 -93
- package/dist/layouts/CardsLayout.js.map +1 -1
- package/dist/layouts/GalleryLayout.css +7 -0
- package/dist/layouts/GalleryLayout.d.ts.map +1 -1
- package/dist/layouts/GalleryLayout.js +76 -53
- package/dist/layouts/GalleryLayout.js.map +1 -1
- package/dist/layouts/GalleryLayout.module.js.map +1 -1
- package/dist/layouts/TableLayout.d.ts.map +1 -1
- package/dist/layouts/TableLayout.js +120 -93
- package/dist/layouts/TableLayout.js.map +1 -1
- package/package.json +7 -7
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { c } from "react/compiler-runtime";
|
|
2
|
+
import { createContext, useEffect, useLayoutEffect, useState, useSyncExternalStore } from "react";
|
|
3
|
+
//#region src/actions/fit.ts
|
|
4
|
+
/**
|
|
5
|
+
* How the actions of rows fit (decision 0060), the same for every row of a list: `0`, every
|
|
6
|
+
* action as an icon but the main one, with its label; `1`, every action as an icon; `n` from 2,
|
|
7
|
+
* the last `n` actions of each row in its menu.
|
|
8
|
+
*/
|
|
9
|
+
var RowActionsFit = createContext(0);
|
|
10
|
+
/** What the fit of a list depends on, besides its width: its items and its columns. */
|
|
11
|
+
function fitContent(items, columns) {
|
|
12
|
+
return `${items.map((item) => item.id).join("\0")}\u0001${columns.map((column) => column.id).join("\0")}`;
|
|
13
|
+
}
|
|
14
|
+
/** Past that many actions in the menu, a row has nothing left to free. */
|
|
15
|
+
var MAX_LEVEL = 12;
|
|
16
|
+
/** The most of the width of its row that the actions of an item take before they crowd it. */
|
|
17
|
+
var SHARE = .4;
|
|
18
|
+
/**
|
|
19
|
+
* From that many actions on a row, they also go to the menu to give the content room, as long as
|
|
20
|
+
* `SHOWN` of them stay out of it.
|
|
21
|
+
*/
|
|
22
|
+
var MANY = 5;
|
|
23
|
+
var SHOWN = 4;
|
|
24
|
+
function measure(element) {
|
|
25
|
+
let crowding = Math.max(0, element.scrollWidth - element.clientWidth);
|
|
26
|
+
let count = 0;
|
|
27
|
+
for (const actions of element.querySelectorAll("[data-row-actions]")) {
|
|
28
|
+
count = Math.max(count, Number(actions.dataset.rowActions));
|
|
29
|
+
const box = actions.parentElement;
|
|
30
|
+
if (box !== null) crowding += Math.max(0, box.scrollWidth - box.clientWidth);
|
|
31
|
+
const first = actions.firstElementChild;
|
|
32
|
+
if (first instanceof HTMLElement) crowding += Math.max(0, actions.offsetHeight - first.offsetHeight);
|
|
33
|
+
const row = actions.closest("tr, li") ?? element;
|
|
34
|
+
crowding += Math.max(0, actions.offsetWidth - row.offsetWidth * SHARE);
|
|
35
|
+
}
|
|
36
|
+
let cut = 0;
|
|
37
|
+
for (const text of element.querySelectorAll("[data-clamp]")) cut += Math.max(0, text.scrollHeight - text.clientHeight);
|
|
38
|
+
return {
|
|
39
|
+
height: element.offsetHeight + cut,
|
|
40
|
+
crowding,
|
|
41
|
+
count
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Whether rows of `count` actions can give the content room with `level`: only when they have many
|
|
46
|
+
* actions, `SHOWN` of which stay out of the menu.
|
|
47
|
+
*/
|
|
48
|
+
function forContent(level, count) {
|
|
49
|
+
return count >= MANY && count - level >= SHOWN;
|
|
50
|
+
}
|
|
51
|
+
/** Whether the next level is worth a try, after `current`. */
|
|
52
|
+
function worthTrying(next, current) {
|
|
53
|
+
if (next === 1) return current.crowding > .5 || forContent(next, current.count);
|
|
54
|
+
return next <= Math.min(current.count, MAX_LEVEL) && current.count >= 2 && (current.crowding > .5 || forContent(next, current.count));
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* The best of the levels tried: the actions crowd least, then the rows are shortest (when the
|
|
58
|
+
* level may give the content room), then the fewest changes.
|
|
59
|
+
*/
|
|
60
|
+
function best(measures) {
|
|
61
|
+
let chosen = 0;
|
|
62
|
+
for (const [level, current] of measures) {
|
|
63
|
+
const kept = measures.get(chosen);
|
|
64
|
+
if (kept === void 0 || level === chosen) continue;
|
|
65
|
+
if (current.crowding < kept.crowding - .5) chosen = level;
|
|
66
|
+
else if (current.crowding <= kept.crowding + .5 && forContent(level, current.count) && current.height < kept.height - .5) chosen = level;
|
|
67
|
+
}
|
|
68
|
+
return chosen;
|
|
69
|
+
}
|
|
70
|
+
/**
|
|
71
|
+
* The level of a list, outside React: it changes while the list commits, and React draws each
|
|
72
|
+
* change at once (`useSyncExternalStore`), before the browser paints.
|
|
73
|
+
*/
|
|
74
|
+
var FitStore = class {
|
|
75
|
+
#level = 0;
|
|
76
|
+
#settled = false;
|
|
77
|
+
/** The measures of the levels tried. */
|
|
78
|
+
#measures = /* @__PURE__ */ new Map();
|
|
79
|
+
#content = null;
|
|
80
|
+
#listeners = /* @__PURE__ */ new Set();
|
|
81
|
+
subscribe = (listener) => {
|
|
82
|
+
this.#listeners.add(listener);
|
|
83
|
+
return () => this.#listeners.delete(listener);
|
|
84
|
+
};
|
|
85
|
+
getLevel = () => this.#level;
|
|
86
|
+
#set(level) {
|
|
87
|
+
if (level !== this.#level) {
|
|
88
|
+
this.#level = level;
|
|
89
|
+
for (const listener of this.#listeners) listener();
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/** Starts over from the labels: true when the list has to draw them first. */
|
|
93
|
+
restart() {
|
|
94
|
+
this.#settled = false;
|
|
95
|
+
this.#measures = /* @__PURE__ */ new Map();
|
|
96
|
+
const drawn = this.#level === 0;
|
|
97
|
+
this.#set(0);
|
|
98
|
+
return !drawn;
|
|
99
|
+
}
|
|
100
|
+
/** Starts over when the content changes. */
|
|
101
|
+
setContent(content) {
|
|
102
|
+
if (content === this.#content) return false;
|
|
103
|
+
this.#content = content;
|
|
104
|
+
return this.restart();
|
|
105
|
+
}
|
|
106
|
+
/** Measures the list drawn at `drawn`, then tries the next level, or settles on the best. */
|
|
107
|
+
step(element, drawn) {
|
|
108
|
+
if (this.#settled || drawn !== this.#level) return;
|
|
109
|
+
const current = measure(element);
|
|
110
|
+
this.#measures.set(drawn, current);
|
|
111
|
+
const next = drawn + 1;
|
|
112
|
+
if (worthTrying(next, current)) this.#set(next);
|
|
113
|
+
else {
|
|
114
|
+
this.#settled = true;
|
|
115
|
+
this.#set(best(this.#measures));
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
};
|
|
119
|
+
/**
|
|
120
|
+
* Fits the actions of the rows of a list in the room they have (decision 0060). It draws each
|
|
121
|
+
* level in turn, from every action as an icon but the main one, labelled, then the main one as an
|
|
122
|
+
* icon too, then a menu of two actions, three…, while the next one may help, and keeps the best:
|
|
123
|
+
* where the actions crowd least (the list overflows, the actions of a row wrap or take more than
|
|
124
|
+
* 40% of it), then, on rows of five actions or more, where the rows are shortest (their content
|
|
125
|
+
* wraps or is cut less), then the fewest actions in the menu.
|
|
126
|
+
*
|
|
127
|
+
* @returns the level, and a callback ref for the element to measure: the list, which holds the
|
|
128
|
+
* actions.
|
|
129
|
+
*/
|
|
130
|
+
function useRowActionsFit(content) {
|
|
131
|
+
const $ = c(12);
|
|
132
|
+
const [element, setElement] = useState(null);
|
|
133
|
+
const [store] = useState(_temp);
|
|
134
|
+
const level = useSyncExternalStore(store.subscribe, store.getLevel, store.getLevel);
|
|
135
|
+
let t0;
|
|
136
|
+
let t1;
|
|
137
|
+
if ($[0] !== content || $[1] !== element || $[2] !== level || $[3] !== store) {
|
|
138
|
+
t0 = () => {
|
|
139
|
+
if (element !== null && !store.setContent(content)) store.step(element, level);
|
|
140
|
+
};
|
|
141
|
+
t1 = [
|
|
142
|
+
store,
|
|
143
|
+
element,
|
|
144
|
+
content,
|
|
145
|
+
level
|
|
146
|
+
];
|
|
147
|
+
$[0] = content;
|
|
148
|
+
$[1] = element;
|
|
149
|
+
$[2] = level;
|
|
150
|
+
$[3] = store;
|
|
151
|
+
$[4] = t0;
|
|
152
|
+
$[5] = t1;
|
|
153
|
+
} else {
|
|
154
|
+
t0 = $[4];
|
|
155
|
+
t1 = $[5];
|
|
156
|
+
}
|
|
157
|
+
useLayoutEffect(t0, t1);
|
|
158
|
+
let t2;
|
|
159
|
+
let t3;
|
|
160
|
+
if ($[6] !== element || $[7] !== store) {
|
|
161
|
+
t2 = () => {
|
|
162
|
+
if (element === null || typeof ResizeObserver === "undefined") return;
|
|
163
|
+
let width = element.clientWidth;
|
|
164
|
+
const observer = new ResizeObserver(() => {
|
|
165
|
+
if (element.clientWidth !== width) {
|
|
166
|
+
width = element.clientWidth;
|
|
167
|
+
if (!store.restart()) store.step(element, 0);
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
observer.observe(element);
|
|
171
|
+
return () => observer.disconnect();
|
|
172
|
+
};
|
|
173
|
+
t3 = [store, element];
|
|
174
|
+
$[6] = element;
|
|
175
|
+
$[7] = store;
|
|
176
|
+
$[8] = t2;
|
|
177
|
+
$[9] = t3;
|
|
178
|
+
} else {
|
|
179
|
+
t2 = $[8];
|
|
180
|
+
t3 = $[9];
|
|
181
|
+
}
|
|
182
|
+
useEffect(t2, t3);
|
|
183
|
+
let t4;
|
|
184
|
+
if ($[10] !== level) {
|
|
185
|
+
t4 = [level, setElement];
|
|
186
|
+
$[10] = level;
|
|
187
|
+
$[11] = t4;
|
|
188
|
+
} else t4 = $[11];
|
|
189
|
+
return t4;
|
|
190
|
+
}
|
|
191
|
+
function _temp() {
|
|
192
|
+
return new FitStore();
|
|
193
|
+
}
|
|
194
|
+
//#endregion
|
|
195
|
+
export { RowActionsFit, fitContent, useRowActionsFit };
|
|
196
|
+
|
|
197
|
+
//# sourceMappingURL=fit.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fit.js","names":["createContext","useEffect","useLayoutEffect","useState","useSyncExternalStore","RowActionsFit","fitContent","items","id","columns","map","item","join","column","MAX_LEVEL","SHARE","MANY","SHOWN","Measure","height","crowding","count","measure","element","HTMLElement","Math","max","scrollWidth","clientWidth","actions","querySelectorAll","Number","dataset","rowActions","box","parentElement","first","firstElementChild","offsetHeight","row","closest","offsetWidth","cut","text","scrollHeight","clientHeight","forContent","level","worthTrying","next","current","min","best","measures","ReadonlyMap","chosen","kept","get","undefined","FitStore","settled","Map","content","listeners","Set","subscribe","listener","add","delete","getLevel","set","#set","restart","drawn","setContent","step","useRowActionsFit","$","_c","setElement","store","_temp","t0","t1","t2","t3","ResizeObserver","width","observer","observe","disconnect","t4","_c"],"sources":["../../src/actions/fit.ts"],"sourcesContent":["import { createContext, useEffect, useLayoutEffect, useState, useSyncExternalStore } from 'react';\n\n/**\n * How the actions of rows fit (decision 0060), the same for every row of a list: `0`, every\n * action as an icon but the main one, with its label; `1`, every action as an icon; `n` from 2,\n * the last `n` actions of each row in its menu.\n */\nexport const RowActionsFit = createContext(0);\n\n/** What the fit of a list depends on, besides its width: its items and its columns. */\nexport function fitContent(\n items: readonly { id: string }[],\n columns: readonly { id: string }[],\n): string {\n return `${items.map((item) => item.id).join('\\u0000')}\\u0001${columns.map((column) => column.id).join('\\u0000')}`;\n}\n\n/** Past that many actions in the menu, a row has nothing left to free. */\nconst MAX_LEVEL = 12;\n\n/** The most of the width of its row that the actions of an item take before they crowd it. */\nconst SHARE = 0.4;\n\n/**\n * From that many actions on a row, they also go to the menu to give the content room, as long as\n * `SHOWN` of them stay out of it.\n */\nconst MANY = 5;\nconst SHOWN = 4;\n\ninterface Measure {\n /**\n * The room the content lacks: the height of the list, since rows grow when their content\n * wraps, and what the displays that clamp their text (`data-clamp`) cut off.\n */\n height: number;\n /**\n * How much the actions don't fit, in pixels: what the list and the boxes of actions overflow,\n * the lines that actions wrap to, and what they take of their row past `SHARE`.\n */\n crowding: number;\n /** The most actions a row has, in the row and its menu. */\n count: number;\n}\n\nfunction measure(element: HTMLElement): Measure {\n let crowding = Math.max(0, element.scrollWidth - element.clientWidth);\n let count = 0;\n for (const actions of element.querySelectorAll<HTMLElement>('[data-row-actions]')) {\n count = Math.max(count, Number(actions.dataset.rowActions));\n const box = actions.parentElement;\n if (box !== null) {\n crowding += Math.max(0, box.scrollWidth - box.clientWidth);\n }\n const first = actions.firstElementChild;\n if (first instanceof HTMLElement) {\n crowding += Math.max(0, actions.offsetHeight - first.offsetHeight);\n }\n const row = actions.closest<HTMLElement>('tr, li') ?? element;\n crowding += Math.max(0, actions.offsetWidth - row.offsetWidth * SHARE);\n }\n let cut = 0;\n for (const text of element.querySelectorAll<HTMLElement>('[data-clamp]')) {\n cut += Math.max(0, text.scrollHeight - text.clientHeight);\n }\n return { height: element.offsetHeight + cut, crowding, count };\n}\n\n/**\n * Whether rows of `count` actions can give the content room with `level`: only when they have many\n * actions, `SHOWN` of which stay out of the menu.\n */\nfunction forContent(level: number, count: number): boolean {\n return count >= MANY && count - level >= SHOWN;\n}\n\n/** Whether the next level is worth a try, after `current`. */\nfunction worthTrying(next: number, current: Measure): boolean {\n if (next === 1) {\n return current.crowding > 0.5 || forContent(next, current.count);\n }\n return (\n next <= Math.min(current.count, MAX_LEVEL) &&\n current.count >= 2 &&\n (current.crowding > 0.5 || forContent(next, current.count))\n );\n}\n\n/**\n * The best of the levels tried: the actions crowd least, then the rows are shortest (when the\n * level may give the content room), then the fewest changes.\n */\nfunction best(measures: ReadonlyMap<number, Measure>): number {\n let chosen = 0;\n for (const [level, current] of measures) {\n const kept = measures.get(chosen);\n if (kept === undefined || level === chosen) {\n continue;\n }\n if (current.crowding < kept.crowding - 0.5) {\n chosen = level;\n } else if (\n current.crowding <= kept.crowding + 0.5 &&\n forContent(level, current.count) &&\n current.height < kept.height - 0.5\n ) {\n chosen = level;\n }\n }\n return chosen;\n}\n\n/**\n * The level of a list, outside React: it changes while the list commits, and React draws each\n * change at once (`useSyncExternalStore`), before the browser paints.\n */\nclass FitStore {\n #level = 0;\n #settled = false;\n /** The measures of the levels tried. */\n #measures = new Map<number, Measure>();\n #content: string | null = null;\n readonly #listeners = new Set<() => void>();\n\n readonly subscribe = (listener: () => void): (() => void) => {\n this.#listeners.add(listener);\n return () => this.#listeners.delete(listener);\n };\n\n readonly getLevel = (): number => this.#level;\n\n #set(level: number): void {\n if (level !== this.#level) {\n this.#level = level;\n for (const listener of this.#listeners) {\n listener();\n }\n }\n }\n\n /** Starts over from the labels: true when the list has to draw them first. */\n restart(): boolean {\n this.#settled = false;\n this.#measures = new Map();\n const drawn = this.#level === 0;\n this.#set(0);\n return !drawn;\n }\n\n /** Starts over when the content changes. */\n setContent(content: string): boolean {\n if (content === this.#content) {\n return false;\n }\n this.#content = content;\n return this.restart();\n }\n\n /** Measures the list drawn at `drawn`, then tries the next level, or settles on the best. */\n step(element: HTMLElement, drawn: number): void {\n if (this.#settled || drawn !== this.#level) {\n return;\n }\n const current = measure(element);\n this.#measures.set(drawn, current);\n const next = drawn + 1;\n if (worthTrying(next, current)) {\n this.#set(next);\n } else {\n this.#settled = true;\n this.#set(best(this.#measures));\n }\n }\n}\n\n/**\n * Fits the actions of the rows of a list in the room they have (decision 0060). It draws each\n * level in turn, from every action as an icon but the main one, labelled, then the main one as an\n * icon too, then a menu of two actions, three…, while the next one may help, and keeps the best:\n * where the actions crowd least (the list overflows, the actions of a row wrap or take more than\n * 40% of it), then, on rows of five actions or more, where the rows are shortest (their content\n * wraps or is cut less), then the fewest actions in the menu.\n *\n * @returns the level, and a callback ref for the element to measure: the list, which holds the\n * actions.\n */\nexport function useRowActionsFit(\n content: string,\n): [level: number, measure: (element: HTMLElement | null) => void] {\n const [element, setElement] = useState<HTMLElement | null>(null);\n const [store] = useState(() => new FitStore());\n const level = useSyncExternalStore(store.subscribe, store.getLevel, store.getLevel);\n\n useLayoutEffect(() => {\n if (element !== null && !store.setContent(content)) {\n store.step(element, level);\n }\n }, [store, element, content, level]);\n\n useEffect(() => {\n // Without ResizeObserver (jsdom), the list fits once, at its first width.\n if (element === null || typeof ResizeObserver === 'undefined') {\n return undefined;\n }\n let width = element.clientWidth;\n const observer = new ResizeObserver(() => {\n if (element.clientWidth !== width) {\n width = element.clientWidth;\n if (!store.restart()) {\n store.step(element, 0);\n }\n }\n });\n observer.observe(element);\n return () => observer.disconnect();\n }, [store, element]);\n\n return [level, setElement];\n}\n"],"mappings":"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"}
|
package/dist/actions/icons.d.ts
CHANGED
|
@@ -7,4 +7,9 @@ export type ActionIcons = Readonly<Record<string, IconComponent>>;
|
|
|
7
7
|
* names (`"send"`, loaded when it first renders), then the icon of a built-in action.
|
|
8
8
|
*/
|
|
9
9
|
export declare function getActionIcon(action: Action, icons?: ActionIcons): IconComponent | undefined;
|
|
10
|
+
/**
|
|
11
|
+
* The tone of an action in rows (decision 0060): `danger` when it destroys, a color for `show`
|
|
12
|
+
* (`info`), `edit` (`accent`) and `restore` (`success`), and `neutral` for the others.
|
|
13
|
+
*/
|
|
14
|
+
export declare function getActionTone(action: Action): 'neutral' | 'accent' | 'info' | 'success' | 'danger';
|
|
10
15
|
//# sourceMappingURL=icons.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/actions/icons.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,aAAa,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAalE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,CAU5F"}
|
|
1
|
+
{"version":3,"file":"icons.d.ts","sourceRoot":"","sources":["../../src/actions/icons.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAChD,OAAO,EAAE,KAAK,aAAa,EAAgB,MAAM,aAAa,CAAC;AAE/D,2FAA2F;AAC3F,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC;AAalE;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,CAU5F;AASD;;;GAGG;AACH,wBAAgB,aAAa,CACzB,MAAM,EAAE,MAAM,GACf,SAAS,GAAG,QAAQ,GAAG,MAAM,GAAG,SAAS,GAAG,QAAQ,CAOtD"}
|
package/dist/actions/icons.js
CHANGED
|
@@ -21,7 +21,21 @@ function getActionIcon(action, icons) {
|
|
|
21
21
|
if (action.icon !== void 0 && action.icon !== "") return getNamedIcon(action.icon);
|
|
22
22
|
return Object.hasOwn(BUILT_IN_ICONS, action.id) ? BUILT_IN_ICONS[action.id] : void 0;
|
|
23
23
|
}
|
|
24
|
+
/** Colors of the built-in actions in rows, as Panneau 4 had them (decision 0060). */
|
|
25
|
+
var BUILT_IN_TONES = {
|
|
26
|
+
show: "info",
|
|
27
|
+
edit: "accent",
|
|
28
|
+
restore: "success"
|
|
29
|
+
};
|
|
30
|
+
/**
|
|
31
|
+
* The tone of an action in rows (decision 0060): `danger` when it destroys, a color for `show`
|
|
32
|
+
* (`info`), `edit` (`accent`) and `restore` (`success`), and `neutral` for the others.
|
|
33
|
+
*/
|
|
34
|
+
function getActionTone(action) {
|
|
35
|
+
if (action.destructive === true) return "danger";
|
|
36
|
+
return Object.hasOwn(BUILT_IN_TONES, action.id) ? BUILT_IN_TONES[action.id] ?? "neutral" : "neutral";
|
|
37
|
+
}
|
|
24
38
|
//#endregion
|
|
25
|
-
export { getActionIcon };
|
|
39
|
+
export { getActionIcon, getActionTone };
|
|
26
40
|
|
|
27
41
|
//# sourceMappingURL=icons.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"icons.js","names":["Copy","Download","Eye","LucideIcon","Pencil","RotateCcw","Trash2","Upload","Action","IconComponent","getNamedIcon","ActionIcons","Readonly","Record","BUILT_IN_ICONS","show","edit","duplicate","delete","restore","export","import","getActionIcon","action","icons","given","undefined","Object","hasOwn","id","icon"],"sources":["../../src/actions/icons.ts"],"sourcesContent":["import {\n Copy,\n Download,\n Eye,\n type LucideIcon,\n Pencil,\n RotateCcw,\n Trash2,\n Upload,\n} from 'lucide-react';\n\nimport type { Action } from '@panneau/protocol';\nimport { type IconComponent, getNamedIcon } from '@panneau/ui';\n\n/** Icons of actions by action id, for actions written in code (`{ archive: Archive }`). */\nexport type ActionIcons = Readonly<Record<string, IconComponent>>;\n\n/** Icons of the built-in actions, when they don't name one. */\nconst BUILT_IN_ICONS: Record<string, LucideIcon> = {\n show: Eye,\n edit: Pencil,\n duplicate: Copy,\n delete: Trash2,\n restore: RotateCcw,\n export: Download,\n import: Upload,\n};\n\n/**\n * The icon of an action: the one given for its id in `icons`, then the Lucide icon its `icon`\n * names (`\"send\"`, loaded when it first renders), then the icon of a built-in action.\n */\nexport function getActionIcon(action: Action, icons?: ActionIcons): IconComponent | undefined {\n const given =\n icons !== undefined && Object.hasOwn(icons, action.id) ? icons[action.id] : undefined;\n if (given !== undefined) {\n return given;\n }\n if (action.icon !== undefined && action.icon !== '') {\n return getNamedIcon(action.icon);\n }\n return Object.hasOwn(BUILT_IN_ICONS, action.id) ? BUILT_IN_ICONS[action.id] : undefined;\n}\n"],"mappings":";;;;AAkBA,IAAMc,iBAA6C;CAC/CC,MAAMb;CACNc,MAAMZ;CACNa,WAAWjB;CACXkB,QAAQZ;CACRa,SAASd;CACTe,QAAQnB;CACRoB,QAAQd;AACZ;;;;;AAMA,SAAgBe,cAAcC,QAAgBC,OAAgD;CAC1F,MAAMC,QACFD,UAAUE,KAAAA,KAAaC,OAAOC,OAAOJ,OAAOD,OAAOM,EAAE,IAAIL,MAAMD,OAAOM,MAAMH,KAAAA;CAChF,IAAID,UAAUC,KAAAA,GACV,OAAOD;CAEX,IAAIF,OAAOO,SAASJ,KAAAA,KAAaH,OAAOO,SAAS,IAC7C,OAAOpB,aAAaa,OAAOO,IAAI;CAEnC,OAAOH,OAAOC,OAAOd,gBAAgBS,OAAOM,EAAE,IAAIf,eAAeS,OAAOM,MAAMH,KAAAA;AAClF"}
|
|
1
|
+
{"version":3,"file":"icons.js","names":["Copy","Download","Eye","LucideIcon","Pencil","RotateCcw","Trash2","Upload","Action","IconComponent","getNamedIcon","ActionIcons","Readonly","Record","BUILT_IN_ICONS","show","edit","duplicate","delete","restore","export","import","getActionIcon","action","icons","given","undefined","Object","hasOwn","id","icon","BUILT_IN_TONES","getActionTone","destructive"],"sources":["../../src/actions/icons.ts"],"sourcesContent":["import {\n Copy,\n Download,\n Eye,\n type LucideIcon,\n Pencil,\n RotateCcw,\n Trash2,\n Upload,\n} from 'lucide-react';\n\nimport type { Action } from '@panneau/protocol';\nimport { type IconComponent, getNamedIcon } from '@panneau/ui';\n\n/** Icons of actions by action id, for actions written in code (`{ archive: Archive }`). */\nexport type ActionIcons = Readonly<Record<string, IconComponent>>;\n\n/** Icons of the built-in actions, when they don't name one. */\nconst BUILT_IN_ICONS: Record<string, LucideIcon> = {\n show: Eye,\n edit: Pencil,\n duplicate: Copy,\n delete: Trash2,\n restore: RotateCcw,\n export: Download,\n import: Upload,\n};\n\n/**\n * The icon of an action: the one given for its id in `icons`, then the Lucide icon its `icon`\n * names (`\"send\"`, loaded when it first renders), then the icon of a built-in action.\n */\nexport function getActionIcon(action: Action, icons?: ActionIcons): IconComponent | undefined {\n const given =\n icons !== undefined && Object.hasOwn(icons, action.id) ? icons[action.id] : undefined;\n if (given !== undefined) {\n return given;\n }\n if (action.icon !== undefined && action.icon !== '') {\n return getNamedIcon(action.icon);\n }\n return Object.hasOwn(BUILT_IN_ICONS, action.id) ? BUILT_IN_ICONS[action.id] : undefined;\n}\n\n/** Colors of the built-in actions in rows, as Panneau 4 had them (decision 0060). */\nconst BUILT_IN_TONES: Record<string, 'accent' | 'info' | 'success'> = {\n show: 'info',\n edit: 'accent',\n restore: 'success',\n};\n\n/**\n * The tone of an action in rows (decision 0060): `danger` when it destroys, a color for `show`\n * (`info`), `edit` (`accent`) and `restore` (`success`), and `neutral` for the others.\n */\nexport function getActionTone(\n action: Action,\n): 'neutral' | 'accent' | 'info' | 'success' | 'danger' {\n if (action.destructive === true) {\n return 'danger';\n }\n return Object.hasOwn(BUILT_IN_TONES, action.id)\n ? (BUILT_IN_TONES[action.id] ?? 'neutral')\n : 'neutral';\n}\n"],"mappings":";;;;AAkBA,IAAMc,iBAA6C;CAC/CC,MAAMb;CACNc,MAAMZ;CACNa,WAAWjB;CACXkB,QAAQZ;CACRa,SAASd;CACTe,QAAQnB;CACRoB,QAAQd;AACZ;;;;;AAMA,SAAgBe,cAAcC,QAAgBC,OAAgD;CAC1F,MAAMC,QACFD,UAAUE,KAAAA,KAAaC,OAAOC,OAAOJ,OAAOD,OAAOM,EAAE,IAAIL,MAAMD,OAAOM,MAAMH,KAAAA;CAChF,IAAID,UAAUC,KAAAA,GACV,OAAOD;CAEX,IAAIF,OAAOO,SAASJ,KAAAA,KAAaH,OAAOO,SAAS,IAC7C,OAAOpB,aAAaa,OAAOO,IAAI;CAEnC,OAAOH,OAAOC,OAAOd,gBAAgBS,OAAOM,EAAE,IAAIf,eAAeS,OAAOM,MAAMH,KAAAA;AAClF;;AAGA,IAAMK,iBAAgE;CAClEhB,MAAM;CACNC,MAAM;CACNG,SAAS;AACb;;;;;AAMA,SAAgBa,cACZT,QACoD;CACpD,IAAIA,OAAOU,gBAAgB,MACvB,OAAO;CAEX,OAAON,OAAOC,OAAOG,gBAAgBR,OAAOM,EAAE,IACvCE,eAAeR,OAAOM,OAAO,YAC9B;AACV"}
|
|
@@ -95,7 +95,7 @@
|
|
|
95
95
|
gap: var(--panneau-space-1) var(--panneau-space-3);
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
-
/* A value after a flag: a country, a phone number. */
|
|
98
|
+
/* A value after a flag: a country, a region, a phone number. */
|
|
99
99
|
.panneau-displays-flagged {
|
|
100
100
|
display: inline-flex;
|
|
101
101
|
align-items: baseline;
|
|
@@ -106,3 +106,8 @@
|
|
|
106
106
|
.panneau-displays-flag {
|
|
107
107
|
flex: 0 0 auto;
|
|
108
108
|
}
|
|
109
|
+
|
|
110
|
+
/* The flag of a region is an image: centered on the text, where an emoji sits on its baseline. */
|
|
111
|
+
.panneau-displays-region-flag {
|
|
112
|
+
align-self: center;
|
|
113
|
+
}
|
|
@@ -16,6 +16,7 @@ var tags = "panneau-displays-tags";
|
|
|
16
16
|
var countries = "panneau-displays-countries";
|
|
17
17
|
var flagged = "panneau-displays-flagged";
|
|
18
18
|
var flag = "panneau-displays-flag";
|
|
19
|
+
var regionFlag = "panneau-displays-region-flag";
|
|
19
20
|
var Displays_module_default = {
|
|
20
21
|
empty,
|
|
21
22
|
text,
|
|
@@ -34,9 +35,10 @@ var Displays_module_default = {
|
|
|
34
35
|
tags,
|
|
35
36
|
countries,
|
|
36
37
|
flagged,
|
|
37
|
-
flag
|
|
38
|
+
flag,
|
|
39
|
+
regionFlag
|
|
38
40
|
};
|
|
39
41
|
//#endregion
|
|
40
|
-
export { badges, boolean, code, color, countries, Displays_module_default as default, empty, flag, flagged, link, media, number, paletteColor, swatch, tags, text, thumbnail };
|
|
42
|
+
export { badges, boolean, code, color, countries, Displays_module_default as default, empty, flag, flagged, link, media, number, paletteColor, regionFlag, swatch, tags, text, thumbnail };
|
|
41
43
|
|
|
42
44
|
//# sourceMappingURL=Displays.module.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Displays.module.js","names":[],"sources":["../../src/displays/Displays.module.css"],"sourcesContent":[".empty {\n color: var(--panneau-color-text-muted);\n}\n\n.text {\n display: -webkit-box;\n overflow: hidden;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow-wrap: anywhere;\n}\n\n.badges {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1);\n}\n\n.boolean {\n display: inline-flex;\n align-items: center;\n}\n\n.true {\n color: var(--panneau-color-success);\n}\n\n.false {\n color: var(--panneau-color-text-muted);\n}\n\n.number {\n font-variant-numeric: var(--panneau-font-numeric);\n}\n\n.link {\n color: var(--panneau-color-link);\n overflow-wrap: anywhere;\n}\n\n.color {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n}\n\n.paletteColor {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.swatch {\n flex: none;\n width: 1rem;\n height: 1rem;\n border: var(--panneau-border-width) solid var(--panneau-color-border-control);\n border-radius: var(--panneau-radius-sm);\n}\n\n.media {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.thumbnail {\n flex: none;\n width: 2.5rem;\n height: 2.5rem;\n object-fit: cover;\n background-color: var(--panneau-color-surface-sunken);\n border-radius: var(--panneau-radius-sm);\n}\n\n.code {\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n white-space: nowrap;\n}\n\n.tags {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1);\n}\n\n/* Several countries. */\n.countries {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1) var(--panneau-space-3);\n}\n\n/* A value after a flag: a country, a phone number. */\n.flagged {\n display: inline-flex;\n align-items: baseline;\n gap: var(--panneau-space-2);\n min-width: 0;\n}\n\n.flag {\n flex: 0 0 auto;\n}\n"],"mappings":""}
|
|
1
|
+
{"version":3,"file":"Displays.module.js","names":[],"sources":["../../src/displays/Displays.module.css"],"sourcesContent":[".empty {\n color: var(--panneau-color-text-muted);\n}\n\n.text {\n display: -webkit-box;\n overflow: hidden;\n -webkit-line-clamp: 2;\n line-clamp: 2;\n -webkit-box-orient: vertical;\n overflow-wrap: anywhere;\n}\n\n.badges {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1);\n}\n\n.boolean {\n display: inline-flex;\n align-items: center;\n}\n\n.true {\n color: var(--panneau-color-success);\n}\n\n.false {\n color: var(--panneau-color-text-muted);\n}\n\n.number {\n font-variant-numeric: var(--panneau-font-numeric);\n}\n\n.link {\n color: var(--panneau-color-link);\n overflow-wrap: anywhere;\n}\n\n.color {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n}\n\n.paletteColor {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.swatch {\n flex: none;\n width: 1rem;\n height: 1rem;\n border: var(--panneau-border-width) solid var(--panneau-color-border-control);\n border-radius: var(--panneau-radius-sm);\n}\n\n.media {\n display: inline-flex;\n align-items: center;\n gap: var(--panneau-space-2);\n}\n\n.thumbnail {\n flex: none;\n width: 2.5rem;\n height: 2.5rem;\n object-fit: cover;\n background-color: var(--panneau-color-surface-sunken);\n border-radius: var(--panneau-radius-sm);\n}\n\n.code {\n font-family: var(--panneau-font-family-mono);\n font-size: var(--panneau-font-size-sm);\n white-space: nowrap;\n}\n\n.tags {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1);\n}\n\n/* Several countries. */\n.countries {\n display: inline-flex;\n flex-wrap: wrap;\n gap: var(--panneau-space-1) var(--panneau-space-3);\n}\n\n/* A value after a flag: a country, a region, a phone number. */\n.flagged {\n display: inline-flex;\n align-items: baseline;\n gap: var(--panneau-space-2);\n min-width: 0;\n}\n\n.flag {\n flex: 0 0 auto;\n}\n\n/* The flag of a region is an image: centered on the text, where an emoji sits on its baseline. */\n.regionFlag {\n align-self: center;\n}\n"],"mappings":""}
|
|
@@ -43,8 +43,9 @@ export declare function TelDisplay({ value, field }: DisplayProps): import("reac
|
|
|
43
43
|
/** A country, or several (`multiple`): their flags and their names in the user's locale. */
|
|
44
44
|
export declare function CountryDisplay({ value }: DisplayProps): import("react").JSX.Element;
|
|
45
45
|
/**
|
|
46
|
-
* A region: its name in the user's locale, from its country in the
|
|
47
|
-
* the field's settings. A region that Panneau doesn't know shows as it
|
|
46
|
+
* A region: its flag, when it has one, and its name in the user's locale, from its country in the
|
|
47
|
+
* item (the field's `from`) or the field's settings. A region that Panneau doesn't know shows as it
|
|
48
|
+
* is.
|
|
48
49
|
*/
|
|
49
50
|
export declare function RegionDisplay({ value, field, item }: DisplayProps): import("react").JSX.Element;
|
|
50
51
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"displays.d.ts","sourceRoot":"","sources":["../../src/displays/displays.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI3D,kGAAkG;AAClG,wBAAgB,UAAU,gCAMzB;AAWD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+
|
|
1
|
+
{"version":3,"file":"displays.d.ts","sourceRoot":"","sources":["../../src/displays/displays.tsx"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,YAAY,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAI3D,kGAAkG;AAClG,wBAAgB,UAAU,gCAMzB;AAWD;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAkBzD;AAED,0BAA0B;AAC1B,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAetD;AAED,6CAA6C;AAC7C,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAQpD;AAED,4CAA4C;AAC5C,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAcrD;AAkBD,2CAA2C;AAC3C,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAOlD;AAED,sEAAsE;AACtE,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAWtD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAqB9D;AAED,8FAA8F;AAC9F,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAOnD;AAED,4DAA4D;AAC5D,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAQlD;AAED,qDAAqD;AACrD,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAkB3D;AAED,mCAAmC;AACnC,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAUtD;AAED,iCAAiC;AACjC,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BASjD;AAED,mCAAmC;AACnC,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BASnD;AAED;;;;GAIG;AACH,wBAAgB,UAAU,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAmCxD;AAwBD,4FAA4F;AAC5F,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAiBrD;AAED;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,EAAE,EAAE,YAAY,+BAsBjE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAa7D;AAED,mCAAmC;AACnC,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAUlD;AAED,yDAAyD;AACzD,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BAezD;AAED,gEAAgE;AAChE,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAuBnD;AAED,gDAAgD;AAChD,wBAAgB,eAAe,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAsBtD;AAED,0FAA0F;AAC1F,wBAAgB,cAAc,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAsBrD;AAID;;;GAGG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAiClD;AAED;;;GAGG;AACH,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,KAAK,EAAE,EAAE,YAAY,+BA0B1D;AAED,sEAAsE;AACtE,wBAAgB,YAAY,CAAC,EAAE,KAAK,EAAE,EAAE,YAAY,+BAmBnD;AAED;;;;GAIG;AACH,eAAO,MAAM,eAAe,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CA6BlE,CAAC"}
|
|
@@ -14,7 +14,7 @@ import { formatDateRange, getDateRangeSettings } from "@panneau/fields/daterange
|
|
|
14
14
|
import { formatDuration, getDurationUnits } from "@panneau/fields/duration";
|
|
15
15
|
import { getLinkText, isLink } from "@panneau/fields/link";
|
|
16
16
|
import { formatMoney } from "@panneau/fields/money";
|
|
17
|
-
import { getRegionCountry, getRegionName } from "@panneau/fields/region";
|
|
17
|
+
import { RegionFlag, getRegionCountry, getRegionName } from "@panneau/fields/region";
|
|
18
18
|
import { parsePhone, splitExtension } from "@panneau/fields/tel";
|
|
19
19
|
//#region src/displays/displays.tsx
|
|
20
20
|
/** What a cell shows without a value. Hidden from assistive technologies, which skip the cell. */
|
|
@@ -81,6 +81,7 @@ function TextDisplay(t0) {
|
|
|
81
81
|
if ($[8] !== text) {
|
|
82
82
|
t2 = /* @__PURE__ */ jsx("span", {
|
|
83
83
|
className: Displays_module_default.text,
|
|
84
|
+
"data-clamp": "",
|
|
84
85
|
children: text
|
|
85
86
|
});
|
|
86
87
|
$[8] = text;
|
|
@@ -103,6 +104,7 @@ function RichTextDisplay(t0) {
|
|
|
103
104
|
if ($[2] !== text) {
|
|
104
105
|
t2 = text === "" ? /* @__PURE__ */ jsx(EmptyValue, {}) : /* @__PURE__ */ jsx("span", {
|
|
105
106
|
className: Displays_module_default.text,
|
|
107
|
+
"data-clamp": "",
|
|
106
108
|
children: text
|
|
107
109
|
});
|
|
108
110
|
$[2] = text;
|
|
@@ -334,6 +336,7 @@ function DateRangeDisplay(t0) {
|
|
|
334
336
|
if ($[6] !== text) {
|
|
335
337
|
t3 = /* @__PURE__ */ jsx("span", {
|
|
336
338
|
className: Displays_module_default.text,
|
|
339
|
+
"data-clamp": "",
|
|
337
340
|
children: text
|
|
338
341
|
});
|
|
339
342
|
$[6] = text;
|
|
@@ -477,48 +480,54 @@ function SelectDisplay(t0) {
|
|
|
477
480
|
}
|
|
478
481
|
/** The labels of related items. */
|
|
479
482
|
function RelationDisplay(t0) {
|
|
480
|
-
const $ = c(
|
|
483
|
+
const $ = c(10);
|
|
481
484
|
const { value } = t0;
|
|
482
485
|
let t1;
|
|
483
486
|
let t2;
|
|
484
487
|
let t3;
|
|
488
|
+
let t4;
|
|
485
489
|
if ($[0] !== value) {
|
|
486
|
-
|
|
490
|
+
t4 = Symbol.for("react.early_return_sentinel");
|
|
487
491
|
bb0: {
|
|
488
492
|
const references = toReferences(value);
|
|
489
493
|
if (references.length === 0) {
|
|
490
|
-
let
|
|
491
|
-
if ($[
|
|
492
|
-
|
|
493
|
-
$[
|
|
494
|
-
} else
|
|
495
|
-
|
|
494
|
+
let t5;
|
|
495
|
+
if ($[5] === Symbol.for("react.memo_cache_sentinel")) {
|
|
496
|
+
t5 = /* @__PURE__ */ jsx(EmptyValue, {});
|
|
497
|
+
$[5] = t5;
|
|
498
|
+
} else t5 = $[5];
|
|
499
|
+
t4 = t5;
|
|
496
500
|
break bb0;
|
|
497
501
|
}
|
|
498
502
|
t1 = Displays_module_default.text;
|
|
499
|
-
t2 =
|
|
503
|
+
t2 = "";
|
|
504
|
+
t3 = references.map(_temp).join(", ");
|
|
500
505
|
}
|
|
501
506
|
$[0] = value;
|
|
502
507
|
$[1] = t1;
|
|
503
508
|
$[2] = t2;
|
|
504
509
|
$[3] = t3;
|
|
510
|
+
$[4] = t4;
|
|
505
511
|
} else {
|
|
506
512
|
t1 = $[1];
|
|
507
513
|
t2 = $[2];
|
|
508
514
|
t3 = $[3];
|
|
515
|
+
t4 = $[4];
|
|
509
516
|
}
|
|
510
|
-
if (
|
|
511
|
-
let
|
|
512
|
-
if ($[
|
|
513
|
-
|
|
517
|
+
if (t4 !== Symbol.for("react.early_return_sentinel")) return t4;
|
|
518
|
+
let t5;
|
|
519
|
+
if ($[6] !== t1 || $[7] !== t2 || $[8] !== t3) {
|
|
520
|
+
t5 = /* @__PURE__ */ jsx("span", {
|
|
514
521
|
className: t1,
|
|
515
|
-
|
|
522
|
+
"data-clamp": t2,
|
|
523
|
+
children: t3
|
|
516
524
|
});
|
|
517
|
-
$[
|
|
518
|
-
$[
|
|
519
|
-
$[
|
|
520
|
-
|
|
521
|
-
|
|
525
|
+
$[6] = t1;
|
|
526
|
+
$[7] = t2;
|
|
527
|
+
$[8] = t3;
|
|
528
|
+
$[9] = t5;
|
|
529
|
+
} else t5 = $[9];
|
|
530
|
+
return t5;
|
|
522
531
|
}
|
|
523
532
|
/** A link that opens the URL. */
|
|
524
533
|
function _temp(reference) {
|
|
@@ -697,6 +706,7 @@ function Country(t0) {
|
|
|
697
706
|
if ($[0] !== code) {
|
|
698
707
|
t1 = /* @__PURE__ */ jsx("span", {
|
|
699
708
|
className: Displays_module_default.text,
|
|
709
|
+
"data-clamp": "",
|
|
700
710
|
children: code
|
|
701
711
|
});
|
|
702
712
|
$[0] = code;
|
|
@@ -731,6 +741,7 @@ function Country(t0) {
|
|
|
731
741
|
if ($[9] !== t3) {
|
|
732
742
|
t4 = /* @__PURE__ */ jsx("span", {
|
|
733
743
|
className: Displays_module_default.text,
|
|
744
|
+
"data-clamp": "",
|
|
734
745
|
children: t3
|
|
735
746
|
});
|
|
736
747
|
$[9] = t3;
|
|
@@ -798,8 +809,9 @@ function CountryDisplay(t0) {
|
|
|
798
809
|
return t4;
|
|
799
810
|
}
|
|
800
811
|
/**
|
|
801
|
-
* A region: its name in the user's locale, from its country in the
|
|
802
|
-
* the field's settings. A region that Panneau doesn't know shows as it
|
|
812
|
+
* A region: its flag, when it has one, and its name in the user's locale, from its country in the
|
|
813
|
+
* item (the field's `from`) or the field's settings. A region that Panneau doesn't know shows as it
|
|
814
|
+
* is.
|
|
803
815
|
*/
|
|
804
816
|
function _temp3(code_0) {
|
|
805
817
|
return /* @__PURE__ */ jsx(Country, { code: code_0 }, code_0);
|
|
@@ -808,7 +820,7 @@ function _temp2(code) {
|
|
|
808
820
|
return typeof code === "string" && code !== "";
|
|
809
821
|
}
|
|
810
822
|
function RegionDisplay(t0) {
|
|
811
|
-
const $ = c(
|
|
823
|
+
const $ = c(17);
|
|
812
824
|
const { value, field, item } = t0;
|
|
813
825
|
const intl = usePanneauIntl();
|
|
814
826
|
if (typeof value !== "string" || value === "") {
|
|
@@ -819,33 +831,67 @@ function RegionDisplay(t0) {
|
|
|
819
831
|
} else t1 = $[0];
|
|
820
832
|
return t1;
|
|
821
833
|
}
|
|
834
|
+
let country;
|
|
822
835
|
let t1;
|
|
823
|
-
let t2;
|
|
824
836
|
if ($[1] !== field || $[2] !== intl.locale || $[3] !== item || $[4] !== value) {
|
|
825
|
-
|
|
826
|
-
t1 =
|
|
827
|
-
t2 = getRegionName(country, value, intl.locale) ?? value;
|
|
837
|
+
country = field !== null ? getRegionCountry(field, item) : null;
|
|
838
|
+
t1 = getRegionName(country, value, intl.locale);
|
|
828
839
|
$[1] = field;
|
|
829
840
|
$[2] = intl.locale;
|
|
830
841
|
$[3] = item;
|
|
831
842
|
$[4] = value;
|
|
832
|
-
$[5] =
|
|
833
|
-
$[6] =
|
|
843
|
+
$[5] = country;
|
|
844
|
+
$[6] = t1;
|
|
834
845
|
} else {
|
|
835
|
-
|
|
836
|
-
|
|
846
|
+
country = $[5];
|
|
847
|
+
t1 = $[6];
|
|
837
848
|
}
|
|
849
|
+
const name = t1;
|
|
850
|
+
if (name === null) {
|
|
851
|
+
let t2;
|
|
852
|
+
if ($[7] !== value) {
|
|
853
|
+
t2 = /* @__PURE__ */ jsx("span", {
|
|
854
|
+
className: Displays_module_default.text,
|
|
855
|
+
"data-clamp": "",
|
|
856
|
+
children: value
|
|
857
|
+
});
|
|
858
|
+
$[7] = value;
|
|
859
|
+
$[8] = t2;
|
|
860
|
+
} else t2 = $[8];
|
|
861
|
+
return t2;
|
|
862
|
+
}
|
|
863
|
+
let t2;
|
|
864
|
+
if ($[9] !== country || $[10] !== value) {
|
|
865
|
+
t2 = /* @__PURE__ */ jsx(RegionFlag, {
|
|
866
|
+
country,
|
|
867
|
+
code: value,
|
|
868
|
+
className: Displays_module_default.regionFlag
|
|
869
|
+
});
|
|
870
|
+
$[9] = country;
|
|
871
|
+
$[10] = value;
|
|
872
|
+
$[11] = t2;
|
|
873
|
+
} else t2 = $[11];
|
|
838
874
|
let t3;
|
|
839
|
-
if ($[
|
|
875
|
+
if ($[12] !== name) {
|
|
840
876
|
t3 = /* @__PURE__ */ jsx("span", {
|
|
841
|
-
className:
|
|
842
|
-
|
|
877
|
+
className: Displays_module_default.text,
|
|
878
|
+
"data-clamp": "",
|
|
879
|
+
children: name
|
|
843
880
|
});
|
|
844
|
-
$[
|
|
845
|
-
$[
|
|
846
|
-
|
|
847
|
-
|
|
848
|
-
|
|
881
|
+
$[12] = name;
|
|
882
|
+
$[13] = t3;
|
|
883
|
+
} else t3 = $[13];
|
|
884
|
+
let t4;
|
|
885
|
+
if ($[14] !== t2 || $[15] !== t3) {
|
|
886
|
+
t4 = /* @__PURE__ */ jsxs("span", {
|
|
887
|
+
className: Displays_module_default.flagged,
|
|
888
|
+
children: [t2, t3]
|
|
889
|
+
});
|
|
890
|
+
$[14] = t2;
|
|
891
|
+
$[15] = t3;
|
|
892
|
+
$[16] = t4;
|
|
893
|
+
} else t4 = $[16];
|
|
894
|
+
return t4;
|
|
849
895
|
}
|
|
850
896
|
/**
|
|
851
897
|
* A duration with its units, `1 h 5 min` or `2 d 4 h`: in the unit of its field (seconds by
|
|
@@ -1038,6 +1084,7 @@ function EmbedDisplay(t0) {
|
|
|
1038
1084
|
if ($[6] !== t2) {
|
|
1039
1085
|
t3 = /* @__PURE__ */ jsx("span", {
|
|
1040
1086
|
className: Displays_module_default.text,
|
|
1087
|
+
"data-clamp": "",
|
|
1041
1088
|
children: t2
|
|
1042
1089
|
});
|
|
1043
1090
|
$[6] = t2;
|
|
@@ -1078,6 +1125,7 @@ function LocationDisplay(t0) {
|
|
|
1078
1125
|
if ($[1] !== address) {
|
|
1079
1126
|
t1 = /* @__PURE__ */ jsx("span", {
|
|
1080
1127
|
className: Displays_module_default.text,
|
|
1128
|
+
"data-clamp": "",
|
|
1081
1129
|
children: address
|
|
1082
1130
|
});
|
|
1083
1131
|
$[1] = address;
|
|
@@ -1183,6 +1231,7 @@ function AddressDisplay(t0) {
|
|
|
1183
1231
|
if ($[12] !== t3) {
|
|
1184
1232
|
t4 = /* @__PURE__ */ jsx("span", {
|
|
1185
1233
|
className: Displays_module_default.text,
|
|
1234
|
+
"data-clamp": "",
|
|
1186
1235
|
children: t3
|
|
1187
1236
|
});
|
|
1188
1237
|
$[12] = t3;
|
|
@@ -1256,6 +1305,7 @@ function LinkDisplay(t0) {
|
|
|
1256
1305
|
if ($[7] !== text) {
|
|
1257
1306
|
t4 = /* @__PURE__ */ jsx("span", {
|
|
1258
1307
|
className: Displays_module_default.text,
|
|
1308
|
+
"data-clamp": "",
|
|
1259
1309
|
children: text
|
|
1260
1310
|
});
|
|
1261
1311
|
$[7] = text;
|
|
@@ -1341,6 +1391,7 @@ function ColorDisplay(t0) {
|
|
|
1341
1391
|
if ($[8] !== t4) {
|
|
1342
1392
|
t5 = /* @__PURE__ */ jsx("span", {
|
|
1343
1393
|
className: Displays_module_default.text,
|
|
1394
|
+
"data-clamp": "",
|
|
1344
1395
|
children: t4
|
|
1345
1396
|
});
|
|
1346
1397
|
$[8] = t4;
|
|
@@ -1417,6 +1468,7 @@ function MediaDisplay(t0) {
|
|
|
1417
1468
|
if ($[3] !== label) {
|
|
1418
1469
|
t2 = label !== "" ? /* @__PURE__ */ jsx("span", {
|
|
1419
1470
|
className: Displays_module_default.text,
|
|
1471
|
+
"data-clamp": "",
|
|
1420
1472
|
children: label
|
|
1421
1473
|
}) : null;
|
|
1422
1474
|
$[3] = label;
|