@ngrok/mantle 0.32.3 → 0.40.1

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 (85) hide show
  1. package/dist/accordion.d.ts +72 -61
  2. package/dist/accordion.js +1 -1
  3. package/dist/accordion.js.map +1 -1
  4. package/dist/alert-dialog.d.ts +311 -462
  5. package/dist/alert-dialog.js +1 -1
  6. package/dist/alert-dialog.js.map +1 -1
  7. package/dist/alert.d.ts +113 -92
  8. package/dist/alert.js +1 -1
  9. package/dist/alert.js.map +1 -1
  10. package/dist/card.d.ts +112 -112
  11. package/dist/card.js +1 -1
  12. package/dist/card.js.map +1 -1
  13. package/dist/{chunk-IVXZIYX4.js → chunk-2ID2TLYD.js} +1 -1
  14. package/dist/chunk-2ID2TLYD.js.map +1 -0
  15. package/dist/{chunk-3X4AKTRA.js → chunk-4GGDPFNZ.js} +2 -2
  16. package/dist/chunk-4GGDPFNZ.js.map +1 -0
  17. package/dist/{chunk-ERBZR6SY.js → chunk-EYZYDUS2.js} +1 -1
  18. package/dist/chunk-EYZYDUS2.js.map +1 -0
  19. package/dist/chunk-F4N3P7B7.js +2 -0
  20. package/dist/chunk-F4N3P7B7.js.map +1 -0
  21. package/dist/{chunk-CGUSOD4E.js → chunk-HSTG2BTX.js} +1 -1
  22. package/dist/chunk-HSTG2BTX.js.map +1 -0
  23. package/dist/chunk-UUXOG7WW.js +2 -0
  24. package/dist/chunk-UUXOG7WW.js.map +1 -0
  25. package/dist/code-block.d.ts +188 -178
  26. package/dist/code-block.js +3 -3
  27. package/dist/code-block.js.map +1 -1
  28. package/dist/combobox.d.ts +178 -141
  29. package/dist/combobox.js +1 -1
  30. package/dist/combobox.js.map +1 -1
  31. package/dist/data-table.d.ts +191 -30
  32. package/dist/data-table.js +1 -1
  33. package/dist/data-table.js.map +1 -1
  34. package/dist/dialog.d.ts +374 -264
  35. package/dist/dialog.js +1 -1
  36. package/dist/dialog.js.map +1 -1
  37. package/dist/dropdown-menu.d.ts +304 -102
  38. package/dist/dropdown-menu.js +1 -1
  39. package/dist/dropdown-menu.js.map +1 -1
  40. package/dist/hover-card.d.ts +94 -58
  41. package/dist/hover-card.js +1 -1
  42. package/dist/hover-card.js.map +1 -1
  43. package/dist/icons.js +1 -1
  44. package/dist/input.d.ts +11 -0
  45. package/dist/input.js +1 -1
  46. package/dist/media-object.d.ts +75 -46
  47. package/dist/media-object.js +1 -1
  48. package/dist/media-object.js.map +1 -1
  49. package/dist/pagination.d.ts +124 -62
  50. package/dist/pagination.js +1 -1
  51. package/dist/pagination.js.map +1 -1
  52. package/dist/popover.d.ts +124 -102
  53. package/dist/popover.js +1 -1
  54. package/dist/popover.js.map +1 -1
  55. package/dist/progress.d.ts +112 -35
  56. package/dist/progress.js +1 -1
  57. package/dist/progress.js.map +1 -1
  58. package/dist/radio-group.d.ts +234 -105
  59. package/dist/radio-group.js +1 -1
  60. package/dist/radio-group.js.map +1 -1
  61. package/dist/select.d.ts +242 -212
  62. package/dist/select.js +1 -1
  63. package/dist/sheet.d.ts +343 -575
  64. package/dist/sheet.js +1 -1
  65. package/dist/sheet.js.map +1 -1
  66. package/dist/table.d.ts +384 -425
  67. package/dist/table.js +1 -1
  68. package/dist/tabs.d.ts +105 -95
  69. package/dist/tabs.js +1 -1
  70. package/dist/tabs.js.map +1 -1
  71. package/dist/theme-provider.js +1 -1
  72. package/dist/toast.d.ts +77 -61
  73. package/dist/toast.js +1 -1
  74. package/dist/tooltip.d.ts +72 -49
  75. package/dist/tooltip.js +1 -1
  76. package/dist/tooltip.js.map +1 -1
  77. package/package.json +4 -5
  78. package/dist/chunk-3X4AKTRA.js.map +0 -1
  79. package/dist/chunk-CGUSOD4E.js.map +0 -1
  80. package/dist/chunk-ERBZR6SY.js.map +0 -1
  81. package/dist/chunk-IDCDPWR4.js +0 -2
  82. package/dist/chunk-IDCDPWR4.js.map +0 -1
  83. package/dist/chunk-IVXZIYX4.js.map +0 -1
  84. package/dist/chunk-JIRNFNH5.js +0 -2
  85. package/dist/chunk-JIRNFNH5.js.map +0 -1
@@ -1,9 +1,9 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
1
  import * as react from 'react';
3
2
  import { ComponentProps } from 'react';
3
+ import * as react_jsx_runtime from 'react/jsx-runtime';
4
4
  import { W as WithAsChild } from './as-child-DJ7x3JFV.js';
5
5
  import { B as ButtonGroup } from './button-group-7oT-O90J.js';
6
- import { SelectTrigger } from './select.js';
6
+ import { Select } from './select.js';
7
7
  import 'class-variance-authority/types';
8
8
  import './variant-props-oDo2u-We.js';
9
9
  import 'class-variance-authority';
@@ -17,31 +17,6 @@ type CursorPaginationProps = ComponentProps<"div"> & {
17
17
  */
18
18
  defaultPageSize: number;
19
19
  };
20
- /**
21
- * A pagination component for use with cursor-based pagination.
22
- *
23
- * Cursor-based pagination is a way of loading data in chunks by using a cursor
24
- * from the last item on the current page to know where to start the next set,
25
- * making sure nothing is missed or repeated. Like a linked list, but for chunks
26
- * of data. It doesn't let you jump to a specific page or know how many total pages
27
- * there are, but it's more efficient for large or real-time data sets.
28
- *
29
- * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-pagination
30
- *
31
- * @example
32
- * ```tsx
33
- * <CursorPagination defaultPageSize={10}>
34
- * <CursorButtons
35
- * hasNextPage={hasNext}
36
- * hasPreviousPage={hasPrevious}
37
- * onNextPage={handleNext}
38
- * onPreviousPage={handlePrevious}
39
- * />
40
- * <CursorPageSizeSelect />
41
- * </CursorPagination>
42
- * ```
43
- */
44
- declare const CursorPagination: react.ForwardRefExoticComponent<Omit<CursorPaginationProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
45
20
  type CursorButtonsProps = Omit<ComponentProps<typeof ButtonGroup>, "appearance"> & {
46
21
  /**
47
22
  * Whether there is a next page of data to load.
@@ -60,24 +35,8 @@ type CursorButtonsProps = Omit<ComponentProps<typeof ButtonGroup>, "appearance">
60
35
  */
61
36
  onPreviousPage?: () => void;
62
37
  };
63
- /**
64
- * A pair of buttons for navigating between pages of data when using cursor-based pagination.
65
- *
66
- * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-buttons
67
- *
68
- * @example
69
- * ```tsx
70
- * <CursorButtons
71
- * hasNextPage={hasNext}
72
- * hasPreviousPage={hasPrevious}
73
- * onNextPage={() => loadNextPage()}
74
- * onPreviousPage={() => loadPreviousPage()}
75
- * />
76
- * ```
77
- */
78
- declare const CursorButtons: react.ForwardRefExoticComponent<Omit<CursorButtonsProps, "ref"> & react.RefAttributes<HTMLFieldSetElement>>;
79
38
  declare const defaultPageSizes: readonly [5, 10, 20, 50, 100];
