@protobase/ui 0.12.1 → 0.12.2

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.
@@ -1,9 +1,10 @@
1
+ import { defaultDisplay } from "./displays/list-displays.js";
1
2
  import { defaultOrderBy } from "./list-order.js";
2
- import { encodeKey, tableDisplay } from "@protobase/schema";
3
+ import { encodeKey } from "@protobase/schema";
3
4
  //#region src/app/current-address.ts
4
- /** What a list shows when its address names nothing: the view's default display, the list's sort, the filters in a bar. */
5
- const listDefaults = (model, view) => ({
6
- display: view?.list?.default ?? tableDisplay,
5
+ /** What a list shows when its address names nothing: its default display for the screen, the list's sort, the filters in a bar. */
6
+ const listDefaults = (model, view, xs = false) => ({
7
+ display: defaultDisplay(view, xs),
7
8
  orderBy: model ? defaultOrderBy(model, view) : "",
8
9
  filterLayout: "bar"
9
10
  });
@@ -1,6 +1,7 @@
1
1
  import { Badge } from "../../primitives/badge.js";
2
2
  import { humanize } from "../../live/naming.js";
3
3
  import { useProjectUi } from "../pages/project-ui.js";
4
+ import { cardFields } from "./list-displays.js";
4
5
  import { AppLink } from "../use-app-address.js";
5
6
  import { displayValue } from "../../live/display-value.js";
6
7
  import { shownWidget } from "../field-types/shown-widget.js";
@@ -9,7 +10,6 @@ import { WidgetPart } from "../field-types/widget-part.js";
9
10
  import { Skeleton } from "../../primitives/skeleton.js";
10
11
  import { toneFor } from "../../live/columns-from-model.js";
11
12
  import { DisplayFooter, DisplayState } from "./display-frame.js";
12
- import { cardFields } from "./list-displays.js";
13
13
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
14
14
  //#region src/app/displays/cards-display.tsx
15
15
  const grid = "grid grid-cols-[repeat(auto-fill,minmax(15rem,1fr))] gap-3";
@@ -1,6 +1,6 @@
1
1
  import { humanize } from "../../live/naming.js";
2
- import { parseSort } from "../list-order.js";
3
2
  import { displayChoices, sortFields } from "./list-displays.js";
3
+ import { parseSort } from "../list-order.js";
4
4
  import { Segmented } from "../../primitives/segmented.js";
5
5
  import { Calendar, Columns3, LayoutGrid, List, SquareKanban, Table2 } from "lucide-react";
6
6
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -3,6 +3,16 @@ import { humanize } from "../../live/naming.js";
3
3
  import { encodeKey, tableDisplay } from "@protobase/schema";
4
4
  //#region src/app/displays/list-displays.ts
5
5
  const displaysOf = (view) => view?.list?.displays ?? [];
6
+ /**
7
+ * The display a list opens in when its address names none. Below the `sm` breakpoint a list with a cards display opens
8
+ * in one: the view's default when that is a cards display, else the first. Otherwise the view's default, or the table.
9
+ */
10
+ const defaultDisplay = (view, xs) => {
11
+ const fallback = view?.list?.default ?? tableDisplay;
12
+ if (!xs) return fallback;
13
+ const cards = displaysOf(view).filter((display) => display.kind === "cards");
14
+ return cards.find((display) => display.name === fallback)?.name ?? cards[0]?.name ?? fallback;
15
+ };
6
16
  /** The display a list shows for the address's `name`: `undefined` for the table, and the view's default for a name it does not have. */
7
17
  const shownDisplay = (view, name) => {
8
18
  if (name === tableDisplay) return void 0;
@@ -59,4 +69,4 @@ const displayRow = (model, row) => {
59
69
  };
60
70
  };
61
71
  //#endregion
62
- export { cardFields, displayChoices, displayRow, displaysOf, loadedFields, shownDisplay, shownFields, sortFields };
72
+ export { cardFields, defaultDisplay, displayChoices, displayRow, displaysOf, loadedFields, shownDisplay, shownFields, sortFields };
@@ -5,6 +5,7 @@ import { Button } from "../primitives/button.js";
5
5
  import { recordKey, recordTitleField } from "../live/model-helpers.js";
6
6
  import { humanize } from "../live/naming.js";
7
7
  import { useProjectUi } from "./pages/project-ui.js";
8
+ import { loadedFields, shownDisplay } from "./displays/list-displays.js";
8
9
  import { parseSort, sortToOrderBy } from "./list-order.js";
9
10
  import { Notice, useAdminMeta, usePermissions } from "./meta-gate.js";
10
11
  import { useAppAddress } from "./use-app-address.js";
@@ -23,7 +24,6 @@ import { useLiveRows } from "../live/use-live-rows.js";
23
24
  import { Sheet } from "../primitives/sheet.js";
24
25
  import { useDeleteFlow } from "./delete/use-delete-flow.js";
25
26
  import { useRestore } from "./delete/use-restore.js";
26
- import { loadedFields, shownDisplay } from "./displays/list-displays.js";
27
27
  import { CardsDisplay } from "./displays/cards-display.js";
28
28
  import { CustomDisplay } from "./displays/custom-display.js";
29
29
  import { DisplaySwitch, SortMenu } from "./displays/display-controls.js";
@@ -1,3 +1,4 @@
1
+ import { useIsXs } from "../lib/use-media-query.js";
1
2
  import { changedList, currentAddress, listDefaults } from "./current-address.js";
2
3
  import { useAdminMeta } from "./meta-gate.js";
3
4
  import { Link, useRouter } from "./router.js";
@@ -13,6 +14,7 @@ import { appPath, readAppPath } from "@protobase/schema";
13
14
  const useAppAddress = () => {
14
15
  const { path, params, basePath, navigate } = useRouter();
15
16
  const { pages, resources, views } = useAdminMeta();
17
+ const xs = useIsXs();
16
18
  const pageNames = useMemo(() => new Set(Object.keys(pages)), [pages]);
17
19
  const query = params.toString();
18
20
  const read = useMemo(() => readAppPath(query ? `${path}?${query}` : path, pageNames), [
@@ -20,7 +22,11 @@ const useAppAddress = () => {
20
22
  query,
21
23
  pageNames
22
24
  ]);
23
- const defaults = useCallback((resource) => listDefaults(resources[resource], views[resource]), [resources, views]);
25
+ const defaults = useCallback((resource) => listDefaults(resources[resource], views[resource], xs), [
26
+ resources,
27
+ views,
28
+ xs
29
+ ]);
24
30
  const address = useMemo(() => currentAddress(read, defaults), [read, defaults]);
25
31
  const go = useCallback((to, options) => navigate(appPath(to), options), [navigate]);
26
32
  return {
@@ -8,5 +8,7 @@ const useMediaQuery = (query) => useSyncExternalStore((onChange) => {
8
8
  }, () => window.matchMedia(query).matches, () => false);
9
9
  /** The `md` breakpoint: where the sidebar stops being a drawer and tables stop squeezing. */
10
10
  const useIsDesktop = () => useMediaQuery("(min-width: 768px)");
11
+ /** Below the `sm` breakpoint: a phone, where a list opens in its cards display. */
12
+ const useIsXs = () => useMediaQuery("not all and (min-width: 640px)");
11
13
  //#endregion
12
- export { useIsDesktop, useMediaQuery };
14
+ export { useIsDesktop, useIsXs, useMediaQuery };
package/dist/package.js CHANGED
@@ -1,5 +1,5 @@
1
1
  //#region package.json
2
- var version = "0.12.1";
2
+ var version = "0.12.2";
3
3
  var protobase = { "pluginApi": 1 };
4
4
  //#endregion
5
5
  export { protobase, version };