@vezham/react 26.0.0-alpha.9 → 26.0.0-beta.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.
Files changed (67) hide show
  1. package/dist/lib/components/command/index.js +2 -2
  2. package/dist/lib/components/menu/index.js +2 -2
  3. package/dist/lib/components/panel/footer/ai/message-actions.js +2 -2
  4. package/dist/lib/components/panel/footer/ai/mock-result.js +2 -2
  5. package/dist/lib/components/panel/footer/control-center/appearance.d.ts +2 -1
  6. package/dist/lib/components/panel/footer/control-center/appearance.d.ts.map +1 -1
  7. package/dist/lib/components/panel/footer/control-center/appearance.js +4 -3
  8. package/dist/lib/components/panel/footer/control-center/control-center.js +11 -8
  9. package/dist/lib/components/panel/footer/control-center/direction.d.ts +2 -1
  10. package/dist/lib/components/panel/footer/control-center/direction.d.ts.map +1 -1
  11. package/dist/lib/components/panel/footer/control-center/direction.js +6 -4
  12. package/dist/lib/components/panel/footer/control-center/editor.d.ts +3 -1
  13. package/dist/lib/components/panel/footer/control-center/editor.d.ts.map +1 -1
  14. package/dist/lib/components/panel/footer/control-center/editor.js +24 -6
  15. package/dist/lib/components/panel/footer/control-center/preview.d.ts +4 -2
  16. package/dist/lib/components/panel/footer/control-center/preview.d.ts.map +1 -1
  17. package/dist/lib/components/panel/footer/control-center/preview.js +4 -2
  18. package/dist/lib/components/panel/footer/control-center/tile.d.ts.map +1 -1
  19. package/dist/lib/components/panel/footer/control-center/tile.js +12 -7
  20. package/dist/lib/components/panel/footer/control-center/variant.d.ts +27 -0
  21. package/dist/lib/components/panel/footer/control-center/variant.d.ts.map +1 -1
  22. package/dist/lib/components/panel/footer/control-center/variant.js +30 -9
  23. package/dist/lib/components/panel/footer/index.js +2 -2
  24. package/dist/lib/components/panel/footer/notification-center/index.js +2 -2
  25. package/dist/lib/components/panel/footer/notification-center/widget-tiles.d.ts +88 -3
  26. package/dist/lib/components/panel/footer/notification-center/widget-tiles.d.ts.map +1 -1
  27. package/dist/lib/components/panel/footer/notification-center/widget-tiles.js +63 -25
  28. package/dist/lib/components/panel/footer/user-menu.d.ts.map +1 -1
  29. package/dist/lib/components/panel/footer/user-menu.js +258 -230
  30. package/dist/lib/components/panel/header/application-menu-sheet.js +5 -5
  31. package/dist/lib/components/panel/header/bookmarks/bookmark-file-tree/index.js +1 -1
  32. package/dist/lib/components/panel/header/bookmarks/bookmark-file-tree/variants.js +1 -1
  33. package/dist/lib/components/panel/header/bookmarks/favorites/grid-list.js +2 -2
  34. package/dist/lib/components/panel/header/bookmarks/index.js +2 -1
  35. package/dist/lib/components/panel/header/bookmarks/shortcut-context-menu.js +2 -1
  36. package/dist/lib/components/panel/header/bookmarks/tree-data.js +2 -1
  37. package/dist/lib/components/panel/header/bookmarks/types.d.ts +0 -5
  38. package/dist/lib/components/panel/header/bookmarks/types.d.ts.map +1 -1
  39. package/dist/lib/components/panel/header/index.js +5 -5
  40. package/dist/lib/components/panel/header/storage/types.d.ts +1 -1
  41. package/dist/lib/components/panel/info-panel/container.module.js +4 -2
  42. package/dist/lib/components/panel/menu/index.js +2 -2
  43. package/dist/lib/components/panel/menu/types.d.ts +2 -11
  44. package/dist/lib/components/panel/menu/types.d.ts.map +1 -1
  45. package/dist/lib/layouts/menu-layout/index-md.js +3 -3
  46. package/dist/lib/layouts/menu-layout/index-sm.js +2 -2
  47. package/dist/lib/layouts/section/index.d.ts.map +1 -1
  48. package/dist/lib/layouts/section/index.js +54 -69
  49. package/dist/lib/layouts/section/sidebar.js +2 -2
  50. package/dist/lib/layouts/section/tab-navigation.d.ts +12 -0
  51. package/dist/lib/layouts/section/tab-navigation.d.ts.map +1 -0
  52. package/dist/lib/layouts/section/tab-navigation.js +32 -0
  53. package/dist/lib/layouts/section/toolbar-more-sheet.js +3 -3
  54. package/dist/lib/layouts/section/toolbar.d.ts +3 -0
  55. package/dist/lib/layouts/section/toolbar.d.ts.map +1 -1
  56. package/dist/lib/layouts/section/toolbar.js +14 -17
  57. package/dist/lib/pages/settings/index.d.ts.map +1 -1
  58. package/dist/lib/pages/settings/index.js +72 -27
  59. package/dist/lib/pages/settings/navigation.d.ts +1 -1
  60. package/dist/lib/pages/settings/navigation.d.ts.map +1 -1
  61. package/dist/lib/pages/settings/settings-content.js +1 -1
  62. package/dist/lib/pages/settings/tile-gallery.d.ts +6 -1
  63. package/dist/lib/pages/settings/tile-gallery.d.ts.map +1 -1
  64. package/dist/lib/pages/settings/tile-gallery.js +175 -100
  65. package/dist/lib/store/useBookmarks/index.js +2 -2
  66. package/dist/lib/store/useStorage/index.js +1 -1
  67. package/package.json +2 -2
