@upbound/monarch-blocks 0.4.1 → 0.6.0

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/README.md CHANGED
@@ -51,6 +51,23 @@ import { DataTable } from '@upbound/monarch-blocks/data-table';
51
51
  Same caveat as `monarch-core`: the root barrel bundles every component into one file and is a client boundary
52
52
  unconditionally. Import a component's own subpath if you need it in a context where that matters.
53
53
 
54
+ ## Graph needs its own CSS
55
+
56
+ `Graph`/`GraphView` render on [ReactFlow](https://reactflow.dev), which ships its own base stylesheet for
57
+ `Controls`/`MiniMap`/`Background`/handle positioning. This is the one component in the package that ships CSS — import
58
+ it once, alongside `monarch-core`'s theme:
59
+
60
+ ```css
61
+ @import 'tailwindcss';
62
+ @import '@upbound/monarch-core/theme.css';
63
+ @import '@upbound/monarch-blocks/graph.css';
64
+
65
+ @source '../../node_modules/@upbound/monarch-core/dist/*.js';
66
+ @source '../../node_modules/@upbound/monarch-blocks/dist/*.js';
67
+ ```
68
+
69
+ No other component in this package needs a CSS import.
70
+
54
71
  ## Not part of the shadcn registry
55
72
 
56
73
  Unlike `@upbound/monarch-core`, these components are **not** available through `npx shadcn add @monarch/...` — the
@@ -66,6 +66,9 @@ var twMerge = extendTailwindMerge({
66
66
  function cn(...inputs) {
67
67
  return twMerge(clsx(inputs));
68
68
  }
69
+ function sortBy(items, getKey) {
70
+ return [...items].sort((a, b) => getKey(a).localeCompare(getKey(b)));
71
+ }
69
72
 
70
73
  // src/hooks/use-mounted.ts
71
74
  import { useSyncExternalStore } from "react";
@@ -1218,6 +1221,7 @@ function CelFilterBar({
1218
1221
  (_a = onCompileResultChangeRef.current) == null ? void 0 : _a.call(onCompileResultChangeRef, __spreadProps(__spreadValues({}, displayResult), { isEmitReady }));
1219
1222
  }, [displayResult, isEmitReady]);
1220
1223
  const conditions = tree.root.children.filter(isCelFilterCondition);
1224
+ const containerRef = React.useRef(null);
1221
1225
  function handleAddFilter(columnId) {
1222
1226
  const condition = createDefaultCondition({ schema, columnId });
1223
1227
  onChange(appendCondition(tree, condition));
@@ -1232,8 +1236,8 @@ function CelFilterBar({
1232
1236
  onChange({ root: __spreadProps(__spreadValues({}, tree.root), { children: [] }) });
1233
1237
  editor.clearSuppress();
1234
1238
  }
1235
- return /* @__PURE__ */ jsxs("div", { "data-slot": "cel-filter-bar", className: cn("flex flex-wrap items-center gap-2", className), children: [
1236
- /* @__PURE__ */ jsx(CelAddFilterButton, { schema, conditions, onSelect: handleAddFilter }),
1239
+ return /* @__PURE__ */ jsxs("div", { "data-slot": "cel-filter-bar", className: cn("flex flex-wrap items-center gap-2", className), ref: containerRef, children: [
1240
+ /* @__PURE__ */ jsx(CelAddFilterButton, { schema, conditions, onSelect: handleAddFilter, container: containerRef }),
1237
1241
  conditions.map((condition) => {
1238
1242
  const columnDef = resolveColumnDefinition(condition, schema);
1239
1243
  if (!columnDef) return null;
@@ -1248,7 +1252,8 @@ function CelFilterBar({
1248
1252
  controller: editor.getController(condition.id),
1249
1253
  issues: displayResult.issues.filter((issue) => issue.nodeId === condition.id),
1250
1254
  onRemove: () => handleRemove(condition.id),
1251
- onRestrictedOptionSelect
1255
+ onRestrictedOptionSelect,
1256
+ container: containerRef
1252
1257
  },
1253
1258
  condition.id
1254
1259
  );
@@ -1259,7 +1264,8 @@ function CelFilterBar({
1259
1264
  function CelAddFilterButton({
1260
1265
  schema,
1261
1266
  conditions,
1262
- onSelect
1267
+ onSelect,
1268
+ container
1263
1269
  }) {
1264
1270
  var _a, _b;
1265
1271
  const usedSingleInstanceColumnIds = new Set(
@@ -1275,7 +1281,10 @@ function CelAddFilterButton({
1275
1281
  list.push(column);
1276
1282
  groupMap.set(key, list);
1277
1283
  }
1278
- const groups = Array.from(groupMap.entries()).map(([value, items]) => ({ value, items }));
1284
+ const groups = sortBy(
1285
+ Array.from(groupMap.entries()).map(([value, items]) => ({ value, items: sortBy(items, (item) => item.title) })),
1286
+ (group) => group.value
1287
+ );
1279
1288
  return /* @__PURE__ */ jsxs(
1280
1289
  Combobox,
1281
1290
  {
@@ -1290,7 +1299,7 @@ function CelAddFilterButton({
1290
1299
  /* @__PURE__ */ jsx(Icon, { name: "plus", "data-icon": "inline-start" }),
1291
1300
  "Add filter"
1292
1301
  ] }),
1293
- /* @__PURE__ */ jsxs(ComboboxContent, { align: "start", className: "w-64", children: [
1302
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, align: "start", className: "w-64", children: [
1294
1303
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: "Search filters\u2026" }),
1295
1304
  /* @__PURE__ */ jsx(ComboboxEmpty, { children: "No filters found." }),
1296
1305
  /* @__PURE__ */ jsx(ComboboxList, { children: (group) => /* @__PURE__ */ jsxs(ComboboxGroup, { items: group.items, children: [
@@ -1354,7 +1363,8 @@ function CelFilterPill({
1354
1363
  controller,
1355
1364
  issues,
1356
1365
  onRemove,
1357
- onRestrictedOptionSelect
1366
+ onRestrictedOptionSelect,
1367
+ container
1358
1368
  }) {
1359
1369
  var _a;
1360
1370
  const shape = (_a = resolveFilterShape(condition, schema)) != null ? _a : columnDef.filterType;
@@ -1371,7 +1381,8 @@ function CelFilterPill({
1371
1381
  controller,
1372
1382
  issues,
1373
1383
  onRemove,
1374
- onRestrictedOptionSelect
1384
+ onRestrictedOptionSelect,
1385
+ container
1375
1386
  }
1376
1387
  );
1377
1388
  }
@@ -1386,7 +1397,8 @@ function CelFilterPill({
1386
1397
  controller,
1387
1398
  issues,
1388
1399
  onRemove,
1389
- onRestrictedOptionSelect
1400
+ onRestrictedOptionSelect,
1401
+ container
1390
1402
  }
1391
1403
  );
1392
1404
  }
@@ -1496,10 +1508,11 @@ function CelCheckboxComboboxPill({
1496
1508
  controller,
1497
1509
  issues,
1498
1510
  onRemove,
1499
- onRestrictedOptionSelect
1511
+ onRestrictedOptionSelect,
1512
+ container
1500
1513
  }) {
1501
1514
  var _a;
1502
- const options = (_a = columnDef.options) != null ? _a : [];
1515
+ const options = sortBy((_a = columnDef.options) != null ? _a : [], (o) => o.label);
1503
1516
  const value = isCheckboxCelValue(condition.value) ? condition.value : [];
1504
1517
  const selected = options.filter((option) => value.includes(option.value));
1505
1518
  const allowedOperators = getAllowedOperators(columnDef);
@@ -1555,7 +1568,7 @@ function CelCheckboxComboboxPill({
1555
1568
  ),
1556
1569
  /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": `Remove ${columnDef.title} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx(Icon, { name: "xmark" }) })
1557
1570
  ] }),
1558
- /* @__PURE__ */ jsxs(ComboboxContent, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1571
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1559
1572
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: `Search ${columnDef.title.toLowerCase()}\u2026` }),
1560
1573
  selected.length > 0 && /* @__PURE__ */ jsxs(Fragment, { children: [
1561
1574
  /* @__PURE__ */ jsxs(ComboboxSelectedChips, { children: [
@@ -1584,10 +1597,11 @@ function CelRadioComboboxPill({
1584
1597
  controller,
1585
1598
  issues,
1586
1599
  onRemove,
1587
- onRestrictedOptionSelect
1600
+ onRestrictedOptionSelect,
1601
+ container
1588
1602
  }) {
1589
1603
  var _a, _b;
1590
- const options = (_a = columnDef.options) != null ? _a : [];
1604
+ const options = sortBy((_a = columnDef.options) != null ? _a : [], (o) => o.label);
1591
1605
  const value = typeof condition.value === "string" ? condition.value : "";
1592
1606
  const selected = (_b = options.find((option) => option.value === value)) != null ? _b : null;
1593
1607
  const allowedOperators = getAllowedOperators(columnDef);
@@ -1639,7 +1653,7 @@ function CelRadioComboboxPill({
1639
1653
  ),
1640
1654
  /* @__PURE__ */ jsx(Button, { variant: "outline", size: "icon", "aria-label": `Remove ${columnDef.title} filter`, onClick: onRemove, children: /* @__PURE__ */ jsx(Icon, { name: "xmark" }) })
1641
1655
  ] }),
1642
- /* @__PURE__ */ jsxs(ComboboxContent, { className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1656
+ /* @__PURE__ */ jsxs(ComboboxContent, { container, className: "min-w-64", collisionAvoidance: { side: "none", align: "shift" }, children: [
1643
1657
  /* @__PURE__ */ jsx(ComboboxInput, { showTrigger: false, placeholder: `Search ${columnDef.title.toLowerCase()}\u2026` }),
1644
1658
  /* @__PURE__ */ jsxs(ComboboxEmpty, { children: [
1645
1659
  "No ",