@protobase/ui 0.21.2 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/app/current-address.js +2 -2
  2. package/dist/app/displays/display-controls.js +3 -4
  3. package/dist/app/displays/list-displays.js +58 -4
  4. package/dist/app/displays/record-card.js +2 -2
  5. package/dist/app/embedded-list/embedded-columns.js +1 -1
  6. package/dist/app/embedded-list/embedded-display.js +6 -2
  7. package/dist/app/embedded-list/embedded-list.js +1 -1
  8. package/dist/app/field-editor.js +1 -1
  9. package/dist/app/list-page.js +6 -4
  10. package/dist/app/pages/field-value.js +1 -1
  11. package/dist/app/record-page.js +2 -2
  12. package/dist/app/related-dots/related-dots-columns.js +2 -1
  13. package/dist/app/related-dots/related-dots.js +1 -1
  14. package/dist/data-grid/cell-text.js +30 -0
  15. package/dist/data-grid/cells.js +27 -35
  16. package/dist/data-grid/content-widths.js +81 -0
  17. package/dist/data-grid/data-grid.js +10 -5
  18. package/dist/data-grid/default-pins.js +13 -0
  19. package/dist/data-grid/pinned-storage.js +2 -1
  20. package/dist/data-grid/truncated-text.js +16 -0
  21. package/dist/data-grid/use-fitted-columns.js +28 -0
  22. package/dist/data-grid/use-pinned-columns.js +6 -5
  23. package/dist/live/columns-from-model.js +6 -6
  24. package/dist/package.js +1 -1
  25. package/dist/shell/assets/app-wZRscg1o.js +69 -0
  26. package/dist/shell/assets/index-C1fzTv_X.css +2 -0
  27. package/dist/shell/assets/{index-7lQIOMrK.js → index-RHKnIOOP.js} +1 -1
  28. package/dist/shell/assets/{maplibre-DEejTZ7I.js → maplibre-DN_v_fcJ.js} +1 -1
  29. package/dist/shell/assets/{markdown-content-ZzP9i4q4.js → markdown-content-Be4vIiWm.js} +1 -1
  30. package/dist/shell/assets/{record-map-B-zsmXL2.js → record-map-CVeshts3.js} +1 -1
  31. package/dist/shell/assets/{records-map-Lj1MQgsW.js → records-map-ClnWq-RH.js} +1 -1
  32. package/dist/shell/assets/{shared-protobase-ui-Bnd7T1j4.js → shared-protobase-ui-DWCBNg3c.js} +1 -1
  33. package/dist/shell/index.html +4 -4
  34. package/dist/shell/protobase.shell.json +1 -1
  35. package/package.json +4 -4
  36. package/dist/shell/assets/app-BnuJWZWd.js +0 -69
  37. package/dist/shell/assets/index-B48ty05p.css +0 -2
@@ -0,0 +1,16 @@
1
+ import { cn } from "../lib/cn.js";
2
+ import { jsx } from "react/jsx-runtime";
3
+ //#region src/data-grid/truncated-text.tsx
4
+ const offerWhole = (text) => (event) => {
5
+ const span = event.currentTarget;
6
+ if (span.scrollWidth > Math.ceil(span.getBoundingClientRect().width)) span.title = text;
7
+ else span.removeAttribute("title");
8
+ };
9
+ /** Text cut to one line with an ellipsis, that shows whole as a tooltip when hovered while cut. */
10
+ const TruncatedText = ({ text, className }) => /* @__PURE__ */ jsx("span", {
11
+ className: cn("truncate", className),
12
+ onMouseEnter: offerWhole(text),
13
+ children: text
14
+ });
15
+ //#endregion
16
+ export { TruncatedText };
@@ -0,0 +1,28 @@
1
+ import { fitColumns } from "./content-widths.js";
2
+ import { useMemo, useState } from "react";
3
+ //#region src/data-grid/use-fitted-columns.ts
4
+ const sizesOf = (specs) => Object.fromEntries(specs.map(({ id, width, minWidth, fixed }) => [id, {
5
+ width,
6
+ minWidth,
7
+ fixed
8
+ }]));
9
+ /**
10
+ * `columns` sized by the first rows shown, fitted once per set of columns: later pages, filters and sorts keep those
11
+ * widths, so columns never jump while scrolling, and a longer value later on is cut, with the whole of it on hover.
12
+ */
13
+ const useFittedColumns = (columns, rows) => {
14
+ const key = columns.map((spec) => spec.id).sort().join(" ");
15
+ const [fitted, setFitted] = useState();
16
+ const current = fitted?.key === key ? fitted : void 0;
17
+ if (!current && rows.length > 0) setFitted({
18
+ key,
19
+ sizes: sizesOf(fitColumns(columns, rows))
20
+ });
21
+ const sizes = current?.sizes;
22
+ return useMemo(() => sizes ? columns.map((spec) => ({
23
+ ...spec,
24
+ ...sizes[spec.id]
25
+ })) : columns, [columns, sizes]);
26
+ };
27
+ //#endregion
28
+ export { useFittedColumns };
@@ -3,14 +3,15 @@ import { useCallback, useState } from "react";
3
3
  //#region src/data-grid/use-pinned-columns.ts
