@gfazioli/mantine-window 2.0.0 → 3.0.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.
Files changed (32) hide show
  1. package/README.md +4 -0
  2. package/dist/cjs/Window.cjs +145 -106
  3. package/dist/cjs/Window.cjs.map +1 -1
  4. package/dist/cjs/WindowGroup.cjs +37 -18
  5. package/dist/cjs/WindowGroup.cjs.map +1 -1
  6. package/dist/cjs/WindowGroup.context.cjs +6 -2
  7. package/dist/cjs/WindowGroup.context.cjs.map +1 -1
  8. package/dist/cjs/hooks/use-mantine-window.cjs +4 -3
  9. package/dist/cjs/hooks/use-mantine-window.cjs.map +1 -1
  10. package/dist/cjs/hooks/use-window-dimensions.cjs +20 -9
  11. package/dist/cjs/hooks/use-window-dimensions.cjs.map +1 -1
  12. package/dist/cjs/hooks/use-window-drag.cjs.map +1 -1
  13. package/dist/cjs/hooks/use-window-state.cjs.map +1 -1
  14. package/dist/esm/Window.mjs +147 -108
  15. package/dist/esm/Window.mjs.map +1 -1
  16. package/dist/esm/WindowGroup.context.mjs +6 -2
  17. package/dist/esm/WindowGroup.context.mjs.map +1 -1
  18. package/dist/esm/WindowGroup.mjs +38 -19
  19. package/dist/esm/WindowGroup.mjs.map +1 -1
  20. package/dist/esm/hooks/use-mantine-window.mjs +4 -3
  21. package/dist/esm/hooks/use-mantine-window.mjs.map +1 -1
  22. package/dist/esm/hooks/use-window-dimensions.mjs +22 -11
  23. package/dist/esm/hooks/use-window-dimensions.mjs.map +1 -1
  24. package/dist/esm/hooks/use-window-drag.mjs.map +1 -1
  25. package/dist/esm/hooks/use-window-state.mjs.map +1 -1
  26. package/dist/types/Window.d.ts +6 -0
  27. package/dist/types/WindowGroup.context.d.ts +2 -4
  28. package/dist/types/hooks/use-mantine-window.d.ts +1 -1
  29. package/dist/types/hooks/use-window-constraints.d.ts +7 -7
  30. package/dist/types/hooks/use-window-dimensions.d.ts +1 -1
  31. package/dist/types/hooks/use-window-drag.d.ts +1 -1
  32. package/package.json +2 -2
@@ -1,7 +1,7 @@
1
1
  'use client';
2
2
  import React from 'react';
3
- import { IconX, IconPlus, IconMinus } from '@tabler/icons-react';
4
- import { createVarsResolver, getShadow, getRadius, factory, useProps, useStyles, Box, Flex, ActionIcon, Menu, Text, ScrollArea } from '@mantine/core';
3
+ import { IconPlus, IconMinus, IconX } from '@tabler/icons-react';
4
+ import { createVarsResolver, getShadow, getRadius, factory, useProps, useStyles, Box, Menu, ActionIcon, Flex, Text, ScrollArea } from '@mantine/core';
5
5
  import { useMantineWindow } from './hooks/use-mantine-window.mjs';
6
6
  import { useResponsiveValue } from './hooks/use-responsive-value.mjs';
7
7
  import { FillIcon, SnapLeftIcon, SnapRightIcon, SnapTopIcon, SnapBottomIcon, ArrangeColumnsIcon, ArrangeRowsIcon, TileIcon } from './LayoutIcons.mjs';
@@ -18,6 +18,8 @@ const defaultProps = {
18
18
  withCollapseButton: true,
19
19
  collapsable: true,
20
20
  withToolsButton: true,
21
+ withScrollArea: true,
22
+ controlsPosition: "left",
21
23
  persistState: false,
22
24
  withinPortal: true,
23
25
  minWidth: 250,
@@ -48,7 +50,7 @@ const varsResolver = createVarsResolver((_, { radius, shadow }) => {
48
50
  resizeHandleLeft: {}
49
51
  };
50
52
  });