@@ -7,12 +7,12 @@ import { TileContent } from "../../components/panel/footer/control-center/contro
7
7
  import { resolveTiles } from "../../components/panel/footer/control-center/configured.js";
8
8
  import { useSidebarShortcut, useWorkspaceNavigation } from "../../components/workspace-navigation/index.js";
9
9
  import { useUser } from "../../store/users/useUserStore.js";
10
- import { WidgetPreview, useWidgetTiles } from "../../components/panel/footer/notification-center/widget-tiles.js";
10
+ import { WidgetPreview, getWidgetSize, useWidgetTiles, widgetSizes } from "../../components/panel/footer/notification-center/widget-tiles.js";
11
11
  import { ShortcutButton } from "../../components/shortcut-key/index.js";
12
12
  import { SettingsContent } from "./settings-content.js";
13
13
  import { TileGallery } from "./tile-gallery.js";
14
14
  import { useNavigate, useSearch } from "@tanstack/react-router";
15
- import { useId, useState } from "react";
15
+ import { useId, useMemo, useState } from "react";
16
16
  import { Avatar, Button, Drawer, SearchField } from "@vezham/react-v3";
17
17
  import { jsx, jsxs } from "react/jsx-runtime";
18
18
  import { AltArrowLeft, Bell, Settings, Sun, UserRounded } from "@vezham/icons-react";
@@ -39,12 +39,12 @@ var sections = [
39
39
  keywords: "profile name email"
40
40
  },
41
41
  {
42
- title: "Edit Widgets",
42
+ title: "Widget Center",
43
43
  icon: Settings,
44
44
  keywords: "notification center tiles"
45
45
  },
46
46
  {
47
- title: "Edit Controls",
47
+ title: "Control Center",
48
48
  icon: Settings,
49
49
  keywords: "control center tiles"
50
50
  }
@@ -75,38 +75,83 @@ var categoryFor = (type) => {
75
75
  if (type === "preview-media" || type === "preview-sound") return "Sound & Media";
76
76
  return "General";
77
77
  };