80
- type CursorPageSizeSelectProps = Omit<ComponentProps<typeof SelectTrigger>, "children"> & {
39
+ type CursorPageSizeSelectProps = Omit<ComponentProps<typeof Select.Trigger>, "children"> & {
81
40
  /**
82
41
  * A list of page sizes to choose from. The default page size must be included in this list.
83
42
  */
@@ -87,20 +46,6 @@ type CursorPageSizeSelectProps = Omit<ComponentProps<typeof SelectTrigger>, "chi
87
46
  */
88
47
  onChangePageSize?: (value: number) => void;
89
48
  };
90
- /**
91
- * A select input for changing the number of items per page when using cursor-based pagination.
92
- *
93
- * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-select
94
- *
95
- * @example
96
- * ```tsx
97
- * <CursorPageSizeSelect
98
- * pageSizes={[10, 20, 50, 100]}
99
- * onChangePageSize={(size) => console.log('Page size changed to:', size)}
100
- * />
101
- * ```
102
- */
103
- declare const CursorPageSizeSelect: react.ForwardRefExoticComponent<Omit<CursorPageSizeSelectProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
104
49
  type CursorPageSizeValueProps = Omit<ComponentProps<"span">, "children"> & WithAsChild;
105
50
  /**
106
51
  * Displays the current page size when using cursor-based pagination as a read-only value.
@@ -111,14 +56,103 @@ type CursorPageSizeValueProps = Omit<ComponentProps<"span">, "children"> & WithA
111
56
  * ```tsx
112
57
  * <div className="flex items-center gap-2">
113
58
  * <span>Items per page:</span>
114
- * <CursorPageSizeValue />
59
+ * <CursorPagination.PageSizeValue />
115
60
  * </div>
116
61
  * ```
117
62
  */
118
- declare function CursorPageSizeValue({ asChild, className, ...props }: CursorPageSizeValueProps): react_jsx_runtime.JSX.Element;
119
- declare namespace CursorPageSizeValue {
63
+ declare function PageSizeValue({ asChild, className, ...props }: CursorPageSizeValueProps): react_jsx_runtime.JSX.Element;
64
+ declare namespace PageSizeValue {
120
65
  var displayName: string;
121
66
  }
67
+ /**
68
+ * A pagination component for use with cursor-based pagination.
69
+ *
70
+ * Cursor-based pagination is a way of loading data in chunks by using a cursor
71
+ * from the last item on the current page to know where to start the next set,
72
+ * making sure nothing is missed or repeated. Like a linked list, but for chunks
73
+ * of data. It doesn't let you jump to a specific page or know how many total pages
74
+ * there are, but it's more efficient for large or real-time data sets.
75
+ *
76
+ * @see https://mantle.ngrok.com/components/cursor-pagination
77
+ *
78
+ * @example
79
+ * ```tsx
80
+ * <CursorPagination defaultPageSize={10}>
81
+ * <CursorPagination.Buttons
82
+ * hasNextPage={hasNext}
83
+ * hasPreviousPage={hasPrevious}
84
+ * onNextPage={handleNext}
85
+ * onPreviousPage={handlePrevious}
86
+ * />
87
+ * <CursorPagination.PageSizeSelect />
88
+ * </CursorPagination>
89
+ * ```
90
+ */
91
+ declare const CursorPagination: {
92
+ /**
93
+ * The root container of the cursor pagination component.
94
+ *
95
+ * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-pagination
96
+ *
97
+ * @example
98
+ * ```tsx
99
+ * <CursorPagination.Root defaultPageSize={10}>
100
+ * <CursorPagination.Buttons
101
+ * hasNextPage={hasNext}
102
+ * hasPreviousPage={hasPrevious}
103
+ * onNextPage={handleNext}
104
+ * onPreviousPage={handlePrevious}
105
+ * />
106
+ * <CursorPagination.PageSizeSelect />
107
+ * </CursorPagination.Root>
108
+ * ```
109
+ */
110
+ readonly Root: react.ForwardRefExoticComponent<Omit<CursorPaginationProps, "ref"> & react.RefAttributes<HTMLDivElement>>;
111
+ /**
112
+ * A pair of buttons for navigating between pages of data when using cursor-based pagination.
113
+ *
114
+ * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-buttons
115
+ *
116
+ * @example
117
+ * ```tsx
118
+ * <CursorPagination.Buttons
119
+ * hasNextPage={hasNext}
120
+ * hasPreviousPage={hasPrevious}
121
+ * onNextPage={() => loadNextPage()}
122
+ * onPreviousPage={() => loadPreviousPage()}
123
+ * />
124
+ * ```
125
+ */
126
+ readonly Buttons: react.ForwardRefExoticComponent<Omit<CursorButtonsProps, "ref"> & react.RefAttributes<HTMLFieldSetElement>>;
127
+ /**
128
+ * A select input for changing the number of items per page when using cursor-based pagination.
129
+ *
130
+ * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-select
131
+ *
132
+ * @example
133
+ * ```tsx
134
+ * <CursorPagination.PageSizeSelect
135
+ * pageSizes={[10, 20, 50, 100]}
136
+ * onChangePageSize={(size) => console.log('Page size changed to:', size)}
137
+ * />
138
+ * ```
139
+ */
140
+ readonly PageSizeSelect: react.ForwardRefExoticComponent<Omit<CursorPageSizeSelectProps, "ref"> & react.RefAttributes<HTMLButtonElement>>;
141
+ /**
142
+ * Displays the current page size when using cursor-based pagination as a read-only value.
143
+ *
144
+ * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-value
145
+ *
146
+ * @example
147
+ * ```tsx
148
+ * <div className="flex items-center gap-2">
149
+ * <span>Items per page:</span>
150
+ * <CursorPagination.PageSizeValue />
151
+ * </div>
152
+ * ```
153
+ */
154
+ readonly PageSizeValue: typeof PageSizeValue;
155
+ };
122
156
 
123
157
  type UseOffsetPaginationProps = {
124
158
  /**
@@ -182,11 +216,39 @@ type OffsetPaginationState = {
182
216
  };
183
217
  /**
184
218
  * A headless hook for managing offset-based pagination state
219
+ *
220
+ * @example
221
+ * ```tsx
222
+ * const pagination = useOffsetPagination({
223
+ * listSize: 150,
224
+ * pageSize: 10
225
+ * });
226
+ *
227
+ * return (
228
+ * <div>
229
+ * <p>Page {pagination.currentPage} of {pagination.totalPages}</p>
230
+ * <button onClick={pagination.previousPage} disabled={!pagination.hasPreviousPage}>
231
+ * Previous
232
+ * </button>
233
+ * <button onClick={pagination.nextPage} disabled={!pagination.hasNextPage}>
234
+ * Next
235
+ * </button>
236
+ * </div>
237
+ * );
238
+ * ```
185
239
  */
186
240
  declare function useOffsetPagination({ listSize, pageSize, }: UseOffsetPaginationProps): OffsetPaginationState;
187
241
  /**
188
242
  * Get a paginated slice of a list based on the current offset pagination state.
243
+ *
244
+ * @example
245
+ * ```tsx
246
+ * const data = ['a', 'b', 'c', 'd', 'e', 'f'];
247
+ * const pagination = useOffsetPagination({ listSize: data.length, pageSize: 2 });
248
+ * const currentPageData = getOffsetPaginatedSlice(data, pagination);
249
+ * // Returns: ['a', 'b'] for page 1, ['c', 'd'] for page 2, etc.
250
+ * ```
189
251
  */
190
252
  declare function getOffsetPaginatedSlice<T>(list: readonly T[], pagination: OffsetPaginationState): T[];
191
253
 
192
- export { CursorButtons, type CursorButtonsProps, CursorPageSizeSelect, type CursorPageSizeSelectProps, CursorPageSizeValue, type CursorPageSizeValueProps, CursorPagination, type CursorPaginationProps, type OffsetPaginationState, type UseOffsetPaginationProps, getOffsetPaginatedSlice, useOffsetPagination };
254
+ export { type CursorButtonsProps, type CursorPageSizeSelectProps, type CursorPageSizeValueProps, CursorPagination, type CursorPaginationProps, type OffsetPaginationState, type UseOffsetPaginationProps, getOffsetPaginatedSlice, useOffsetPagination };
@@ -1,2 +1,2 @@
1
- import{a as b,c as v,d as y,e as x,g as h}from"./chunk-3X4AKTRA.js";import"./chunk-MF2QITTY.js";import{b as z}from"./chunk-J6ZF5J72.js";import{a as d}from"./chunk-3H3EUKI7.js";import{a as f}from"./chunk-RTXWW6ND.js";import"./chunk-PANPBV3Q.js";import"./chunk-4LSFAAZW.js";import"./chunk-72TJUKMV.js";import"./chunk-3C5O3AQA.js";import"./chunk-I6T6YV2L.js";import"./chunk-NPTDRQT5.js";import{a as p}from"./chunk-AZ56JGNY.js";import{CaretLeftIcon as A}from"@phosphor-icons/react/CaretLeft";import{CaretRightIcon as E}from"@phosphor-icons/react/CaretRight";import{Slot as F}from"@radix-ui/react-slot";import{createContext as W,forwardRef as c,useContext as N,useState as $}from"react";import P from"tiny-invariant";import{jsx as s,jsxs as l}from"react/jsx-runtime";var m=W(void 0),O=c(({className:n,children:e,defaultPageSize:a,...t},i)=>{let[o,r]=$(a);return s(m.Provider,{value:{defaultPageSize:a,pageSize:o,setPageSize:r},children:s("div",{className:p("inline-flex items-center justify-between gap-2",n),ref:i,...t,children:e})})});O.displayName="CursorPagination";var T=c(({hasNextPage:n,hasPreviousPage:e,onNextPage:a,onPreviousPage:t,...i},o)=>l(d,{appearance:"panel",ref:o,...i,children:[s(f,{appearance:"ghost",disabled:!e,icon:s(A,{}),label:"Previous page",onClick:t,size:"sm",type:"button"}),s(z,{orientation:"vertical",className:"min-h-5"}),s(f,{appearance:"ghost",disabled:!n,icon:s(E,{}),label:"Next page",onClick:a,size:"sm",type:"button"})]}));T.displayName="CursorButtons";var D=[5,10,20,50,100],V=c(({className:n,pageSizes:e=D,onChangePageSize:a,...t},i)=>{let o=N(m);return P(o,"CursorPageSizeSelect must be used as a child of a CursorPagination component"),P(e.includes(o.defaultPageSize),"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes"),P(e.includes(o.pageSize),"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes"),l(b,{defaultValue:`${o.pageSize}`,onValueChange:r=>{let g=Number.parseInt(r,10);Number.isNaN(g)&&(g=o.defaultPageSize),o.setPageSize(g),a?.(g)},children:[s(y,{ref:i,className:p("w-auto min-w-36",n),value:o.pageSize,...t,children:s(v,{})}),s(x,{width:"trigger",children:e.map(r=>l(h,{value:`${r}`,children:[r," per page"]},r))})]})});V.displayName="CursorPageSizeSelect";function B({asChild:n=!1,className:e,...a}){let t=N(m);return P(t,"CursorPageSizeValue must be used as a child of a CursorPagination component"),l(n?F:"span",{className:p("text-muted text-sm font-normal",e),...a,children:[t.pageSize," per page"]})}B.displayName="CursorPageSizeValue";import{useEffect as w,useState as I}from"react";function H({listSize:n,pageSize:e}){let[a,t]=I(1),[i,o]=I(e);w(()=>{o(e),t(1)},[e]),w(()=>{t(1)},[n]);let r=Math.ceil(n/i),g=(a-1)*i,S=a>1,C=a<r;function M(u){let k=Math.max(1,Math.min(u,r));t(k)}function R(){C&&t(u=>Math.min(u+1,r))}function G(){S&&t(u=>Math.max(u-1,1))}function L(u){o(u),t(1)}function U(){t(r)}function j(){t(1)}return{currentPage:a,goToFirstPage:j,goToLastPage:U,goToPage:M,hasNextPage:C,hasPreviousPage:S,nextPage:R,offset:g,pageSize:i,previousPage:G,setPageSize:L,totalPages:r}}function q(n,e){return n.slice(e.offset,e.offset+e.pageSize)}export{T as CursorButtons,V as CursorPageSizeSelect,B as CursorPageSizeValue,O as CursorPagination,q as getOffsetPaginatedSlice,H as useOffsetPagination};
1
+ import{a as p}from"./chunk-4GGDPFNZ.js";import"./chunk-MF2QITTY.js";import{b}from"./chunk-J6ZF5J72.js";import{a as z}from"./chunk-3H3EUKI7.js";import{a as m}from"./chunk-RTXWW6ND.js";import"./chunk-PANPBV3Q.js";import"./chunk-4LSFAAZW.js";import"./chunk-72TJUKMV.js";import"./chunk-3C5O3AQA.js";import"./chunk-I6T6YV2L.js";import"./chunk-NPTDRQT5.js";import{a as P}from"./chunk-AZ56JGNY.js";import{CaretLeftIcon as L}from"@phosphor-icons/react/CaretLeft";import{CaretRightIcon as U}from"@phosphor-icons/react/CaretRight";import{Slot as j}from"@radix-ui/react-slot";import{createContext as k,forwardRef as c,useContext as v,useState as A}from"react";import f from"tiny-invariant";import{jsx as s,jsxs as l}from"react/jsx-runtime";var S=k(void 0),y=c(({className:r,children:e,defaultPageSize:a,...t},i)=>{let[o,n]=A(a);return s(S.Provider,{value:{defaultPageSize:a,pageSize:o,setPageSize:n},children:s("div",{className:P("inline-flex items-center justify-between gap-2",r),ref:i,...t,children:e})})});y.displayName="CursorPagination";var x=c(({hasNextPage:r,hasPreviousPage:e,onNextPage:a,onPreviousPage:t,...i},o)=>l(z,{appearance:"panel",ref:o,...i,children:[s(m,{appearance:"ghost",disabled:!e,icon:s(L,{}),label:"Previous page",onClick:t,size:"sm",type:"button"}),s(b,{orientation:"vertical",className:"min-h-5"}),s(m,{appearance:"ghost",disabled:!r,icon:s(U,{}),label:"Next page",onClick:a,size:"sm",type:"button"})]}));x.displayName="CursorButtons";var E=[5,10,20,50,100],h=c(({className:r,pageSizes:e=E,onChangePageSize:a,...t},i)=>{let o=v(S);return f(o,"CursorPageSizeSelect must be used as a child of a CursorPagination component"),f(e.includes(o.defaultPageSize),"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes"),f(e.includes(o.pageSize),"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes"),l(p.Root,{defaultValue:`${o.pageSize}`,onValueChange:n=>{let g=Number.parseInt(n,10);Number.isNaN(g)&&(g=o.defaultPageSize),o.setPageSize(g),a?.(g)},children:[s(p.Trigger,{ref:i,className:P("w-auto min-w-36",r),value:o.pageSize,...t,children:s(p.Value,{})}),s(p.Content,{width:"trigger",children:e.map(n=>l(p.Item,{value:`${n}`,children:[n," per page"]},n))})]})});h.displayName="CursorPageSizeSelect";function N({asChild:r=!1,className:e,...a}){let t=v(S);return f(t,"CursorPageSizeValue must be used as a child of a CursorPagination component"),l(r?j:"span",{className:P("text-muted text-sm font-normal",e),...a,children:[t.pageSize," per page"]})}N.displayName="CursorPageSizeValue";var F={Root:y,Buttons:x,PageSizeSelect:h,PageSizeValue:N};import{useEffect as O,useState as T}from"react";function W({listSize:r,pageSize:e}){let[a,t]=T(1),[i,o]=T(e);O(()=>{o(e),t(1)},[e]),O(()=>{t(1)},[r]);let n=Math.ceil(r/i),g=(a-1)*i,C=a>1,d=a<n;function V(u){let G=Math.max(1,Math.min(u,n));t(G)}function B(){d&&t(u=>Math.min(u+1,n))}function R(){C&&t(u=>Math.max(u-1,1))}function w(u){o(u),t(1)}function I(){t(n)}function M(){t(1)}return{currentPage:a,goToFirstPage:M,goToLastPage:I,goToPage:V,hasNextPage:d,hasPreviousPage:C,nextPage:B,offset:g,pageSize:i,previousPage:R,setPageSize:w,totalPages:n}}function $(r,e){return r.slice(e.offset,e.offset+e.pageSize)}export{F as CursorPagination,$ as getOffsetPaginatedSlice,W as useOffsetPagination};
2
2
  //# sourceMappingURL=pagination.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/components/pagination/cursor-pagination.tsx","../src/components/pagination/use-offset-pagination.tsx"],"sourcesContent":["\"use client\";\n\nimport { CaretLeftIcon } from \"@phosphor-icons/react/CaretLeft\";\nimport { CaretRightIcon } from \"@phosphor-icons/react/CaretRight\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n\ttype ComponentProps,\n\ttype ComponentRef,\n\tcreateContext,\n\tforwardRef,\n\tuseContext,\n\tuseState,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { ButtonGroup, IconButton } from \"../button/index.js\";\nimport {\n\tSelect,\n\tSelectContent,\n\tSelectItem,\n\tSelectTrigger,\n\tSelectValue,\n} from \"../select/select.js\";\nimport { Separator } from \"../separator/separator.js\";\n\ntype CursorPaginationContextValue = {\n\t/**\n\t * The default number of items per page.\n\t */\n\tdefaultPageSize: number;\n\t/**\n\t * The current number of items per page.\n\t */\n\tpageSize: number;\n\t/**\n\t * A function to set the number of items per page.\n\t */\n\tsetPageSize: (value: number) => void;\n};\n\nconst CursorPaginationContext = createContext<\n\tCursorPaginationContextValue | undefined\n>(undefined);\n\ntype CursorPaginationProps = ComponentProps<\"div\"> & {\n\t/**\n\t * The default number of items per page.\n\t */\n\tdefaultPageSize: number;\n};\n\n/**\n * A pagination component for use with cursor-based pagination.\n *\n * Cursor-based pagination is a way of loading data in chunks by using a cursor\n * from the last item on the current page to know where to start the next set,\n * making sure nothing is missed or repeated. Like a linked list, but for chunks\n * of data. It doesn't let you jump to a specific page or know how many total pages\n * there are, but it's more efficient for large or real-time data sets.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-pagination\n *\n * @example\n * ```tsx\n * <CursorPagination defaultPageSize={10}>\n * <CursorButtons\n * hasNextPage={hasNext}\n * hasPreviousPage={hasPrevious}\n * onNextPage={handleNext}\n * onPreviousPage={handlePrevious}\n * />\n * <CursorPageSizeSelect />\n * </CursorPagination>\n * ```\n */\nconst CursorPagination = forwardRef<HTMLDivElement, CursorPaginationProps>(\n\t({ className, children, defaultPageSize, ...props }, ref) => {\n\t\tconst [pageSize, setPageSize] = useState<number>(defaultPageSize);\n\n\t\treturn (\n\t\t\t<CursorPaginationContext.Provider\n\t\t\t\tvalue={{ defaultPageSize, pageSize, setPageSize }}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"inline-flex items-center justify-between gap-2\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</CursorPaginationContext.Provider>\n\t\t);\n\t},\n);\nCursorPagination.displayName = \"CursorPagination\";\n\ntype CursorButtonsProps = Omit<\n\tComponentProps<typeof ButtonGroup>,\n\t\"appearance\"\n> & {\n\t/**\n\t * Whether there is a next page of data to load.\n\t */\n\thasNextPage: boolean;\n\t/**\n\t * Whether there is a previous page of data to load.\n\t */\n\thasPreviousPage: boolean;\n\t/**\n\t * A callback that is called when the next page button is clicked.\n\t */\n\tonNextPage?: () => void;\n\t/**\n\t * A callback that is called when the previous page button is clicked.\n\t */\n\tonPreviousPage?: () => void;\n};\n\n/**\n * A pair of buttons for navigating between pages of data when using cursor-based pagination.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-buttons\n *\n * @example\n * ```tsx\n * <CursorButtons\n * hasNextPage={hasNext}\n * hasPreviousPage={hasPrevious}\n * onNextPage={() => loadNextPage()}\n * onPreviousPage={() => loadPreviousPage()}\n * />\n * ```\n */\nconst CursorButtons = forwardRef<\n\tComponentRef<typeof ButtonGroup>,\n\tCursorButtonsProps\n>(\n\t(\n\t\t{ hasNextPage, hasPreviousPage, onNextPage, onPreviousPage, ...props },\n\t\tref,\n\t) => {\n\t\t// TODO(cody): this _feels_ like a good spot for left and right arrow keys to navigate between pages when focused on the buttons\n\n\t\treturn (\n\t\t\t<ButtonGroup appearance=\"panel\" ref={ref} {...props}>\n\t\t\t\t<IconButton\n\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\tdisabled={!hasPreviousPage}\n\t\t\t\t\ticon={<CaretLeftIcon />}\n\t\t\t\t\tlabel=\"Previous page\"\n\t\t\t\t\tonClick={onPreviousPage}\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t/>\n\t\t\t\t<Separator orientation=\"vertical\" className=\"min-h-5\" />\n\t\t\t\t<IconButton\n\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\tdisabled={!hasNextPage}\n\t\t\t\t\ticon={<CaretRightIcon />}\n\t\t\t\t\tlabel=\"Next page\"\n\t\t\t\t\tonClick={onNextPage}\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t/>\n\t\t\t</ButtonGroup>\n\t\t);\n\t},\n);\nCursorButtons.displayName = \"CursorButtons\";\n\nconst defaultPageSizes = [5, 10, 20, 50, 100] as const;\n\ntype CursorPageSizeSelectProps = Omit<\n\tComponentProps<typeof SelectTrigger>,\n\t\"children\"\n> & {\n\t/**\n\t * A list of page sizes to choose from. The default page size must be included in this list.\n\t */\n\tpageSizes?: typeof defaultPageSizes | readonly number[];\n\t/**\n\t * A callback that is called when the page size is changed.\n\t */\n\tonChangePageSize?: (value: number) => void;\n};\n\n/**\n * A select input for changing the number of items per page when using cursor-based pagination.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-select\n *\n * @example\n * ```tsx\n * <CursorPageSizeSelect\n * pageSizes={[10, 20, 50, 100]}\n * onChangePageSize={(size) => console.log('Page size changed to:', size)}\n * />\n * ```\n */\nconst CursorPageSizeSelect = forwardRef<\n\tComponentRef<typeof SelectTrigger>,\n\tCursorPageSizeSelectProps\n>(\n\t(\n\t\t{ className, pageSizes = defaultPageSizes, onChangePageSize, ...rest },\n\t\tref,\n\t) => {\n\t\tconst ctx = useContext(CursorPaginationContext);\n\n\t\tinvariant(\n\t\t\tctx,\n\t\t\t\"CursorPageSizeSelect must be used as a child of a CursorPagination component\",\n\t\t);\n\n\t\tinvariant(\n\t\t\tpageSizes.includes(ctx.defaultPageSize),\n\t\t\t\"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes\",\n\t\t);\n\n\t\tinvariant(\n\t\t\tpageSizes.includes(ctx.pageSize),\n\t\t\t\"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes\",\n\t\t);\n\n\t\treturn (\n\t\t\t<Select\n\t\t\t\tdefaultValue={`${ctx.pageSize}`}\n\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\tlet newPageSize = Number.parseInt(value, 10);\n\t\t\t\t\tif (Number.isNaN(newPageSize)) {\n\t\t\t\t\t\tnewPageSize = ctx.defaultPageSize;\n\t\t\t\t\t}\n\t\t\t\t\tctx.setPageSize(newPageSize);\n\t\t\t\t\tonChangePageSize?.(newPageSize);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<SelectTrigger\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cx(\"w-auto min-w-36\", className)}\n\t\t\t\t\tvalue={ctx.pageSize}\n\t\t\t\t\t{...rest}\n\t\t\t\t>\n\t\t\t\t\t<SelectValue />\n\t\t\t\t</SelectTrigger>\n\t\t\t\t<SelectContent width=\"trigger\">\n\t\t\t\t\t{pageSizes.map((size) => (\n\t\t\t\t\t\t<SelectItem key={size} value={`${size}`}>\n\t\t\t\t\t\t\t{size} per page\n\t\t\t\t\t\t</SelectItem>\n\t\t\t\t\t))}\n\t\t\t\t</SelectContent>\n\t\t\t</Select>\n\t\t);\n\t},\n);\nCursorPageSizeSelect.displayName = \"CursorPageSizeSelect\";\n\ntype CursorPageSizeValueProps = Omit<ComponentProps<\"span\">, \"children\"> &\n\tWithAsChild;\n\n/**\n * Displays the current page size when using cursor-based pagination as a read-only value.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-value\n *\n * @example\n * ```tsx\n * <div className=\"flex items-center gap-2\">\n * <span>Items per page:</span>\n * <CursorPageSizeValue />\n * </div>\n * ```\n */\nfunction CursorPageSizeValue({\n\tasChild = false,\n\tclassName,\n\t...props\n}: CursorPageSizeValueProps) {\n\tconst ctx = useContext(CursorPaginationContext);\n\n\tinvariant(\n\t\tctx,\n\t\t\"CursorPageSizeValue must be used as a child of a CursorPagination component\",\n\t);\n\n\tconst Component = asChild ? Slot : \"span\";\n\n\treturn (\n\t\t<Component\n\t\t\tclassName={cx(\"text-muted text-sm font-normal\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{ctx.pageSize} per page\n\t\t</Component>\n\t);\n}\nCursorPageSizeValue.displayName = \"CursorPageSizeValue\";\n\nexport {\n\t//,\n\tCursorButtons,\n\tCursorPageSizeSelect,\n\tCursorPageSizeValue,\n\tCursorPagination,\n};\n\nexport type {\n\t//,\n\tCursorButtonsProps,\n\tCursorPageSizeSelectProps,\n\tCursorPageSizeValueProps,\n\tCursorPaginationProps,\n};\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\ntype UseOffsetPaginationProps = {\n\t/**\n\t * The total number of items in the list to be paginated.\n\t */\n\tlistSize: number;\n\t/**\n\t * The number of items per page.\n\t */\n\tpageSize: number;\n};\n\ntype OffsetPaginationState = {\n\t/**\n\t * The current page number, 1-indexed (starting at 1).\n\t */\n\tcurrentPage: number;\n\t/**\n\t * Whether there is a previous page.\n\t */\n\thasPreviousPage: boolean;\n\t/**\n\t * Whether there is a next page.\n\t */\n\thasNextPage: boolean;\n\t/**\n\t * Go to a specific page.\n\t */\n\tgoToPage: (page: number) => void;\n\t/**\n\t * Go to the first page.\n\t */\n\tgoToFirstPage: () => void;\n\t/**\n\t * Go to the last page.\n\t */\n\tgoToLastPage: () => void;\n\t/**\n\t * Go to the next page.\n\t */\n\tnextPage: () => void;\n\t/**\n\t * The offset of the current page in the list.\n\t */\n\toffset: number;\n\t/**\n\t * The number of items per page.\n\t */\n\tpageSize: number;\n\t/**\n\t * Go to the previous page.\n\t */\n\tpreviousPage: () => void;\n\t/**\n\t * Set the number of items per page. This will reset the current page to the first page.\n\t */\n\tsetPageSize: (size: number) => void;\n\t/**\n\t * The total number of pages.\n\t */\n\ttotalPages: number;\n};\n\n/**\n * A headless hook for managing offset-based pagination state\n */\nfunction useOffsetPagination({\n\tlistSize,\n\tpageSize,\n}: UseOffsetPaginationProps): OffsetPaginationState {\n\tconst [currentPage, setCurrentPage] = useState(1);\n\tconst [currentPageSize, setCurrentPageSize] = useState(pageSize);\n\n\t// Reset the current page to 1 when the page size prop changes\n\tuseEffect(() => {\n\t\tsetCurrentPageSize(pageSize);\n\t\tsetCurrentPage(1);\n\t}, [pageSize]);\n\n\t// Reset the current page to 1 when the list size prop changes\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: when the listSize prop changes, we want to reset the current page to the start\n\tuseEffect(() => {\n\t\tsetCurrentPage(1);\n\t}, [listSize]);\n\n\tconst totalPages = Math.ceil(listSize / currentPageSize);\n\tconst offset = (currentPage - 1) * currentPageSize;\n\n\tconst hasPreviousPage = currentPage > 1;\n\tconst hasNextPage = currentPage < totalPages;\n\n\tfunction goToPage(page: number) {\n\t\tconst nextPage = Math.max(1, Math.min(page, totalPages));\n\t\tsetCurrentPage(nextPage);\n\t}\n\n\tfunction nextPage() {\n\t\tif (hasNextPage) {\n\t\t\tsetCurrentPage((prev) => Math.min(prev + 1, totalPages));\n\t\t}\n\t}\n\n\tfunction previousPage() {\n\t\tif (hasPreviousPage) {\n\t\t\tsetCurrentPage((prev) => Math.max(prev - 1, 1));\n\t\t}\n\t}\n\n\tfunction setPageSize(size: number) {\n\t\tsetCurrentPageSize(size);\n\t\tsetCurrentPage(1); // reset to the first page when page size changes\n\t}\n\n\tfunction goToLastPage() {\n\t\tsetCurrentPage(totalPages);\n\t}\n\n\tfunction goToFirstPage() {\n\t\tsetCurrentPage(1);\n\t}\n\n\treturn {\n\t\tcurrentPage,\n\t\tgoToFirstPage,\n\t\tgoToLastPage,\n\t\tgoToPage,\n\t\thasNextPage,\n\t\thasPreviousPage,\n\t\tnextPage,\n\t\toffset,\n\t\tpageSize: currentPageSize,\n\t\tpreviousPage,\n\t\tsetPageSize,\n\t\ttotalPages,\n\t};\n}\n\n/**\n * Get a paginated slice of a list based on the current offset pagination state.\n */\nfunction getOffsetPaginatedSlice<T>(\n\tlist: readonly T[],\n\tpagination: OffsetPaginationState,\n): T[] {\n\treturn list.slice(pagination.offset, pagination.offset + pagination.pageSize);\n}\n\nexport {\n\t//,\n\tgetOffsetPaginatedSlice,\n\tuseOffsetPagination,\n};\n\nexport type {\n\t//,\n\tOffsetPaginationState,\n\tUseOffsetPaginationProps,\n};\n"],"mappings":"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","names":["CaretLeftIcon","CaretRightIcon","Slot","createContext","forwardRef","useContext","useState","invariant","jsx","jsxs","CursorPaginationContext","createContext","CursorPagination","forwardRef","className","children","defaultPageSize","props","ref","pageSize","setPageSize","useState","cx","CursorButtons","hasNextPage","hasPreviousPage","onNextPage","onPreviousPage","ButtonGroup","IconButton","CaretLeftIcon","Separator","CaretRightIcon","defaultPageSizes","CursorPageSizeSelect","pageSizes","onChangePageSize","rest","ctx","useContext","invariant","Select","value","newPageSize","SelectTrigger","SelectValue","SelectContent","size","SelectItem","CursorPageSizeValue","asChild","Slot","useEffect","useState","useOffsetPagination","listSize","pageSize","currentPage","setCurrentPage","currentPageSize","setCurrentPageSize","totalPages","offset","hasPreviousPage","hasNextPage","goToPage","page","nextPage","prev","previousPage","setPageSize","size","goToLastPage","goToFirstPage","getOffsetPaginatedSlice","list","pagination"]}
1
+ {"version":3,"sources":["../src/components/pagination/cursor-pagination.tsx","../src/components/pagination/use-offset-pagination.tsx"],"sourcesContent":["\"use client\";\n\nimport { CaretLeftIcon } from \"@phosphor-icons/react/CaretLeft\";\nimport { CaretRightIcon } from \"@phosphor-icons/react/CaretRight\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport {\n\ttype ComponentProps,\n\ttype ComponentRef,\n\tcreateContext,\n\tforwardRef,\n\tuseContext,\n\tuseState,\n} from \"react\";\nimport invariant from \"tiny-invariant\";\nimport type { WithAsChild } from \"../../types/as-child.js\";\nimport { cx } from \"../../utils/cx/cx.js\";\nimport { ButtonGroup, IconButton } from \"../button/index.js\";\nimport { Select } from \"../select/select.js\";\nimport { Separator } from \"../separator/separator.js\";\n\ntype CursorPaginationContextValue = {\n\t/**\n\t * The default number of items per page.\n\t */\n\tdefaultPageSize: number;\n\t/**\n\t * The current number of items per page.\n\t */\n\tpageSize: number;\n\t/**\n\t * A function to set the number of items per page.\n\t */\n\tsetPageSize: (value: number) => void;\n};\n\nconst CursorPaginationContext = createContext<\n\tCursorPaginationContextValue | undefined\n>(undefined);\n\ntype CursorPaginationProps = ComponentProps<\"div\"> & {\n\t/**\n\t * The default number of items per page.\n\t */\n\tdefaultPageSize: number;\n};\n\n/**\n * A pagination component for use with cursor-based pagination.\n *\n * Cursor-based pagination is a way of loading data in chunks by using a cursor\n * from the last item on the current page to know where to start the next set,\n * making sure nothing is missed or repeated. Like a linked list, but for chunks\n * of data. It doesn't let you jump to a specific page or know how many total pages\n * there are, but it's more efficient for large or real-time data sets.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-pagination\n *\n * @example\n * ```tsx\n * <CursorPagination defaultPageSize={10}>\n * <CursorPagination.Buttons\n * hasNextPage={hasNext}\n * hasPreviousPage={hasPrevious}\n * onNextPage={handleNext}\n * onPreviousPage={handlePrevious}\n * />\n * <CursorPagination.PageSizeSelect />\n * </CursorPagination>\n * ```\n */\nconst Root = forwardRef<HTMLDivElement, CursorPaginationProps>(\n\t({ className, children, defaultPageSize, ...props }, ref) => {\n\t\tconst [pageSize, setPageSize] = useState<number>(defaultPageSize);\n\n\t\treturn (\n\t\t\t<CursorPaginationContext.Provider\n\t\t\t\tvalue={{ defaultPageSize, pageSize, setPageSize }}\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName={cx(\n\t\t\t\t\t\t\"inline-flex items-center justify-between gap-2\",\n\t\t\t\t\t\tclassName,\n\t\t\t\t\t)}\n\t\t\t\t\tref={ref}\n\t\t\t\t\t{...props}\n\t\t\t\t>\n\t\t\t\t\t{children}\n\t\t\t\t</div>\n\t\t\t</CursorPaginationContext.Provider>\n\t\t);\n\t},\n);\nRoot.displayName = \"CursorPagination\";\n\ntype CursorButtonsProps = Omit<\n\tComponentProps<typeof ButtonGroup>,\n\t\"appearance\"\n> & {\n\t/**\n\t * Whether there is a next page of data to load.\n\t */\n\thasNextPage: boolean;\n\t/**\n\t * Whether there is a previous page of data to load.\n\t */\n\thasPreviousPage: boolean;\n\t/**\n\t * A callback that is called when the next page button is clicked.\n\t */\n\tonNextPage?: () => void;\n\t/**\n\t * A callback that is called when the previous page button is clicked.\n\t */\n\tonPreviousPage?: () => void;\n};\n\n/**\n * A pair of buttons for navigating between pages of data when using cursor-based pagination.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-buttons\n *\n * @example\n * ```tsx\n * <CursorPagination.Buttons\n * hasNextPage={hasNext}\n * hasPreviousPage={hasPrevious}\n * onNextPage={() => loadNextPage()}\n * onPreviousPage={() => loadPreviousPage()}\n * />\n * ```\n */\nconst Buttons = forwardRef<\n\tComponentRef<typeof ButtonGroup>,\n\tCursorButtonsProps\n>(\n\t(\n\t\t{ hasNextPage, hasPreviousPage, onNextPage, onPreviousPage, ...props },\n\t\tref,\n\t) => {\n\t\t// TODO(cody): this _feels_ like a good spot for left and right arrow keys to navigate between pages when focused on the buttons\n\n\t\treturn (\n\t\t\t<ButtonGroup appearance=\"panel\" ref={ref} {...props}>\n\t\t\t\t<IconButton\n\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\tdisabled={!hasPreviousPage}\n\t\t\t\t\ticon={<CaretLeftIcon />}\n\t\t\t\t\tlabel=\"Previous page\"\n\t\t\t\t\tonClick={onPreviousPage}\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t/>\n\t\t\t\t<Separator orientation=\"vertical\" className=\"min-h-5\" />\n\t\t\t\t<IconButton\n\t\t\t\t\tappearance=\"ghost\"\n\t\t\t\t\tdisabled={!hasNextPage}\n\t\t\t\t\ticon={<CaretRightIcon />}\n\t\t\t\t\tlabel=\"Next page\"\n\t\t\t\t\tonClick={onNextPage}\n\t\t\t\t\tsize=\"sm\"\n\t\t\t\t\ttype=\"button\"\n\t\t\t\t/>\n\t\t\t</ButtonGroup>\n\t\t);\n\t},\n);\nButtons.displayName = \"CursorButtons\";\n\nconst defaultPageSizes = [5, 10, 20, 50, 100] as const;\n\ntype CursorPageSizeSelectProps = Omit<\n\tComponentProps<typeof Select.Trigger>,\n\t\"children\"\n> & {\n\t/**\n\t * A list of page sizes to choose from. The default page size must be included in this list.\n\t */\n\tpageSizes?: typeof defaultPageSizes | readonly number[];\n\t/**\n\t * A callback that is called when the page size is changed.\n\t */\n\tonChangePageSize?: (value: number) => void;\n};\n\n/**\n * A select input for changing the number of items per page when using cursor-based pagination.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-select\n *\n * @example\n * ```tsx\n * <CursorPagination.PageSizeSelect\n * pageSizes={[10, 20, 50, 100]}\n * onChangePageSize={(size) => console.log('Page size changed to:', size)}\n * />\n * ```\n */\nconst PageSizeSelect = forwardRef<\n\tComponentRef<typeof Select.Trigger>,\n\tCursorPageSizeSelectProps\n>(\n\t(\n\t\t{ className, pageSizes = defaultPageSizes, onChangePageSize, ...rest },\n\t\tref,\n\t) => {\n\t\tconst ctx = useContext(CursorPaginationContext);\n\n\t\tinvariant(\n\t\t\tctx,\n\t\t\t\"CursorPageSizeSelect must be used as a child of a CursorPagination component\",\n\t\t);\n\n\t\tinvariant(\n\t\t\tpageSizes.includes(ctx.defaultPageSize),\n\t\t\t\"CursorPagination.defaultPageSize must be included in CursorPageSizeSelect.pageSizes\",\n\t\t);\n\n\t\tinvariant(\n\t\t\tpageSizes.includes(ctx.pageSize),\n\t\t\t\"CursorPagination.pageSize must be included in CursorPageSizeSelect.pageSizes\",\n\t\t);\n\n\t\treturn (\n\t\t\t<Select.Root\n\t\t\t\tdefaultValue={`${ctx.pageSize}`}\n\t\t\t\tonValueChange={(value) => {\n\t\t\t\t\tlet newPageSize = Number.parseInt(value, 10);\n\t\t\t\t\tif (Number.isNaN(newPageSize)) {\n\t\t\t\t\t\tnewPageSize = ctx.defaultPageSize;\n\t\t\t\t\t}\n\t\t\t\t\tctx.setPageSize(newPageSize);\n\t\t\t\t\tonChangePageSize?.(newPageSize);\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t<Select.Trigger\n\t\t\t\t\tref={ref}\n\t\t\t\t\tclassName={cx(\"w-auto min-w-36\", className)}\n\t\t\t\t\tvalue={ctx.pageSize}\n\t\t\t\t\t{...rest}\n\t\t\t\t>\n\t\t\t\t\t<Select.Value />\n\t\t\t\t</Select.Trigger>\n\t\t\t\t<Select.Content width=\"trigger\">\n\t\t\t\t\t{pageSizes.map((size) => (\n\t\t\t\t\t\t<Select.Item key={size} value={`${size}`}>\n\t\t\t\t\t\t\t{size} per page\n\t\t\t\t\t\t</Select.Item>\n\t\t\t\t\t))}\n\t\t\t\t</Select.Content>\n\t\t\t</Select.Root>\n\t\t);\n\t},\n);\nPageSizeSelect.displayName = \"CursorPageSizeSelect\";\n\ntype CursorPageSizeValueProps = Omit<ComponentProps<\"span\">, \"children\"> &\n\tWithAsChild;\n\n/**\n * Displays the current page size when using cursor-based pagination as a read-only value.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-value\n *\n * @example\n * ```tsx\n * <div className=\"flex items-center gap-2\">\n * <span>Items per page:</span>\n * <CursorPagination.PageSizeValue />\n * </div>\n * ```\n */\nfunction PageSizeValue({\n\tasChild = false,\n\tclassName,\n\t...props\n}: CursorPageSizeValueProps) {\n\tconst ctx = useContext(CursorPaginationContext);\n\n\tinvariant(\n\t\tctx,\n\t\t\"CursorPageSizeValue must be used as a child of a CursorPagination component\",\n\t);\n\n\tconst Component = asChild ? Slot : \"span\";\n\n\treturn (\n\t\t<Component\n\t\t\tclassName={cx(\"text-muted text-sm font-normal\", className)}\n\t\t\t{...props}\n\t\t>\n\t\t\t{ctx.pageSize} per page\n\t\t</Component>\n\t);\n}\nPageSizeValue.displayName = \"CursorPageSizeValue\";\n\n/**\n * A pagination component for use with cursor-based pagination.\n *\n * Cursor-based pagination is a way of loading data in chunks by using a cursor\n * from the last item on the current page to know where to start the next set,\n * making sure nothing is missed or repeated. Like a linked list, but for chunks\n * of data. It doesn't let you jump to a specific page or know how many total pages\n * there are, but it's more efficient for large or real-time data sets.\n *\n * @see https://mantle.ngrok.com/components/cursor-pagination\n *\n * @example\n * ```tsx\n * <CursorPagination defaultPageSize={10}>\n * <CursorPagination.Buttons\n * hasNextPage={hasNext}\n * hasPreviousPage={hasPrevious}\n * onNextPage={handleNext}\n * onPreviousPage={handlePrevious}\n * />\n * <CursorPagination.PageSizeSelect />\n * </CursorPagination>\n * ```\n */\nconst CursorPagination = {\n\t/**\n\t * The root container of the cursor pagination component.\n\t *\n\t * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-pagination\n\t *\n\t * @example\n\t * ```tsx\n\t * <CursorPagination.Root defaultPageSize={10}>\n\t * <CursorPagination.Buttons\n\t * hasNextPage={hasNext}\n\t * hasPreviousPage={hasPrevious}\n\t * onNextPage={handleNext}\n\t * onPreviousPage={handlePrevious}\n\t * />\n\t * <CursorPagination.PageSizeSelect />\n\t * </CursorPagination.Root>\n\t * ```\n\t */\n\tRoot,\n\t/**\n\t * A pair of buttons for navigating between pages of data when using cursor-based pagination.\n\t *\n\t * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-buttons\n\t *\n\t * @example\n\t * ```tsx\n\t * <CursorPagination.Buttons\n\t * hasNextPage={hasNext}\n\t * hasPreviousPage={hasPrevious}\n\t * onNextPage={() => loadNextPage()}\n\t * onPreviousPage={() => loadPreviousPage()}\n\t * />\n\t * ```\n\t */\n\tButtons,\n\t/**\n\t * A select input for changing the number of items per page when using cursor-based pagination.\n\t *\n\t * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-select\n\t *\n\t * @example\n\t * ```tsx\n\t * <CursorPagination.PageSizeSelect\n\t * pageSizes={[10, 20, 50, 100]}\n\t * onChangePageSize={(size) => console.log('Page size changed to:', size)}\n\t * />\n\t * ```\n\t */\n\tPageSizeSelect,\n\t/**\n\t * Displays the current page size when using cursor-based pagination as a read-only value.\n\t *\n\t * @see https://mantle.ngrok.com/components/cursor-pagination#api-cursor-page-size-value\n\t *\n\t * @example\n\t * ```tsx\n\t * <div className=\"flex items-center gap-2\">\n\t * <span>Items per page:</span>\n\t * <CursorPagination.PageSizeValue />\n\t * </div>\n\t * ```\n\t */\n\tPageSizeValue,\n} as const;\n\nexport {\n\t//,\n\tCursorPagination,\n};\n\nexport type {\n\t//,\n\tCursorButtonsProps,\n\tCursorPageSizeSelectProps,\n\tCursorPageSizeValueProps,\n\tCursorPaginationProps,\n};\n","\"use client\";\n\nimport { useEffect, useState } from \"react\";\n\ntype UseOffsetPaginationProps = {\n\t/**\n\t * The total number of items in the list to be paginated.\n\t */\n\tlistSize: number;\n\t/**\n\t * The number of items per page.\n\t */\n\tpageSize: number;\n};\n\ntype OffsetPaginationState = {\n\t/**\n\t * The current page number, 1-indexed (starting at 1).\n\t */\n\tcurrentPage: number;\n\t/**\n\t * Whether there is a previous page.\n\t */\n\thasPreviousPage: boolean;\n\t/**\n\t * Whether there is a next page.\n\t */\n\thasNextPage: boolean;\n\t/**\n\t * Go to a specific page.\n\t */\n\tgoToPage: (page: number) => void;\n\t/**\n\t * Go to the first page.\n\t */\n\tgoToFirstPage: () => void;\n\t/**\n\t * Go to the last page.\n\t */\n\tgoToLastPage: () => void;\n\t/**\n\t * Go to the next page.\n\t */\n\tnextPage: () => void;\n\t/**\n\t * The offset of the current page in the list.\n\t */\n\toffset: number;\n\t/**\n\t * The number of items per page.\n\t */\n\tpageSize: number;\n\t/**\n\t * Go to the previous page.\n\t */\n\tpreviousPage: () => void;\n\t/**\n\t * Set the number of items per page. This will reset the current page to the first page.\n\t */\n\tsetPageSize: (size: number) => void;\n\t/**\n\t * The total number of pages.\n\t */\n\ttotalPages: number;\n};\n\n/**\n * A headless hook for managing offset-based pagination state\n *\n * @example\n * ```tsx\n * const pagination = useOffsetPagination({\n * listSize: 150,\n * pageSize: 10\n * });\n *\n * return (\n * <div>\n * <p>Page {pagination.currentPage} of {pagination.totalPages}</p>\n * <button onClick={pagination.previousPage} disabled={!pagination.hasPreviousPage}>\n * Previous\n * </button>\n * <button onClick={pagination.nextPage} disabled={!pagination.hasNextPage}>\n * Next\n * </button>\n * </div>\n * );\n * ```\n */\nfunction useOffsetPagination({\n\tlistSize,\n\tpageSize,\n}: UseOffsetPaginationProps): OffsetPaginationState {\n\tconst [currentPage, setCurrentPage] = useState(1);\n\tconst [currentPageSize, setCurrentPageSize] = useState(pageSize);\n\n\t// Reset the current page to 1 when the page size prop changes\n\tuseEffect(() => {\n\t\tsetCurrentPageSize(pageSize);\n\t\tsetCurrentPage(1);\n\t}, [pageSize]);\n\n\t// Reset the current page to 1 when the list size prop changes\n\t// biome-ignore lint/correctness/useExhaustiveDependencies: when the listSize prop changes, we want to reset the current page to the start\n\tuseEffect(() => {\n\t\tsetCurrentPage(1);\n\t}, [listSize]);\n\n\tconst totalPages = Math.ceil(listSize / currentPageSize);\n\tconst offset = (currentPage - 1) * currentPageSize;\n\n\tconst hasPreviousPage = currentPage > 1;\n\tconst hasNextPage = currentPage < totalPages;\n\n\tfunction goToPage(page: number) {\n\t\tconst nextPage = Math.max(1, Math.min(page, totalPages));\n\t\tsetCurrentPage(nextPage);\n\t}\n\n\tfunction nextPage() {\n\t\tif (hasNextPage) {\n\t\t\tsetCurrentPage((prev) => Math.min(prev + 1, totalPages));\n\t\t}\n\t}\n\n\tfunction previousPage() {\n\t\tif (hasPreviousPage) {\n\t\t\tsetCurrentPage((prev) => Math.max(prev - 1, 1));\n\t\t}\n\t}\n\n\tfunction setPageSize(size: number) {\n\t\tsetCurrentPageSize(size);\n\t\tsetCurrentPage(1); // reset to the first page when page size changes\n\t}\n\n\tfunction goToLastPage() {\n\t\tsetCurrentPage(totalPages);\n\t}\n\n\tfunction goToFirstPage() {\n\t\tsetCurrentPage(1);\n\t}\n\n\treturn {\n\t\tcurrentPage,\n\t\tgoToFirstPage,\n\t\tgoToLastPage,\n\t\tgoToPage,\n\t\thasNextPage,\n\t\thasPreviousPage,\n\t\tnextPage,\n\t\toffset,\n\t\tpageSize: currentPageSize,\n\t\tpreviousPage,\n\t\tsetPageSize,\n\t\ttotalPages,\n\t};\n}\n\n/**\n * Get a paginated slice of a list based on the current offset pagination state.\n *\n * @example\n * ```tsx\n * const data = ['a', 'b', 'c', 'd', 'e', 'f'];\n * const pagination = useOffsetPagination({ listSize: data.length, pageSize: 2 });\n * const currentPageData = getOffsetPaginatedSlice(data, pagination);\n * // Returns: ['a', 'b'] for page 1, ['c', 'd'] for page 2, etc.\n * ```\n */\nfunction getOffsetPaginatedSlice<T>(\n\tlist: readonly T[],\n\tpagination: OffsetPaginationState,\n): T[] {\n\treturn list.slice(pagination.offset, pagination.offset + pagination.pageSize);\n}\n\nexport {\n\t//,\n\tgetOffsetPaginatedSlice,\n\tuseOffsetPagination,\n};\n\nexport type {\n\t//,\n\tOffsetPaginationState,\n\tUseOffsetPaginationProps,\n};\n"],"mappings":"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","names":["CaretLeftIcon","CaretRightIcon","Slot","createContext","forwardRef","useContext","useState","invariant","jsx","jsxs","CursorPaginationContext","createContext","Root","forwardRef","className","children","defaultPageSize","props","ref","pageSize","setPageSize","useState","cx","Buttons","hasNextPage","hasPreviousPage","onNextPage","onPreviousPage","ButtonGroup","IconButton","CaretLeftIcon","Separator","CaretRightIcon","defaultPageSizes","PageSizeSelect","pageSizes","onChangePageSize","rest","ctx","useContext","invariant","Select","value","newPageSize","size","PageSizeValue","asChild","Slot","CursorPagination","useEffect","useState","useOffsetPagination","listSize","pageSize","currentPage","setCurrentPage","currentPageSize","setCurrentPageSize","totalPages","offset","hasPreviousPage","hasNextPage","goToPage","page","nextPage","prev","previousPage","setPageSize","size","goToLastPage","goToFirstPage","getOffsetPaginatedSlice","list","pagination"]}
package/dist/popover.d.ts CHANGED
@@ -3,120 +3,142 @@ import * as PopoverPrimitive from '@radix-ui/react-popover';
3
3
 
4
4
  /**
5
5
  * A floating overlay that displays rich content in a portal, triggered by a button.
6
- * This is the root, stateful component that manages the open/closed state of the popover.
7
6
  *
8
- * @see https://mantle.ngrok.com/components/popover#api-popover
7
+ * @see https://mantle.ngrok.com/components/popover
9
8
  *
10
9
  * @example
11
10
  * ```tsx
12
- * <Popover>
13
- * <PopoverTrigger asChild>
11
+ * <Popover.Root>
12
+ * <Popover.Trigger asChild>
14
13
  * <Button type="button" appearance="outlined">
15
14
  * Open Popover
16
15
  * </Button>
17
- * </PopoverTrigger>
18
- * <PopoverContent>
16
+ * </Popover.Trigger>
17
+ * <Popover.Content>
19
18
  * <p>This is the popover content.</p>
20
- * </PopoverContent>
21
- * </Popover>
19
+ * </Popover.Content>
20
+ * </Popover.Root>
22
21
  * ```
23
22
  */
24
- declare const Popover: react.FC<PopoverPrimitive.PopoverProps>;
25
- /**
26
- * The trigger button that opens the popover.
27
- *
28
- * @see https://mantle.ngrok.com/components/popover#api-popover-trigger
29
- *
30
- * @example
31
- * ```tsx
32
- * <Popover>
33
- * <PopoverTrigger asChild>
34
- * <Button type="button" appearance="outlined">
35
- * Open Popover
36
- * </Button>
37
- * </PopoverTrigger>
38
- * <PopoverContent>
39
- * <p>This is the popover content.</p>
40
- * </PopoverContent>
41
- * </Popover>
42
- * ```
43
- */
44
- declare const PopoverTrigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
45
- /**
46
- * An optional element to position the PopoverContent against. If this part is not used, the content will position alongside the PopoverTrigger.
47
- *
48
- * @see https://mantle.ngrok.com/components/popover#api-popover-anchor
49
- *
50
- * @example
51
- * ```tsx
52
- * <Popover>
53
- * <PopoverTrigger asChild>
54
- * <Button type="button" appearance="outlined">
55
- * Open Popover
56
- * </Button>
57
- * </PopoverTrigger>
58
- * <PopoverAnchor asChild>
59
- * <div>Anchor element</div>
60
- * </PopoverAnchor>
61
- * <PopoverContent>
62
- * <p>This is the popover content.</p>
63
- * </PopoverContent>
64
- * </Popover>
65
- * ```
66
- */
67
- declare const PopoverAnchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
68
- /**
69
- * A button that closes an open popover.
70
- *
71
- * @see https://mantle.ngrok.com/components/popover#api-popover-close
72
- *
73
- * @example
74
- * ```tsx
75
- * <Popover>
76
- * <PopoverTrigger asChild>
77
- * <Button type="button" appearance="outlined">
78
- * Open Popover
79
- * </Button>
80
- * </PopoverTrigger>
81
- * <PopoverContent>
82
- * <p>This is the popover content.</p>
83
- * <PopoverClose asChild>
84
- * <Button type="button">Close</Button>
85
- * </PopoverClose>
86
- * </PopoverContent>
87
- * </Popover>
88
- * ```
89
- */
90
- declare const PopoverClose: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
91
- /**
92
- * The content to render inside the popover.
93
- *
94
- * @see https://mantle.ngrok.com/components/popover#api-popover-content
95
- *
96
- * @example
97
- * ```tsx
98
- * <Popover>
99
- * <PopoverTrigger asChild>
100
- * <Button type="button" appearance="outlined">
101
- * Open Popover
102
- * </Button>
103
- * </PopoverTrigger>
104
- * <PopoverContent>
105
- * <p>This is the popover content.</p>
106
- * </PopoverContent>
107
- * </Popover>
108
- * ```
109
- */
110
- declare const PopoverContent: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
23
+ declare const Popover: {
24
+ /**
25
+ * The root, stateful component that manages the open/closed state of the popover.
26
+ *
27
+ * @see https://mantle.ngrok.com/components/popover#api-popover
28
+ *
29
+ * @example
30
+ * ```tsx
31
+ * <Popover.Root>
32
+ * <Popover.Trigger asChild>
33
+ * <Button>Open popover</Button>
34
+ * </Popover.Trigger>
35
+ * <Popover.Content>
36
+ * <p>This is the popover content.</p>
37
+ * </Popover.Content>
38
+ * </Popover.Root>
39
+ * ```
40
+ */
41
+ readonly Root: react.FC<PopoverPrimitive.PopoverProps>;
42
+ /**
43
+ * An optional element to position the PopoverContent against. If not used, content positions alongside the trigger.
44
+ *
45
+ * @see https://mantle.ngrok.com/components/popover#api-popover-anchor
46
+ *
47
+ * @example
48
+ * ```tsx
49
+ * <Popover.Root>
50
+ * <Popover.Anchor asChild>
51
+ * <div>Position relative to this element</div>
52
+ * </Popover.Anchor>
53
+ * <Popover.Trigger asChild>
54
+ * <Button type="button">Open Popover</Button>
55
+ * </Popover.Trigger>
56
+ * <Popover.Content>
57
+ * <Text>This popover is positioned relative to the anchor.</Text>
58
+ * </Popover.Content>
59
+ * </Popover.Root>
60
+ * ```
61
+ */
62
+ readonly Anchor: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverAnchorProps & react.RefAttributes<HTMLDivElement>>;
63
+ /**
64
+ * A button that closes an open popover. Can be placed anywhere within the popover content.
65
+ *
66
+ * @see https://mantle.ngrok.com/components/popover#api-popover-close
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * <Popover.Root>
71
+ * <Popover.Trigger asChild>
72
+ * <Button type="button">Settings</Button>
73
+ * </Popover.Trigger>
74
+ * <Popover.Content>
75
+ * <div className="flex items-center justify-between">
76
+ * <Text>Settings Panel</Text>
77
+ * <Popover.Close asChild>
78
+ * <Button type="button" appearance="ghost" size="sm">✕</Button>
79
+ * </Popover.Close>
80
+ * </div>
81
+ * <Text>Configure your preferences here.</Text>
82
+ * </Popover.Content>
83
+ * </Popover.Root>
84
+ * ```
85
+ */
86
+ readonly Close: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverCloseProps & react.RefAttributes<HTMLButtonElement>>;
87
+ /**
88
+ * The content to render inside the popover. Appears in a portal with rich styling and animations.
89
+ *
90
+ * @see https://mantle.ngrok.com/components/popover#api-popover-content
91
+ *
92
+ * @example
93
+ * ```tsx
94
+ * <Popover.Root>
95
+ * <Popover.Trigger asChild>
96
+ * <Button type="button">Show Info</Button>
97
+ * </Popover.Trigger>
98
+ * <Popover.Content side="top" align="center">
99
+ * <div className="space-y-2">
100
+ * <Text weight="strong">Additional Information</Text>
101
+ * <Text>This is the content inside the popover.</Text>
102
+ * <Button type="button" size="sm">Action</Button>
103
+ * </div>
104
+ * </Popover.Content>
105
+ * </Popover.Root>
106
+ * ```
107
+ */
108
+ readonly Content: react.ForwardRefExoticComponent<Omit<PopoverPrimitive.PopoverContentProps & react.RefAttributes<HTMLDivElement>, "ref"> & {
109
+ /**
110
+ * The preferred width of the `PopoverContent` as a tailwind `max-w-` class.
111
+ *
112
+ * By default, a `Popover`'s content width is responsive with a default
113
+ * preferred width: the maximum width of the `PopoverContent`
114
+ *
115
+ * @default `max-w-72`
116
+ */
117
+ preferredWidth?: `max-w-${string}`;
118
+ } & react.RefAttributes<HTMLDivElement>>;
111
119
  /**
112
- * The preferred width of the `PopoverContent` as a tailwind `max-w-` class.
120
+ * The trigger button that opens the popover when clicked or focused.
113
121
  *
114
- * By default, a `Popover`'s content width is responsive with a default
115
- * preferred width: the maximum width of the `PopoverContent`
122
+ * @see https://mantle.ngrok.com/components/popover#api-popover-trigger
116
123
  *
117
- * @default `max-w-72`
124
+ * @example
125
+ * ```tsx
126
+ * <Popover.Root>
127
+ * <Popover.Trigger asChild>
128
+ * <Button type="button" appearance="outlined">
129
+ * Options
130
+ * </Button>
131
+ * </Popover.Trigger>
132
+ * <Popover.Content>
133
+ * <div className="space-y-2">
134
+ * <Button type="button" variant="ghost">Edit</Button>
135
+ * <Button type="button" variant="ghost">Delete</Button>
136
+ * </div>
137
+ * </Popover.Content>
138
+ * </Popover.Root>
139
+ * ```
118
140
  */
119
- preferredWidth?: `max-w-${string}`;
120
- } & react.RefAttributes<HTMLDivElement>>;
141
+ readonly Trigger: react.ForwardRefExoticComponent<PopoverPrimitive.PopoverTriggerProps & react.RefAttributes<HTMLButtonElement>>;
142
+ };
121
143
 
122
- export { Popover, PopoverAnchor, PopoverClose, PopoverContent, PopoverTrigger };
144
+ export { Popover };
package/dist/popover.js CHANGED
@@ -1,2 +1,2 @@
1
- import{a as t}from"./chunk-AZ56JGNY.js";import*as o from"@radix-ui/react-popover";import{forwardRef as C}from"react";import{jsx as r}from"react/jsx-runtime";var i=o.Root;i.displayName="Popover";var p=o.Trigger;p.displayName="PopoverTrigger";var a=o.Anchor;a.displayName="PopoverAnchor";var n=o.Close;n.displayName="PopoverClose";var s=C(({align:P="center",className:d,onClick:m,preferredWidth:v="max-w-72",sideOffset:f=4,...l},c)=>r(o.Portal,{children:r(o.Content,{align:P,className:t("text-popover-foreground border-popover bg-popover data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95 z-50 rounded-md border p-4 shadow-md outline-none",v,d),onClick:e=>{e.stopPropagation(),m?.(e)},ref:c,sideOffset:f,...l})}));s.displayName="PopoverContent";export{i as Popover,a as PopoverAnchor,n as PopoverClose,s as PopoverContent,p as PopoverTrigger};
1
+ import{a as t}from"./chunk-AZ56JGNY.js";import*as o from"@radix-ui/react-popover";import{forwardRef as C}from"react";import{jsx as r}from"react/jsx-runtime";var i=o.Root;i.displayName="Popover";var a=o.Trigger;a.displayName="PopoverTrigger";var p=o.Anchor;p.displayName="PopoverAnchor";var n=o.Close;n.displayName="PopoverClose";var s=C(({align:d="center",className:m,onClick:P,preferredWidth:v="max-w-72",sideOffset:f=4,...l},c)=>r(o.Portal,{children:r(o.Content,{align:d,className:t("text-popover-foreground border-popover bg-popover data-side-bottom:slide-in-from-top-2 data-side-left:slide-in-from-right-2 data-side-right:slide-in-from-left-2 data-side-top:slide-in-from-bottom-2 data-state-closed:animate-out data-state-closed:fade-out-0 data-state-closed:zoom-out-95 data-state-open:animate-in data-state-open:fade-in-0 data-state-open:zoom-in-95 z-50 rounded-md border p-4 shadow-md outline-none",v,m),onClick:e=>{e.stopPropagation(),P?.(e)},ref:c,sideOffset:f,...l})}));s.displayName="PopoverContent";var g={Root:i,Anchor:p,Close:n,Content:s,Trigger:a};export{g as Popover};
2
2
  //# sourceMappingURL=popover.js.map