51
- const Window = factory((_props, _) => {
53
+ const Window = factory((_props) => {
52
54
  const props = useProps("Window", defaultProps, _props);
53
55
  const {
54
56
  opened,
@@ -62,6 +64,9 @@ const Window = factory((_props, _) => {
62
64
  collapsable,
63
65
  withCloseButton,
64
66
  withToolsButton,
67
+ withScrollArea,
68
+ controlsPosition,
69
+ controlsOrder: controlsOrderProp,
65
70
  onClose,
66
71
  radius,
67
72
  shadow,
@@ -138,11 +143,11 @@ const Window = factory((_props, _) => {
138
143
  mod: [{ "data-with-border": withBorder, "data-window-draggable": draggableWindow }, mod],
139
144
  onMouseDown: draggableWindow ? handleMouseDownDrag : void 0,
140
145
  onTouchStart: draggableWindow ? handleTouchStartDrag : void 0,
141
- bg: color,
142
146
  role: "dialog",
143
147
  "aria-label": title || props.id || "Window",
144
148
  "data-mantine-window": true,
145
149
  ...others,
150
+ bg: color,
146
151
  ...getStyles("root", {
147
152
  style: {
148
153
  position: resolvedWithinPortal ? "fixed" : "absolute",
@@ -159,114 +164,137 @@ const Window = factory((_props, _) => {
159
164
  {
160
165
  ...getStyles("header"),
161
166
  onClick: bringToFront,
162
- mod: { "window-draggable": draggableHeader },
167
+ mod: { "window-draggable": draggableHeader, "controls-position": controlsPosition },
163
168
  onMouseDown: draggableHeader ? handleMouseDownDrag : void 0,
164
169
  onTouchStart: draggableHeader ? handleTouchStartDrag : void 0,
165
170
  onDoubleClick: () => collapsable && setIsCollapsed(!isCollapsed)
166
171
  },
167
- /* @__PURE__ */ React.createElement(Flex, { align: "center", gap: "xs", miw: 0 }, /* @__PURE__ */ React.createElement(Flex, { align: "center", gap: 8 }, withCloseButton && /* @__PURE__ */ React.createElement(
168
- ActionIcon,
169
- {
170
- radius: 256,
171
- color: "red",
172
- onClick: handleClose,
173
- "aria-label": "Close window",
174
- ...getStyles("closeButton")
175
- },
176
- /* @__PURE__ */ React.createElement(IconX, { size: 14 })
177
- ), withCollapseButton && collapsable && /* @__PURE__ */ React.createElement(
178
- ActionIcon,
179
- {
180
- radius: 256,
181
- color: "yellow",
182
- onClick: () => setIsCollapsed(!isCollapsed),
183
- "aria-label": isCollapsed ? "Expand window" : "Collapse window",
184
- ...getStyles("collapseButton")
185
- },
186
- isCollapsed ? /* @__PURE__ */ React.createElement(IconPlus, { size: 14 }) : /* @__PURE__ */ React.createElement(IconMinus, { size: 14 })
187
- ), withToolsButton && (groupCtx?.showToolsButton ?? true) && /* @__PURE__ */ React.createElement(Menu, { shadow: "md", width: 220, position: "bottom-start", withArrow: true }, /* @__PURE__ */ React.createElement(Menu.Target, null, /* @__PURE__ */ React.createElement(
188
- ActionIcon,
189
- {
190
- radius: 256,
191
- color: "green",
192
- "aria-label": "Window layout options",
193
- ...getStyles("windowToolsButton")
194
- },
195
- /* @__PURE__ */ React.createElement(FillIcon, { size: 14 })
196
- )), /* @__PURE__ */ React.createElement(Menu.Dropdown, null, /* @__PURE__ */ React.createElement(Menu.Label, null, "Move & Resize"), /* @__PURE__ */ React.createElement(Flex, { justify: "space-between", pb: "xs", px: "sm" }, /* @__PURE__ */ React.createElement(
197
- ActionIcon,
198
- {
199
- variant: "subtle",
200
- size: "lg",
201
- "aria-label": "Snap left",
202
- onClick: () => applySingleLayout("snap-left")
203
- },
204
- /* @__PURE__ */ React.createElement(SnapLeftIcon, null)
205
- ), /* @__PURE__ */ React.createElement(
206
- ActionIcon,
207
- {
208
- variant: "subtle",
209
- size: "lg",
210
- "aria-label": "Snap right",
211
- onClick: () => applySingleLayout("snap-right")
212
- },
213
- /* @__PURE__ */ React.createElement(SnapRightIcon, null)
214
- ), /* @__PURE__ */ React.createElement(
215
- ActionIcon,
216
- {
217
- variant: "subtle",
218
- size: "lg",
219
- "aria-label": "Snap top",
220
- onClick: () => applySingleLayout("snap-top")
221
- },
222
- /* @__PURE__ */ React.createElement(SnapTopIcon, null)
223
- ), /* @__PURE__ */ React.createElement(
224
- ActionIcon,
225
- {
226
- variant: "subtle",
227
- size: "lg",
228
- "aria-label": "Snap bottom",
229
- onClick: () => applySingleLayout("snap-bottom")
230
- },
231
- /* @__PURE__ */ React.createElement(SnapBottomIcon, null)
232
- )), /* @__PURE__ */ React.createElement(Menu.Divider, null), /* @__PURE__ */ React.createElement(Menu.Label, null, "Fill & Arrange"), /* @__PURE__ */ React.createElement(Flex, { justify: "space-between", pb: "xs", px: "sm" }, /* @__PURE__ */ React.createElement(
233
- ActionIcon,
234
- {
235
- variant: "subtle",
236
- size: "lg",
237
- "aria-label": "Fill",
238
- onClick: () => applySingleLayout("fill")
239
- },
240
- /* @__PURE__ */ React.createElement(FillIcon, null)
241
- ), groupCtx && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
242
- ActionIcon,
243
- {
244
- variant: "subtle",
245
- size: "lg",
246
- "aria-label": "Arrange columns",
247
- onClick: () => groupCtx.applyLayout("arrange-columns")
248
- },
249
- /* @__PURE__ */ React.createElement(ArrangeColumnsIcon, null)
250
- ), /* @__PURE__ */ React.createElement(
251
- ActionIcon,
252
- {
253
- variant: "subtle",
254
- size: "lg",
255
- "aria-label": "Arrange rows",
256
- onClick: () => groupCtx.applyLayout("arrange-rows")
257
- },
258
- /* @__PURE__ */ React.createElement(ArrangeRowsIcon, null)
259
- ), /* @__PURE__ */ React.createElement(
260
- ActionIcon,
261
- {
262
- variant: "subtle",
263
- size: "lg",
264
- "aria-label": "Tile",
265
- onClick: () => groupCtx.applyLayout("tile")
266
- },
267
- /* @__PURE__ */ React.createElement(TileIcon, null)
268
- ))), groupCtx && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Menu.Divider, null), /* @__PURE__ */ React.createElement(Menu.Item, { onClick: () => groupCtx.collapseAll() }, "Collapse all"), /* @__PURE__ */ React.createElement(Menu.Item, { onClick: () => groupCtx.expandAll() }, "Expand all"), /* @__PURE__ */ React.createElement(Menu.Item, { color: "red", onClick: () => groupCtx.closeAll() }, "Close all"))))), /* @__PURE__ */ React.createElement(Flex, { align: "center", gap: "xs", miw: 0 }, /* @__PURE__ */ React.createElement(Text, { truncate: true, ...getStyles("title") }, title)))
269
- ), !isCollapsed && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
172
+ (() => {
173
+ const defaultOrder = controlsPosition === "right" ? ["tools", "collapse", "close"] : ["close", "collapse", "tools"];
174
+ const order = controlsOrderProp ?? defaultOrder;
175
+ const controlElements = {
176
+ close: withCloseButton ? /* @__PURE__ */ React.createElement(
177
+ ActionIcon,
178
+ {
179
+ key: "close",
180
+ radius: 256,
181
+ color: "red",
182
+ onClick: handleClose,
183
+ "aria-label": "Close window",
184
+ ...getStyles("closeButton")
185
+ },
186
+ /* @__PURE__ */ React.createElement(IconX, { size: 14 })
187
+ ) : null,
188
+ collapse: withCollapseButton && collapsable ? /* @__PURE__ */ React.createElement(
189
+ ActionIcon,
190
+ {
191
+ key: "collapse",
192
+ radius: 256,
193
+ color: "yellow",
194
+ onClick: () => setIsCollapsed(!isCollapsed),
195
+ "aria-label": isCollapsed ? "Expand window" : "Collapse window",
196
+ ...getStyles("collapseButton")
197
+ },
198
+ isCollapsed ? /* @__PURE__ */ React.createElement(IconPlus, { size: 14 }) : /* @__PURE__ */ React.createElement(IconMinus, { size: 14 })
199
+ ) : null,
200
+ tools: withToolsButton && (groupCtx?.showToolsButton ?? true) ? /* @__PURE__ */ React.createElement(Menu, { key: "tools", shadow: "md", width: 220, position: "bottom-start", withArrow: true }, /* @__PURE__ */ React.createElement(Menu.Target, null, /* @__PURE__ */ React.createElement(
201
+ ActionIcon,
202
+ {
203
+ radius: 256,
204
+ color: "green",
205
+ "aria-label": "Window layout options",
206
+ ...getStyles("windowToolsButton")
207
+ },
208
+ /* @__PURE__ */ React.createElement(FillIcon, { size: 14 })
209
+ )), /* @__PURE__ */ React.createElement(Menu.Dropdown, null, /* @__PURE__ */ React.createElement(Menu.Label, null, "Move & Resize"), /* @__PURE__ */ React.createElement(Flex, { justify: "space-between", pb: "xs", px: "sm" }, /* @__PURE__ */ React.createElement(
210
+ ActionIcon,
211
+ {
212
+ variant: "subtle",
213
+ size: "lg",
214
+ "aria-label": "Snap left",
215
+ onClick: () => applySingleLayout("snap-left")
216
+ },
217
+ /* @__PURE__ */ React.createElement(SnapLeftIcon, null)
218
+ ), /* @__PURE__ */ React.createElement(
219
+ ActionIcon,
220
+ {
221
+ variant: "subtle",
222
+ size: "lg",
223
+ "aria-label": "Snap right",
224
+ onClick: () => applySingleLayout("snap-right")
225
+ },
226
+ /* @__PURE__ */ React.createElement(SnapRightIcon, null)
227
+ ), /* @__PURE__ */ React.createElement(
228
+ ActionIcon,
229
+ {
230
+ variant: "subtle",
231
+ size: "lg",
232
+ "aria-label": "Snap top",
233
+ onClick: () => applySingleLayout("snap-top")
234
+ },
235
+ /* @__PURE__ */ React.createElement(SnapTopIcon, null)
236
+ ), /* @__PURE__ */ React.createElement(
237
+ ActionIcon,
238
+ {
239
+ variant: "subtle",
240
+ size: "lg",
241
+ "aria-label": "Snap bottom",
242
+ onClick: () => applySingleLayout("snap-bottom")
243
+ },
244
+ /* @__PURE__ */ React.createElement(SnapBottomIcon, null)
245
+ )), /* @__PURE__ */ React.createElement(Menu.Divider, null), /* @__PURE__ */ React.createElement(Menu.Label, null, "Fill & Arrange"), /* @__PURE__ */ React.createElement(Flex, { justify: "space-between", pb: "xs", px: "sm" }, /* @__PURE__ */ React.createElement(
246
+ ActionIcon,
247
+ {
248
+ variant: "subtle",
249
+ size: "lg",
250
+ "aria-label": "Fill",
251
+ onClick: () => applySingleLayout("fill")
252
+ },
253
+ /* @__PURE__ */ React.createElement(FillIcon, null)
254
+ ), groupCtx && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
255
+ ActionIcon,
256
+ {
257
+ variant: "subtle",
258
+ size: "lg",
259
+ "aria-label": "Arrange columns",
260
+ onClick: () => groupCtx.applyLayout("arrange-columns")
261
+ },
262
+ /* @__PURE__ */ React.createElement(ArrangeColumnsIcon, null)
263
+ ), /* @__PURE__ */ React.createElement(
264
+ ActionIcon,
265
+ {
266
+ variant: "subtle",
267
+ size: "lg",
268
+ "aria-label": "Arrange rows",
269
+ onClick: () => groupCtx.applyLayout("arrange-rows")
270
+ },
271
+ /* @__PURE__ */ React.createElement(ArrangeRowsIcon, null)
272
+ ), /* @__PURE__ */ React.createElement(
273
+ ActionIcon,
274
+ {
275
+ variant: "subtle",
276
+ size: "lg",
277
+ "aria-label": "Tile",
278
+ onClick: () => groupCtx.applyLayout("tile")
279
+ },
280
+ /* @__PURE__ */ React.createElement(TileIcon, null)
281
+ ))), groupCtx && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Menu.Divider, null), /* @__PURE__ */ React.createElement(Menu.Item, { onClick: () => groupCtx.collapseAll() }, "Collapse all"), /* @__PURE__ */ React.createElement(Menu.Item, { onClick: () => groupCtx.expandAll() }, "Expand all"), /* @__PURE__ */ React.createElement(Menu.Item, { color: "red", onClick: () => groupCtx.closeAll() }, "Close all")))) : null
282
+ };
283
+ const controlsGroup = /* @__PURE__ */ React.createElement(Flex, { align: "center", gap: 8 }, order.map((name) => controlElements[name]));
284
+ const titleGroup = /* @__PURE__ */ React.createElement(Flex, { align: "center", gap: "xs", miw: 0 }, /* @__PURE__ */ React.createElement(Text, { truncate: true, ...getStyles("title") }, title));
285
+ return /* @__PURE__ */ React.createElement(
286
+ Flex,
287
+ {
288
+ align: "center",
289
+ gap: "xs",
290
+ miw: 0,
291
+ justify: controlsPosition === "right" ? "space-between" : void 0,
292
+ w: controlsPosition === "right" ? "100%" : void 0
293
+ },
294
+ controlsPosition === "left" ? /* @__PURE__ */ React.createElement(React.Fragment, null, controlsGroup, titleGroup) : /* @__PURE__ */ React.createElement(React.Fragment, null, titleGroup, controlsGroup)
295
+ );
296
+ })()
297
+ ), !isCollapsed && /* @__PURE__ */ React.createElement(React.Fragment, null, withScrollArea ? /* @__PURE__ */ React.createElement(
270
298
  ScrollArea,
271
299
  {
272
300
  ...getStyles("content", {
@@ -276,6 +304,17 @@ const Window = factory((_props, _) => {
276
304
  })
277
305
  },
278
306
  children
307
+ ) : /* @__PURE__ */ React.createElement(
308
+ Box,
309
+ {
310
+ ...getStyles("content", {
311
+ style: {
312
+ height: Math.max(0, size.height - HEADER_HEIGHT),
313
+ overflow: "hidden"
314
+ }
315
+ })
316
+ },
317
+ children
279
318
  ), resizable !== "none" && /* @__PURE__ */ React.createElement(React.Fragment, null, resizable === "both" && /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(
280
319
  Box,
281
320
  {