4
4
  /**
5
5
  * The ids of the columns pinned to the left, in pin order. With a `storageKey` the choice is kept in local storage
6
- * (per user and resource); `initial` applies until the user has chosen.
6
+ * (per user and resource); `initial` applies until the user has chosen, as it is on each render.
7
7
  */
8
8
  const usePinnedColumns = (storageKey, initial = []) => {
9
- const [pinned, setPinned] = useState(() => (storageKey ? readPinned(localStorage, storageKey) : void 0) ?? initial);
10
- return [pinned, useCallback((next) => {
11
- setPinned(next);
9
+ const [chosen, setChosen] = useState(() => storageKey ? readPinned(localStorage, storageKey) : void 0);
10
+ const update = useCallback((next) => {
11
+ setChosen(next);
12
12
  if (storageKey) writePinned(localStorage, storageKey, next);
13
- }, [storageKey])];
13
+ }, [storageKey]);
14
+ return [chosen ?? initial, update];
14
15
  };
15
16
  //#endregion
16
17
  export { usePinnedColumns };
@@ -1,6 +1,8 @@
1
+ import { recordTitleField } from "./model-helpers.js";
1
2
  import { humanize } from "./naming.js";
2
- import { isMarkdown } from "../markdown/markdown-hint.js";
3
+ import { badgeWidth, headerWidth } from "../data-grid/content-widths.js";
3
4
  import { markdownExcerpt } from "../markdown/markdown-excerpt.js";
5
+ import { isMarkdown } from "../markdown/markdown-hint.js";
4
6
  import { enumLabel } from "@protobase/schema";
5
7
  //#region src/live/columns-from-model.ts
6
8
  const tones = {
@@ -37,10 +39,6 @@ const widths = {
37
39
  user: 130,
38
40
  file: 180
39
41
  };
40
- /** Room for a header at 12px plus cell padding, the sort arrow and the column menu button. */
41
- const headerWidth = (header, sortable) => Math.ceil(header.length * 7.2) + 24 + (sortable ? 16 : 0) + 28;
42
- /** A status badge: dot, padding and the longest label. */
43
- const badgeWidth = (labels) => Math.ceil(Math.max(0, ...labels.map((label) => label.length)) * 7.2) + 56;
44
42
  const fixedKinds = /* @__PURE__ */ new Set([
45
43
  "datetime",
46
44
  "date",
@@ -67,6 +65,7 @@ const currencyCents = (value) => Math.round(Number.parseFloat(String(value)) * 1
67
65
  const listColumnNames = (resource, view) => view?.list?.columns ?? Object.keys(resource.fields).slice(0, 6);
68
66
  /** Grid columns for `names`, by default the view's list: kinds follow the field types and the view's format hints. */
69
67
  const columnsFromModel = (resource, view, highlight = [], names = listColumnNames(resource, view)) => {
68
+ const title = recordTitleField(resource, view);
70
69
  return names.flatMap((name, index) => {
71
70
  const field = resource.fields[name];
72
71
  if (!field) return [];
@@ -82,6 +81,7 @@ const columnsFromModel = (resource, view, highlight = [], names = listColumnName
82
81
  sortable: field.sortable,
83
82
  minWidth: Math.max(kind === "id" ? 150 : 0, headerWidth(viewField?.label ?? humanize(name), field.sortable), kind === "status" ? badgeWidth(Object.values(labels)) : 0, suffixWidth > 0 ? widths[kind] + suffixWidth : 0),
84
83
  ...fixedKinds.has(kind) && { fixed: true },
84
+ ...name === title && { title: true },
85
85
  ...highlight.includes(name) && { highlight: true },
86
86
  ...field.type === "enum" && {
87
87
  tones: Object.fromEntries((field.enumValues ?? []).map((value) => [value, toneFor(value)])),
@@ -102,4 +102,4 @@ const columnsFromModel = (resource, view, highlight = [], names = listColumnName
102
102
  });
103
103
  };
104
104
  //#endregion
105
- export { columnsFromModel, headerWidth, listColumnNames, toneFor };
105
+ export { columnsFromModel, listColumnNames, toneFor };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.21.2";
2
+ var version = "0.21.3";
3
3
  var protobase = { "pluginApi": 1 };
4
4
  //#endregion
5
5
  export { protobase, version };