@jackbernnie/hiyf 0.3.6 → 0.3.8

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.
@@ -48,7 +48,7 @@ function AerialEmbed({
48
48
  rel: "noreferrer",
49
49
  title,
50
50
  "aria-label": `${title} \u2014 open satellite view`,
51
- className: "relative block w-full overflow-hidden rounded-lg bg-muted",
51
+ className: "relative block w-full shrink-0 overflow-hidden rounded-lg bg-muted",
52
52
  style: { height: AERIAL_HEIGHT },
53
53
  children: [
54
54
  /* @__PURE__ */ jsx("div", { className: "absolute left-1/2 top-1/2", children: tiles.map((tile) => /* @__PURE__ */ jsx(
@@ -107,7 +107,7 @@ function MapEmbed({
107
107
  const half = Math.min(20, Math.max(4e-3, 40 / 2 ** clampedZoom));
108
108
  const bbox = `${lon - half},${lat - half},${lon + half},${lat + half}`;
109
109
  const src = `https://www.openstreetmap.org/export/embed.html?bbox=${bbox}&layer=mapnik&marker=${lat},${lon}`;
110
- return /* @__PURE__ */ jsx("div", { className: "w-full overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsx(AspectRatio, { ratio: 16 / 9, children: /* @__PURE__ */ jsx(
110
+ return /* @__PURE__ */ jsx("div", { className: "w-full shrink-0 overflow-hidden rounded-lg bg-muted", children: /* @__PURE__ */ jsx(AspectRatio, { ratio: 16 / 9, children: /* @__PURE__ */ jsx(
111
111
  "iframe",
112
112
  {
113
113
  src,
@@ -40,6 +40,17 @@ export interface TableColumn<T> {
40
40
  filterValue?: string;
41
41
  /** Called when a filter option is selected. */
42
42
  onFilterChange?: (value: string) => void;
43
+ /**
44
+ * Multi-select filter mode: the currently selected option values. When provided
45
+ * (with onFilterValuesChange), the header menu renders filterOptions as toggling
46
+ * check items that DON'T close the menu, so several can be selected in one visit.
47
+ * There is no "all" convention in this mode — an empty array means unfiltered, and
48
+ * a "Clear" item appears whenever anything is selected. Mutually exclusive with
49
+ * filterValue/onFilterChange single-select mode.
50
+ */
51
+ filterValues?: string[];
52
+ /** Called with the full updated selection whenever a multi-select option is toggled. */
53
+ onFilterValuesChange?: (values: string[]) => void;
43
54
  /** Optional explanatory text shown in a hover tooltip via an info icon next to the header. */
44
55
  headerInfo?: string;
45
56
  /**
@@ -70,9 +70,16 @@ function HeaderMenu({
70
70
  onSortChange
71
71
  }) {
72
72
  const activeSort = sort?.key === column.key ? sort : void 0;
73
+ const multi = column.filterValues !== void 0;
73
74
  const firstFilterValue = column.filterOptions?.[0]?.value;
74
- const filterActive = column.filterValue !== void 0 && firstFilterValue !== void 0 && column.filterValue !== firstFilterValue;
75
+ const filterActive = multi ? (column.filterValues?.length ?? 0) > 0 : column.filterValue !== void 0 && firstFilterValue !== void 0 && column.filterValue !== firstFilterValue;
75
76
  const active = Boolean(activeSort) || filterActive;
77
+ const toggleValue = (value) => {
78
+ const cur = column.filterValues ?? [];
79
+ column.onFilterValuesChange?.(
80
+ cur.includes(value) ? cur.filter((v) => v !== value) : [...cur, value]
81
+ );
82
+ };
76
83
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
77
84
  /* @__PURE__ */ jsx(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx(
78
85
  "button",
@@ -107,17 +114,43 @@ function HeaderMenu({
107
114
  )
108
115
  ] }),
109
116
  column.sortable && column.filterOptions && column.filterOptions.length > 0 && /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
110
- column.filterOptions?.map((option) => /* @__PURE__ */ jsxs(
111
- DropdownMenuItem,
112
- {
113
- onSelect: () => column.onFilterChange?.(option.value),
114
- children: [
115
- /* @__PURE__ */ jsx(CheckGlyph, { visible: column.filterValue === option.value }),
116
- option.label
117
- ]
118
- },
119
- option.value
120
- ))
117
+ column.filterOptions?.map(
118
+ (option) => multi ? (
119
+ // Multi-select: toggling keeps the menu open so several values can be
120
+ // picked in one visit (preventDefault stops Radix's close-on-select).
121
+ /* @__PURE__ */ jsxs(
122
+ DropdownMenuItem,
123
+ {
124
+ onSelect: (event) => {
125
+ event.preventDefault();
126
+ toggleValue(option.value);
127
+ },
128
+ children: [
129
+ /* @__PURE__ */ jsx(CheckGlyph, { visible: (column.filterValues ?? []).includes(option.value) }),
130
+ option.label
131
+ ]
132
+ },
133
+ option.value
134
+ )
135
+ ) : /* @__PURE__ */ jsxs(
136
+ DropdownMenuItem,
137
+ {
138
+ onSelect: () => column.onFilterChange?.(option.value),
139
+ children: [
140
+ /* @__PURE__ */ jsx(CheckGlyph, { visible: column.filterValue === option.value }),
141
+ option.label
142
+ ]
143
+ },
144
+ option.value
145
+ )
146
+ ),
147
+ multi && (column.filterValues?.length ?? 0) > 0 ? /* @__PURE__ */ jsxs(Fragment, { children: [
148
+ /* @__PURE__ */ jsx(DropdownMenuSeparator, {}),
149
+ /* @__PURE__ */ jsxs(DropdownMenuItem, { onSelect: () => column.onFilterValuesChange?.([]), children: [
150
+ /* @__PURE__ */ jsx(CheckGlyph, { visible: false }),
151
+ "Clear"
152
+ ] })
153
+ ] }) : null
121
154
  ] })
122
155
  ] });
123
156
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jackbernnie/hiyf",
3
- "version": "0.3.6",
3
+ "version": "0.3.8",
4
4
  "description": "human-in-your-face — an AI design protocol (a locked, LLM-safe design system). Forked from Polar's Orbit (Apache-2.0).",
5
5
  "license": "Apache-2.0",
6
6
  "type": "module",