78
+ var suggestionShapesFor = (type) => {
79
+ if ([
80
+ "appearance-toggle",
81
+ "direction-toggle",
82
+ "preview-focus",
83
+ "preview-stage-manager"
84
+ ].includes(type)) return [
85
+ "compact",
86
+ "wide",
87
+ "full"
88
+ ];
89
+ if ([
90
+ "preview-display",
91
+ "preview-media",
92
+ "preview-sound"
93
+ ].includes(type)) return ["wide", "full"];
94
+ return ["wide", "full"];
95
+ };
78
96
  var SettingsGallery = ({ active, controlCenter, onDone }) => {
79
97
  const widgets = useWidgetTiles();
80
- const controls = useTileEditor(controlCenter ? resolveTiles(controlCenter, () => void 0) : []);
81
- if (active === "Edit Widgets") return /* @__PURE__ */ jsx(TileGallery, {
82
- title: "Edit Widgets",
98
+ const configuredControls = useMemo(() => controlCenter ? resolveTiles(controlCenter, () => void 0) : [], [controlCenter]);
99
+ const controls = useTileEditor(configuredControls);
100
+ const currentControls = new Map(controls.orderedTiles.map((tile) => [tile.id, tile]));
101
+ if (active === "Widget Center") return /* @__PURE__ */ jsx(TileGallery, {
102
+ title: "Widget Center",
83
103
  kind: "widgets",
84
104
  editor: widgets.editor,
85
- tiles: widgets.orderedTiles.map((tile) => ({
86
- ...tile,
87
- shape: tile.size,
88
- category: tile.category,
89
- preview: /* @__PURE__ */ jsx(WidgetPreview, { tile })
90
- })),
105
+ tiles: widgets.orderedTiles.map((tile) => {
106
+ const size = getWidgetSize(tile);
107
+ return {
108
+ ...tile,
109
+ shape: size,
110
+ category: tile.category,
111
+ suggestionGroup: tile.label,
112
+ suggestionShapes: widgetSizes,
113
+ suggestionPreview: (suggestionSize) => /* @__PURE__ */ jsx(WidgetPreview, { tile: {
114
+ ...tile,
115
+ size: suggestionSize,
116
+ span: void 0
117
+ } }),
118
+ preview: /* @__PURE__ */ jsx(WidgetPreview, { tile })
119
+ };
120
+ }),
91
121
  onDone
92
122
  }, "widgets");
93
123
  return /* @__PURE__ */ jsx(AppearanceProvider, { children: /* @__PURE__ */ jsx(PreviewProvider, {
94
124
  enabled: true,
95
125
  children: /* @__PURE__ */ jsx(TileGallery, {
96
- title: "Edit Controls",
126
+ title: "Control Center",
97
127
  kind: "controls",
98
128
  editor: controls.editor,
99
- tiles: controls.orderedTiles.map((tile) => ({
100
- id: tile.id,
101
- label: controls.editor.items.find((item) => item.id === tile.id)?.label ?? tile.id,
102
- shape: tile.span,
103
- category: categoryFor(controlCenter?.tiles.find((item) => item.id === tile.id)?.type ?? ""),
104
- preview: /* @__PURE__ */ jsx(TileContent, {
105
- entry: tile,
106
- context: {},
107
- onOpen: () => void 0
108
- })
109
- })),
129
+ tiles: configuredControls.map((configuredTile) => {
130
+ const tile = currentControls.get(configuredTile.id) ?? configuredTile;
131
+ const type = controlCenter?.tiles.find((item) => item.id === tile.id)?.type ?? "";
132
+ const label = controls.editor.items.find((item) => item.id === tile.id)?.label ?? tile.id;
133
+ return {
134
+ id: tile.id,
135
+ label,
136
+ shape: tile.span,
137
+ suggestionGroup: label,
138
+ suggestionShapes: suggestionShapesFor(type),
139
+ suggestionPreview: (span) => /* @__PURE__ */ jsx(TileContent, {
140
+ entry: {
141
+ ...tile,
142
+ span
143
+ },
144
+ context: {},
145
+ onOpen: () => void 0
146
+ }),
147
+ category: categoryFor(type),
148
+ preview: /* @__PURE__ */ jsx(TileContent, {
149
+ entry: tile,
150
+ context: {},
151
+ onOpen: () => void 0
152
+ })
153
+ };
154
+ }),
110
155
  onDone
111
156
  }, "controls")
112
157
  }) });
@@ -122,7 +167,7 @@ var SettingsPage = ({ onBack, section = "General", onSectionChange, controlCente
122
167
  if (window.matchMedia("(min-width: 768px)").matches) toggleNavigation();
123
168
  else setIsDrawerOpen((open) => !open);
124
169
  };
125
- useSidebarShortcut(toggleSidebar, active !== "Edit Widgets" && active !== "Edit Controls");
170
+ useSidebarShortcut(toggleSidebar, active !== "Widget Center" && active !== "Control Center");
126
171
  const { user } = useUser();
127
172
  const visibleSections = sections.filter((section) => `${section.title} ${section.keywords}`.toLowerCase().includes(query.toLowerCase().trim()));
128
173
  const openSection = (section) => {
@@ -130,7 +175,7 @@ var SettingsPage = ({ onBack, section = "General", onSectionChange, controlCente
130
175
  onSectionChange?.(section);
131
176
  setIsDrawerOpen(false);
132
177
  };
133
- if (active === "Edit Widgets" || active === "Edit Controls") return /* @__PURE__ */ jsx(SettingsGallery, {
178
+ if (active === "Widget Center" || active === "Control Center") return /* @__PURE__ */ jsx(SettingsGallery, {
134
179
  active,
135
180
  controlCenter,
136
181
  onDone: () => openSection("General")
@@ -1,4 +1,4 @@
1
- export type SettingsSection = 'General' | 'Appearance' | 'Notifications' | 'Account' | 'Edit Widgets' | 'Edit Controls';
1
+ export type SettingsSection = 'General' | 'Appearance' | 'Notifications' | 'Account' | 'Widget Center' | 'Control Center';
2
2
  export declare const SettingsNavigationContext: import('react').Context<((section: SettingsSection) => void) | null>;
3
3
  export declare const useSettingsNavigation: () => ((section: SettingsSection) => void) | null;
4
4
  //# sourceMappingURL=navigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/lib/pages/settings/navigation.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,YAAY,GACZ,eAAe,GACf,SAAS,GACT,cAAc,GACd,eAAe,CAAA;AACnB,eAAO,MAAM,yBAAyB,qCACzB,eAAe,KAAK,IAAI,SAC9B,CAAA;AACP,eAAO,MAAM,qBAAqB,mBAFrB,eAAe,KAAK,IAAI,QAE2C,CAAA"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../../../src/lib/pages/settings/navigation.tsx"],"names":[],"mappings":"AAEA,MAAM,MAAM,eAAe,GACvB,SAAS,GACT,YAAY,GACZ,eAAe,GACf,SAAS,GACT,eAAe,GACf,gBAAgB,CAAA;AACpB,eAAO,MAAM,yBAAyB,qCACzB,eAAe,KAAK,IAAI,SAC9B,CAAA;AACP,eAAO,MAAM,qBAAqB,mBAFrB,eAAe,KAAK,IAAI,QAE2C,CAAA"}
@@ -204,7 +204,7 @@ var settingsComponents = {
204
204
  };
205
205
  var SettingsContentView = ({ active }) => {
206
206
  const preferences = useSettingsPreferences();
207
- if (active === "Edit Widgets" || active === "Edit Controls") return null;
207
+ if (active === "Widget Center" || active === "Control Center") return null;
208
208
  const Content = settingsComponents[active];
209
209
  return /* @__PURE__ */ jsx(Content, { ...preferences });
210
210
  };
@@ -1,10 +1,15 @@
1
1
  import { ReactNode } from 'react';
2
2
  import { EditorState } from '../../components/panel/footer/control-center/editor';
3
+ type GalleryShape = 'small' | 'medium' | 'large' | 'compact' | 'standard' | 'wide' | 'full';
3
4
  type GalleryTile = {
4
5
  id: string;
5
6
  label: string;
7
+ description?: string;
6
8
  category: string;
7
- shape: 'small' | 'medium' | 'large' | 'compact' | 'standard' | 'wide' | 'full';
9
+ shape: GalleryShape;
10
+ suggestionGroup?: string;
11
+ suggestionShapes?: readonly GalleryShape[];
12
+ suggestionPreview?: (shape: GalleryShape) => ReactNode;
8
13
  preview?: ReactNode;
9
14
  };
10
15
  type Props = {
@@ -1 +1 @@
1
- {"version":3,"file":"tile-gallery.d.ts","sourceRoot":"","sources":["../../../../src/lib/pages/settings/tile-gallery.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAkB,KAAK,SAAS,EAAmB,MAAM,OAAO,CAAA;AAWvE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAA;AAEtF,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;IAC9E,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB,CAAA;AAED,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,SAAS,GAAG,UAAU,CAAA;IAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AA4YD,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,gCA4FvC,CAAA"}
1
+ {"version":3,"file":"tile-gallery.d.ts","sourceRoot":"","sources":["../../../../src/lib/pages/settings/tile-gallery.tsx"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,SAAS,EAGf,MAAM,OAAO,CAAA;AAWd,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,qDAAqD,CAAA;AAOtF,KAAK,YAAY,GACf,OAAO,GAAG,QAAQ,GAAG,OAAO,GAAG,SAAS,GAAG,UAAU,GAAG,MAAM,GAAG,MAAM,CAAA;AAMzE,KAAK,WAAW,GAAG;IACjB,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,CAAA;IAChB,KAAK,EAAE,YAAY,CAAA;IACnB,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,gBAAgB,CAAC,EAAE,SAAS,YAAY,EAAE,CAAA;IAC1C,iBAAiB,CAAC,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,SAAS,CAAA;IACtD,OAAO,CAAC,EAAE,SAAS,CAAA;CACpB,CAAA;AASD,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,CAAA;IACb,IAAI,EAAE,SAAS,GAAG,UAAU,CAAA;IAC5B,KAAK,EAAE,SAAS,WAAW,EAAE,CAAA;IAC7B,MAAM,EAAE,WAAW,CAAA;IACnB,MAAM,EAAE,MAAM,IAAI,CAAA;CACnB,CAAA;AAigBD,eAAO,MAAM,WAAW,GAAI,OAAO,KAAK,gCA6FvC,CAAA"}
@@ -1,12 +1,17 @@
1
- import { useId, useState } from "react";
1
+ import { controlCenterVariants } from "../../components/panel/footer/control-center/variant.js";
2
+ import { notificationCenterWidgetVariants } from "../../components/panel/footer/notification-center/widget-tiles.js";
3
+ import { Fragment, useId, useState } from "react";
2
4
  import { Button, Drawer, SearchField, Surface, Tooltip } from "@vezham/react-v3";
3
5
  import { jsx, jsxs } from "react/jsx-runtime";
4
6
  import { Add, AltArrowLeft, Minus, Settings, Sidebar } from "@vezham/icons-react";
5
7
  //#region src/lib/pages/settings/tile-gallery.tsx
8
+ var controlCenterStyles = controlCenterVariants();
9
+ var widgetStyles = notificationCenterWidgetVariants();
10
+ var controlSpan = (shape) => shape;
11
+ var widgetSize = (shape) => shape;
6
12
  var useGallery = ({ kind, tiles, editor }) => {
7
13
  const dragInstructionsId = useId();
8
14
  const [draggedId, setDraggedId] = useState(null);
9
- const [draggedHeight, setDraggedHeight] = useState(0);
10
15
  const [dropTarget, setDropTarget] = useState(null);
11
16
  const [announcement, setAnnouncement] = useState("");
12
17
  const [query, setQuery] = useState("");
@@ -18,19 +23,43 @@ var useGallery = ({ kind, tiles, editor }) => {
18
23
  const categories = ["All", ...new Set(tiles.map((tile) => tile.category))];
19
24
  const matchingTiles = tiles.filter((tile) => `${tile.label} ${tile.category}`.toLowerCase().includes(normalizedQuery));
20
25
  const matchingCategories = [...new Set(matchingTiles.map((tile) => tile.category))];
21
- const available = tiles.filter((tile) => `${tile.label} ${tile.category}`.toLowerCase().includes(normalizedQuery) && (category === "All" || tile.category === category));
26
+ const availableTiles = tiles.filter((tile) => `${tile.label} ${tile.category}`.toLowerCase().includes(normalizedQuery) && (category === "All" || tile.category === category));
27
+ const seenSuggestionGroups = /* @__PURE__ */ new Set();
28
+ const available = availableTiles.filter((tile) => {
29
+ const group = tile.suggestionGroup ?? tile.id;
30
+ if (seenSuggestionGroups.has(group)) return false;
31
+ seenSuggestionGroups.add(group);
32
+ return true;
33
+ }).flatMap((tile) => tile.suggestionShapes ? tile.suggestionShapes.map((shape) => ({
34
+ ...tile,
35
+ shape,
36
+ preview: tile.suggestionPreview?.(shape) ?? tile.preview,
37
+ suggestionKey: `${tile.id}:${shape}`
38
+ })) : [{
39
+ ...tile,
40
+ suggestionKey: tile.id
41
+ }]);
42
+ const availableGroups = Array.from(available.reduce((groups, tile) => {
43
+ const group = tile.suggestionGroup ?? tile.id;
44
+ const existing = groups.get(group);
45
+ if (existing) existing.tiles.push(tile);
46
+ else groups.set(group, {
47
+ id: group,
48
+ label: tile.label,
49
+ tiles: [tile]
50
+ });
51
+ return groups;
52
+ }, /* @__PURE__ */ new Map()).values());
22
53
  const visible = editor.items.filter((item) => item.visible).flatMap((item) => tiles.filter((tile) => tile.id === item.id));
23
54
  const itemFor = (id) => editor.items.find((item) => item.id === id);
24
55
  const finishDrag = () => {
25
56
  setDraggedId(null);
26
57
  setDropTarget(null);
27
- setDraggedHeight(0);
28
58
  };
29
- const startDrag = (event, id) => {
59
+ const startDrag = (event, id, span) => {
30
60
  event.dataTransfer.setData("application/x-vx-settings-tile", id);
61
+ if (span) event.dataTransfer.setData("application/x-vx-settings-tile-span", span);
31
62
  event.dataTransfer.effectAllowed = "move";
32
- const currentTile = event.currentTarget;
33
- setDraggedHeight((currentTile.hasAttribute("data-preview-tile") ? currentTile : currentTile.querySelector("[inert]"))?.getBoundingClientRect().height ?? 64);
34
63
  setDraggedId(id);
35
64
  };
36
65
  const moveTile = (id, offset) => {
@@ -49,11 +78,14 @@ var useGallery = ({ kind, tiles, editor }) => {
49
78
  event.preventDefault();
50
79
  event.stopPropagation();
51
80
  const id = event.dataTransfer.getData("application/x-vx-settings-tile");
81
+ const requestedSpan = event.dataTransfer.getData("application/x-vx-settings-tile-span");
52
82
  const item = itemFor(id);
83
+ const span = tiles.find((tile) => tile.id === id)?.suggestionShapes?.includes(requestedSpan) ? requestedSpan : void 0;
53
84
  finishDrag();
54
85
  if (!item?.editable) return;
55
86
  if (editor.onPlace) {
56
- editor.onPlace(id, target);
87
+ if (span) editor.onPlace(id, target, span);
88
+ else editor.onPlace(id, target);
57
89
  return;
58
90
  }
59
91
  if (!item.visible) editor.onVisibilityChange(id, true);
@@ -87,18 +119,17 @@ var useGallery = ({ kind, tiles, editor }) => {
87
119
  className: `w-full justify-start rounded-lg text-sm ${category === value ? "bg-surface-secondary font-semibold" : "text-muted"}`,
88
120
  children: [/* @__PURE__ */ jsx(Settings, { size: 16 }), value === "All" ? `All ${kind}` : value]
89
121
  }, value));
90
- const tileSpan = (tile) => kind === "widgets" ? tile.shape === "large" ? "col-span-2 row-span-2" : tile.shape === "medium" ? "col-span-2" : "" : tile.shape === "compact" ? "" : tile.shape === "standard" ? "col-span-2" : tile.shape === "wide" ? "col-span-3" : "col-span-4";
122
+ const tileSpan = (tile) => kind === "widgets" ? widgetStyles.tile({ size: widgetSize(tile.shape) }) : controlCenterStyles.tileContainer({ span: controlSpan(tile.shape) });
91
123
  const draggedTile = tiles.find((tile) => tile.id === draggedId);
92
124
  const blankWidget = (tile) => /* @__PURE__ */ jsx(Surface, {
93
125
  variant: "transparent",
94
126
  "aria-hidden": "true",
95
- className: `bg-surface-secondary border-border w-full rounded-2xl border ${tile.shape === "large" ? "aspect-square" : tile.shape === "medium" ? "aspect-[2/1]" : "aspect-square"}`,
127
+ className: `bg-surface-secondary border-border w-full rounded-2xl border ${widgetStyles.preview({ size: widgetSize(tile.shape) })}`,
96
128
  children: null
97
129
  });
98
130
  return {
99
131
  dragInstructionsId,
100
132
  draggedId,
101
- draggedHeight,
102
133
  dropTarget,
103
134
  announcement,
104
135
  query,
@@ -107,12 +138,18 @@ var useGallery = ({ kind, tiles, editor }) => {
107
138
  isCategoryMenuOpen,
108
139
  showPreview,
109
140
  available,
141
+ availableGroups,
110
142
  visible,
111
143
  itemFor,
112
144
  finishDrag,
113
145
  startDrag,
114
146
  moveTile,
115
147
  dropTile,
148
+ addTile: (tile) => {
149
+ if (editor.onAdd && tile.suggestionShapes) editor.onAdd(tile.id, tile.shape);
150
+ else if (editor.onPlace && tile.suggestionShapes) editor.onPlace(tile.id, void 0, tile.shape);
151
+ else editor.onVisibilityChange(tile.id, true);
152
+ },
116
153
  search,
117
154
  categoryButtons,
118
155
  tileSpan,
@@ -123,19 +160,9 @@ var useGallery = ({ kind, tiles, editor }) => {
123
160
  setShowPreview
124
161
  };
125
162
  };
126
- var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHeight, dropTarget, itemFor, startDrag, finishDrag, moveTile, dropTile, tileSpan, blankWidget, dragInstructionsId, draggedTile, setDropTarget }) => /* @__PURE__ */ jsxs("aside", {
163
+ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, dropTarget, itemFor, startDrag, finishDrag, moveTile, dropTile, tileSpan, blankWidget, dragInstructionsId, draggedTile, setDropTarget }) => /* @__PURE__ */ jsxs("aside", {
127
164
  "aria-label": `Current ${kind}`,
128
165
  className: `${showPreview ? "flex" : "hidden xl:flex"} border-border min-h-0 min-w-0 flex-1 flex-col p-5 xl:w-96 xl:flex-none xl:border-l`,
129
- onDragOver: (event) => {
130
- if (!event.dataTransfer.types.includes("application/x-vx-settings-tile")) return;
131
- event.preventDefault();
132
- event.dataTransfer.dropEffect = "move";
133
- setDropTarget("empty");
134
- },
135
- onDragLeave: (event) => {
136
- if (!event.currentTarget.contains(event.relatedTarget)) setDropTarget(null);
137
- },
138
- onDrop: (event) => dropTile(event),
139
166
  children: [
140
167
  /* @__PURE__ */ jsxs("div", {
141
168
  className: "mb-4 flex items-center justify-between gap-3",
@@ -148,7 +175,18 @@ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHe
148
175
  })]
149
176
  }),
150
177
  /* @__PURE__ */ jsxs("div", {
151
- className: "@container mx-auto min-h-0 w-full max-w-[352px] flex-1 overflow-y-auto px-2 pt-3 pb-4",
178
+ "data-preview-drop-area": true,
179
+ className: `relative ${kind === "widgets" ? widgetStyles.galleryPreview() : controlCenterStyles.galleryPreview()}`,
180
+ onDragOver: (event) => {
181
+ if (!event.dataTransfer.types.includes("application/x-vx-settings-tile")) return;
182
+ event.preventDefault();
183
+ event.dataTransfer.dropEffect = "move";
184
+ setDropTarget("empty");
185
+ },
186
+ onDragLeave: (event) => {
187
+ if (!event.currentTarget.contains(event.relatedTarget)) setDropTarget(null);
188
+ },
189
+ onDrop: (event) => dropTile(event),
152
190
  children: [visible.length === 0 && /* @__PURE__ */ jsxs("p", {
153
191
  className: "text-muted py-8 text-center text-sm",
154
192
  children: [
@@ -156,11 +194,13 @@ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHe
156
194
  kind,
157
195
  " added. Choose a tile from the gallery."
158
196
  ]
159
- }), /* @__PURE__ */ jsxs("div", {
160
- className: `grid gap-4 ${kind === "widgets" ? "auto-rows-[calc((100cqw-1rem)/2)] grid-cols-2" : "grid-cols-4 items-start"}`,
161
- children: [visible.map((tile) => {
197
+ }), /* @__PURE__ */ jsx("div", {
198
+ className: kind === "widgets" ? widgetStyles.grid() : controlCenterStyles.home(),
199
+ children: visible.map((tile, index) => {
162
200
  const editable = itemFor(tile.id)?.editable;
163
- return /* @__PURE__ */ jsxs("div", {
201
+ const nextTile = visible[index + 1];
202
+ const emptyWidgetSlot = kind === "widgets" && draggedTile !== void 0 && tile.shape === "small" && nextTile?.shape !== "small";
203
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("div", {
164
204
  "data-preview-tile": tile.id,
165
205
  draggable: editable,
166
206
  role: "group",
@@ -180,7 +220,7 @@ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHe
180
220
  onDrop: (event) => dropTile(event, tile.id),
181
221
  "data-dragging": draggedId === tile.id || void 0,
182
222
  "data-drop-target": dropTarget === tile.id || void 0,
183
- className: `group focus-visible:outline-focus data-[drop-target]:bg-accent-soft data-[drop-target]:outline-accent/40 group-focus-within:[&>div>*]:ring-foreground/35 group-hover:[&>div>*]:ring-foreground/35 relative min-w-0 rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-2 data-[dragging]:opacity-40 data-[drop-target]:outline data-[drop-target]:outline-offset-2 [&>div>*]:transition-[box-shadow] group-focus-within:[&>div>*]:ring-1 group-hover:[&>div>*]:ring-1 ${editable ? "cursor-grab active:cursor-grabbing" : ""} ${tileSpan(tile)}`,
223
+ className: `group focus-visible:outline-focus data-[drop-target]:bg-accent-soft data-[drop-target]:outline-accent/40 group-focus-within:[&>div>*]:ring-foreground/35 group-hover:[&>div>*]:ring-foreground/35 relative min-w-0 overflow-visible rounded-2xl focus-visible:outline-2 focus-visible:outline-offset-2 data-[dragging]:opacity-40 data-[drop-target]:outline data-[drop-target]:outline-offset-2 [&>div>*]:transition-[box-shadow] group-focus-within:[&>div>*]:ring-1 group-hover:[&>div>*]:ring-1 ${editable ? "cursor-grab active:cursor-grabbing" : ""} ${tileSpan(tile)}`,
184
224
  children: [
185
225
  /* @__PURE__ */ jsx("div", {
186
226
  inert: true,
@@ -215,24 +255,32 @@ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHe
215
255
  isIconOnly: true,
216
256
  size: "sm",
217
257
  variant: "secondary",
218
- className: "text-muted absolute -top-2 -left-2 z-10 size-6 min-w-0 rounded-full p-0 opacity-0 transition-opacity group-focus-within:opacity-100 group-hover:opacity-100 [@media(hover:none)]:opacity-100",
258
+ className: "border-danger text-danger hover:bg-danger/10! absolute -top-1 -left-1 z-20 size-6! min-w-0 rounded-full border bg-transparent! p-0 opacity-0 shadow-md transition-opacity group-focus-within:opacity-100 group-hover:opacity-100",
219
259
  "aria-label": `Remove ${tile.label}`,
220
260
  onPress: () => editor.onVisibilityChange(tile.id, false),
221
261
  children: /* @__PURE__ */ jsx(Minus, {
222
262
  "aria-hidden": "true",
223
- className: "size-3.5"
263
+ className: "size-3"
224
264
  })
225
265
  }), /* @__PURE__ */ jsxs(Tooltip.Content, { children: ["Remove ", tile.label] })] })
226
266
  ]
227
- }, tile.id);
228
- }), draggedTile && /* @__PURE__ */ jsx("div", {
229
- "data-preview-empty-drop": true,
230
- "aria-label": `Drop ${draggedTile.label} here`,
231
- "data-drop-target": dropTarget === "empty" || void 0,
232
- className: `border-border text-muted data-[drop-target]:border-accent/40 data-[drop-target]:bg-accent-soft flex items-center justify-center rounded-2xl border border-dashed text-xs ${tileSpan(draggedTile)}`,
233
- style: kind === "controls" ? { height: draggedHeight } : void 0,
234
- children: "Drop here"
235
- })]
267
+ }), emptyWidgetSlot && /* @__PURE__ */ jsx("div", {
268
+ "data-preview-empty-slot": tile.id,
269
+ "data-drop-target": dropTarget === `after:${tile.id}` || void 0,
270
+ onDragOver: (event) => {
271
+ if (!event.dataTransfer.types.includes("application/x-vx-settings-tile")) return;
272
+ event.preventDefault();
273
+ event.stopPropagation();
274
+ event.dataTransfer.dropEffect = "move";
275
+ setDropTarget(`after:${tile.id}`);
276
+ },
277
+ onDragLeave: (event) => {
278
+ if (!event.currentTarget.contains(event.relatedTarget)) setDropTarget((current) => current === `after:${tile.id}` ? null : current);
279
+ },
280
+ onDrop: (event) => dropTile(event, nextTile?.id),
281
+ className: "aspect-square"
282
+ })] }, tile.id);
283
+ })
236
284
  })]
237
285
  }),
238
286
  /* @__PURE__ */ jsxs(Button, {
@@ -243,67 +291,94 @@ var GalleryPreview = ({ kind, editor, showPreview, visible, draggedId, draggedHe
243
291
  })
244
292
  ]
245
293
  });
246
- var GalleryAvailable = ({ kind, editor, isSearching, showPreview, category, available, itemFor, startDrag, finishDrag, blankWidget }) => /* @__PURE__ */ jsxs("section", {
247
- "aria-label": `Available ${kind}`,
248
- className: `${showPreview ? "hidden xl:flex" : "flex"} min-h-0 min-w-0 flex-1 flex-col p-4 md:p-6`,
249
- children: [
250
- /* @__PURE__ */ jsx("h2", {
251
- className: "mb-1 text-sm font-semibold",
252
- children: isSearching ? "Search results" : category === "All" ? "Suggestions" : category
253
- }),
254
- /* @__PURE__ */ jsx("p", {
255
- className: "text-muted mb-5 text-xs",
256
- children: "Add or drag a tile into your preview. Changes save automatically."
257
- }),
258
- /* @__PURE__ */ jsxs("div", {
259
- className: "min-h-0 flex-1 overflow-y-auto p-1",
260
- children: [available.length === 0 && /* @__PURE__ */ jsxs("p", {
261
- role: "status",
262
- className: "text-muted py-8 text-sm",
263
- children: [
264
- "No ",
265
- kind,
266
- " found."
267
- ]
268
- }), /* @__PURE__ */ jsx("div", {
269
- className: "grid grid-cols-2 items-start gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5",
270
- children: available.map((tile) => {
271
- const item = itemFor(tile.id);
272
- return /* @__PURE__ */ jsxs("div", {
273
- "data-gallery-tile": tile.id,
274
- draggable: item?.editable,
275
- onDragStart: (event) => startDrag(event, tile.id),
276
- onDragEnd: finishDrag,
277
- className: `group relative min-w-0 ${tile.shape === "medium" || tile.shape === "large" || tile.shape === "full" || tile.shape === "wide" ? "col-span-2" : ""}`,
278
- children: [
279
- /* @__PURE__ */ jsx("div", {
280
- inert: true,
281
- className: "pointer-events-none flex min-h-24 items-center justify-center [&>button]:w-full",
282
- children: kind === "widgets" ? tile.preview ?? blankWidget(tile) : tile.preview
283
- }),
284
- item?.editable && !item.visible && /* @__PURE__ */ jsx(Button, {
285
- isIconOnly: true,
286
- size: "sm",
287
- variant: "ghost",
288
- "aria-label": `Quick add ${tile.label}`,
289
- className: "bg-success hover:bg-success/90 absolute -top-1 -left-1 z-10 size-7 min-w-0 rounded-full p-0 text-white opacity-0 shadow-sm transition-opacity group-focus-within:opacity-100 group-hover:opacity-100",
290
- onPress: () => editor.onVisibilityChange(tile.id, true),
291
- children: /* @__PURE__ */ jsx(Add, {
292
- "aria-hidden": "true",
293
- className: "size-4"
294
- })
295
- }),
296
- /* @__PURE__ */ jsx("p", {
297
- className: "mt-2 min-w-0 truncate text-xs",
298
- children: tile.label
299
- })
300
- ]
301
- }, tile.id);
294
+ var GalleryAvailable = ({ kind, isSearching, showPreview, category, available, availableGroups, itemFor, startDrag, finishDrag, blankWidget, addTile }) => {
295
+ const suggestionTile = (tile) => {
296
+ const item = itemFor(tile.id);
297
+ const isAdded = item?.visible === true;
298
+ const isCompactControl = kind === "controls" && tile.shape === "compact";
299
+ const size = kind === "controls" ? controlCenterStyles.gallerySuggestion({ span: controlSpan(tile.shape) }) : widgetStyles.gallerySuggestion({ size: widgetSize(tile.shape) });
300
+ return /* @__PURE__ */ jsxs("div", {
301
+ "data-gallery-tile": tile.suggestionKey,
302
+ "data-control-span": kind === "controls" ? tile.shape : void 0,
303
+ "data-widget-size": kind === "widgets" ? tile.shape : void 0,
304
+ "data-added": isAdded || void 0,
305
+ draggable: item?.editable,
306
+ onDragStart: (event) => startDrag(event, tile.id, tile.suggestionShapes ? tile.shape : void 0),
307
+ onDragEnd: finishDrag,
308
+ className: `group relative min-w-0 justify-self-center transition-opacity ${kind === "widgets" ? "grid h-full grid-rows-[minmax(0,1fr)_auto] self-stretch" : ""} ${isAdded ? "opacity-50" : ""} ${size}`,
309
+ children: [
310
+ /* @__PURE__ */ jsx("div", {
311
+ inert: true,
312
+ className: `pointer-events-none flex items-center justify-center [&>section]:w-full ${isCompactControl ? "mx-auto size-14 [&>button]:size-14" : "[&>button]:w-full"} ${kind === "widgets" ? "h-full min-h-24 [&>[data-widget-size]]:w-full" : ""}`,
313
+ children: kind === "widgets" ? tile.preview ?? blankWidget(tile) : tile.preview
314
+ }),
315
+ item?.editable && !item.visible && /* @__PURE__ */ jsx(Button, {
316
+ isIconOnly: true,
317
+ size: "sm",
318
+ variant: "ghost",
319
+ "aria-label": `Quick add ${tile.label}${tile.suggestionKey === tile.id ? "" : ` (${tile.shape})`}`,
320
+ className: "bg-success hover:bg-success/90 absolute -top-1 -left-1 z-10 size-6 min-w-0 rounded-full p-0 text-white opacity-0 shadow-sm transition-opacity group-focus-within:opacity-100 group-hover:opacity-100",
321
+ onPress: () => addTile(tile),
322
+ children: /* @__PURE__ */ jsx(Add, {
323
+ "aria-hidden": "true",
324
+ className: "size-3"
325
+ })
326
+ }),
327
+ /* @__PURE__ */ jsxs("div", {
328
+ className: "mt-2 min-w-0 text-center",
329
+ children: [/* @__PURE__ */ jsx("p", {
330
+ className: "truncate text-sm font-medium",
331
+ children: tile.label
332
+ }), kind === "widgets" && tile.description && /* @__PURE__ */ jsx("p", {
333
+ className: "text-muted mt-0.5 line-clamp-2 text-xs",
334
+ children: tile.description
335
+ })]
302
336
  })
303
- })]
304
- })
305
- ]
306
- });
337
+ ]
338
+ }, tile.suggestionKey);
339
+ };
340
+ return /* @__PURE__ */ jsxs("section", {
341
+ "aria-label": `Available ${kind}`,
342
+ className: `${showPreview ? "hidden xl:flex" : "flex"} min-h-0 min-w-0 flex-1 flex-col p-4 md:p-6`,
343
+ children: [
344
+ /* @__PURE__ */ jsx("h2", {
345
+ className: "mb-1 text-sm font-semibold",
346
+ children: isSearching ? "Search results" : category === "All" ? "Suggestions" : category
347
+ }),
348
+ /* @__PURE__ */ jsx("p", {
349
+ className: "text-muted mb-5 text-xs",
350
+ children: "Add or drag a tile into your preview. Changes save automatically."
351
+ }),
352
+ /* @__PURE__ */ jsxs("div", {
353
+ className: "min-h-0 flex-1 overflow-y-auto p-3",
354
+ children: [available.length === 0 && /* @__PURE__ */ jsxs("p", {
355
+ role: "status",
356
+ className: "text-muted py-8 text-sm",
357
+ children: [
358
+ "No ",
359
+ kind,
360
+ " found."
361
+ ]
362
+ }), available.some((tile) => tile.suggestionShapes) ? /* @__PURE__ */ jsx("div", {
363
+ className: "flex flex-col gap-6",
364
+ children: availableGroups.map((group) => /* @__PURE__ */ jsxs("section", {
365
+ "aria-label": `${group.label} sizes`,
366
+ children: [/* @__PURE__ */ jsx("h3", {
367
+ className: "text-sm font-light",
368
+ children: group.label
369
+ }), /* @__PURE__ */ jsx("div", {
370
+ className: `mt-3 grid grid-cols-1 justify-items-center gap-x-8 gap-y-4 min-[600px]:grid-cols-2 min-[820px]:grid-cols-3 ${kind === "widgets" ? "items-stretch" : ""}`,
371
+ children: group.tiles.map(suggestionTile)
372
+ })]
373
+ }, group.id))
374
+ }) : /* @__PURE__ */ jsx("div", {
375
+ className: "grid grid-cols-2 items-start gap-4 sm:grid-cols-3 xl:grid-cols-4 2xl:grid-cols-5",
376
+ children: available.map(suggestionTile)
377
+ })]
378
+ })
379
+ ]
380
+ });
381
+ };
307
382
  var TileGallery = (props) => {
308
383
  const context = {
309
384
  ...props,
@@ -316,7 +391,7 @@ var TileGallery = (props) => {
316
391
  /* @__PURE__ */ jsx("span", {
317
392
  id: dragInstructionsId,
318
393
  className: "sr-only",
319
- children: "Drag the tile to reorder, or focus it and use the arrow keys."
394
+ children: "Drag the tile to reorder or drop it anywhere in the preview. You can also focus it and use the arrow keys."
320
395
  }),
321
396
  /* @__PURE__ */ jsx("span", {
322
397
  role: "status",
@@ -1,4 +1,4 @@
1
- import { bookmarksData } from "./data.js";
1
+ import { bookmarksData, sampleFavorites } from "./data.js";
2
2
  import { Bookmarks } from "./action.js";
3
3
  import { useQuery, useQueryClient } from "@tanstack/react-query";
4
4
  //#region src/lib/store/useBookmarks/index.ts
@@ -26,4 +26,4 @@ var useBookmarks = {
26
26
  actions: useBookmarksActions
27
27
  };
28
28
  //#endregion
29
- export { useBookmarks };
29
+ export { bookmarksData, sampleFavorites, useBookmarks };
@@ -10,4 +10,4 @@ var useStorageList = (rq = {}) => useQuery({
10
10
  });
11
11
  var useStorage = { list: useStorageList };
12
12
  //#endregion
13
- export { useStorage };
13
+ export { storageData, useStorage };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vezham/react",
3
- "version": "26.0.0-alpha.9",
3
+ "version": "26.0.0-beta.2",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+https://github.com/vezham/vx-fe-pkgs.git",
@@ -109,7 +109,7 @@
109
109
  ],
110
110
  "dependencies": {
111
111
  "@tanstack/react-hotkeys": "^0.10.0",
112
- "@vezham/hooks": "26.0.0-alpha.9",
112
+ "@vezham/hooks": "26.0.0-beta.2",
113
113
  "react-aria-components": "1.21.1"
114
114
  }
115
115
  }