@lateralus-ai/shipping-ui 1.4.10 → 1.4.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lateralus-ai/shipping-ui",
3
- "version": "1.4.10",
3
+ "version": "1.4.12",
4
4
  "description": "Shared UI theme and components for Lateralus shipping applications",
5
5
  "main": "dist/index.cjs",
6
6
  "module": "dist/index.esm.js",
@@ -14,6 +14,7 @@ interface ImageViewerProps {
14
14
  canvasClassName?: string
15
15
  documentUrl?: string
16
16
  mainCanvasClassname?: string
17
+ initialPage?: number
17
18
  onClose: () => void
18
19
  totalPages: number
19
20
  getImageSrc: (page: number) => string | Promise<string>
@@ -24,6 +25,7 @@ export const ImageViewer = ({
24
25
  className,
25
26
  canvasClassName,
26
27
  mainCanvasClassname,
28
+ initialPage = 1,
27
29
  onClose,
28
30
  totalPages,
29
31
  getImageSrc,
@@ -33,7 +35,10 @@ export const ImageViewer = ({
33
35
  const [zoom, zoomActions] = useZoom()
34
36
  const [rotation, rotationActions] = useRotation()
35
37
  const [{ pan, isDragging }, panActions] = usePanning()
36
- const [{ currentPage }, pageActions] = usePageManagement(totalPages)
38
+ const [{ currentPage }, pageActions] = usePageManagement(
39
+ totalPages,
40
+ initialPage
41
+ )
37
42
  const [imageSrc, setImageSrc] = useState<string>(() => {
38
43
  const initialResult = getImageSrc(currentPage)
39
44
  return typeof initialResult === "string" ? initialResult : ""
@@ -73,10 +73,10 @@ export const PdfViewer = ({
73
73
  {title}
74
74
  </ModalPanel.Header>
75
75
 
76
- <div className="grid grow h-full overflow-hidden">
76
+ <div className="grid grow h-full overflow-hidden shadow">
77
77
  <div
78
78
  className={cn(
79
- "col-start-1 row-start-1 bg-gray-200 h-full overflow-hidden select-none p-8 flex justify-center items-center",
79
+ "col-start-1 row-start-1 bg-gray-200 h-full overflow-hidden select-none p-8 flex justify-center items-center mt-8",
80
80
  isDragging ? "cursor-grabbing" : "cursor-grab"
81
81
  )}
82
82
  onMouseDown={panActions.handleMouseDown}
@@ -114,67 +114,19 @@ export const PdfViewer = ({
114
114
  </div>
115
115
  </div>
116
116
 
117
- <div className="col-start-1 row-start-1 self-end p-4 flex gap-2 justify-between w-full z-10">
118
- <ButtonGroup className="divide-x-0 h-[52px]">
117
+ <div className="col-start-1 row-start-1 self-start flex justify-between w-full z-10 flex-wrap items-center gap-3 bg-gray-50 p-2 shadow">
118
+ <ButtonGroup className="divide-x-1 gap-1">
119
119
  <IconButton
120
120
  variant="filled"
121
121
  color="white"
122
- className="py-[26px]"
123
- onClick={zoomActions.zoomOut}
124
- >
125
- <Icon icon="lucide:minus" />
126
- </IconButton>
127
- <Tooltip content="Click to reset zoom and pan">
128
- <button
129
- className="!bg-white text-center cursor-pointer w-[60px]"
130
- onClick={() => {
131
- zoomActions.reset()
132
- panActions.reset()
133
- }}
134
- >
135
- {zoom}%
136
- </button>
137
- </Tooltip>
138
- <IconButton
139
- variant="filled"
140
- color="white"
141
- className="py-[26px]"
142
- onClick={zoomActions.zoomIn}
143
- >
144
- <Icon icon="lucide:plus" />
145
- </IconButton>
146
- </ButtonGroup>
147
- <ButtonGroup className="divide-x-0 h-[52px]">
148
- <IconButton
149
- variant="filled"
150
- color="white"
151
- className="py-[26px]"
152
- onClick={rotationActions.rotateClockwise}
153
- >
154
- <Icon icon="lucide:iteration-cw" />
155
- </IconButton>
156
-
157
- <IconButton
158
- variant="filled"
159
- color="white"
160
- className="py-[26px]"
161
- onClick={rotationActions.rotateCounterClockwise}
162
- >
163
- <Icon icon="lucide:iteration-ccw" />
164
- </IconButton>
165
- </ButtonGroup>
166
- <ButtonGroup className="divide-x-0 ">
167
- <IconButton
168
- variant="filled"
169
- color="white"
170
- className="py-[26px]"
122
+ className="w-8 h-8 rounded border border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
171
123
  onClick={pageActions.prevPage}
172
124
  disabled={currentPage === 1}
173
125
  >
174
126
  <Icon icon="lucide:chevron-left" />
175
127
  </IconButton>
176
128
  <input
177
- className="bg-white pl-4 flex items-center w-[50px] text-center focus:outline-none w-[60px]"
129
+ className="w-14 h-8 rounded border !border-gray-300 bg-white px-1 py-1 text-center text-sm text-gray-700 dark:border-gray-600 dark:bg-gray-700 dark:text-white"
178
130
  value={currentPage}
179
131
  onChange={(e: ChangeEvent<HTMLInputElement>) => {
180
132
  const page = parseInt(e.target.value)
@@ -186,19 +138,70 @@ export const PdfViewer = ({
186
138
  min="1"
187
139
  max={totalPages}
188
140
  />
189
- <div className="flex items-center bg-white px-2">
141
+ <div className="flex items-center bg-transparent px-2">
190
142
  of {totalPages}
191
143
  </div>
192
144
  <IconButton
193
145
  variant="filled"
194
146
  color="white"
195
- className="py-[26px]"
147
+ className="w-8 h-8 rounded border !border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
196
148
  onClick={pageActions.nextPage}
197
149
  disabled={currentPage === totalPages}
198
150
  >
199
151
  <Icon icon="lucide:chevron-right" />
200
152
  </IconButton>
201
153
  </ButtonGroup>
154
+ <div className="flex gap-2 items-center">
155
+ <ButtonGroup className="divide-x-1 gap-1">
156
+ <IconButton
157
+ variant="filled"
158
+ color="white"
159
+ className="w-8 h-8 rounded border !border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
160
+ onClick={zoomActions.zoomOut}
161
+ >
162
+ <Icon icon="lucide:minus" />
163
+ </IconButton>
164
+ <Tooltip content="Click to reset zoom and pan">
165
+ <button
166
+ className="w-14 h-8 rounded border !border-gray-300 bg-white px-1 py-1 text-center text-sm text-gray-700 dark:border-gray-600 dark:bg-gray-700 dark:text-white"
167
+ onClick={() => {
168
+ zoomActions.reset()
169
+ panActions.reset()
170
+ }}
171
+ >
172
+ {zoom}%
173
+ </button>
174
+ </Tooltip>
175
+ <IconButton
176
+ variant="filled"
177
+ color="white"
178
+ className="w-8 h-8 rounded border !border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
179
+ onClick={zoomActions.zoomIn}
180
+ >
181
+ <Icon icon="lucide:plus" />
182
+ </IconButton>
183
+ </ButtonGroup>
184
+ <div className="h-6 w-px bg-gray-300 dark:bg-gray-600"></div>
185
+ <ButtonGroup className="divide-x-1 gap-1">
186
+ {/* <IconButton
187
+ variant="filled"
188
+ color="white"
189
+ className="w-8 h-8 rounded border !border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
190
+ onClick={rotationActions.rotateClockwise}
191
+ >
192
+ <Icon icon="lucide:iteration-cw" />
193
+ </IconButton> */}
194
+
195
+ <IconButton
196
+ variant="filled"
197
+ color="white"
198
+ className="w-8 h-8 rounded border !border-gray-300 bg-white p-2 text-gray-700 hover:bg-gray-200 disabled:opacity-50 dark:border-gray-600 dark:bg-gray-700 dark:text-white dark:hover:bg-gray-600 focus:outline-none max-w-auto"
199
+ onClick={rotationActions.rotateCounterClockwise}
200
+ >
201
+ <Icon icon="lucide:iteration-ccw" />
202
+ </IconButton>
203
+ </ButtonGroup>
204
+ </div>
202
205
  </div>
203
206
  </div>
204
207
  </div>
@@ -1,29 +1,32 @@
1
- import { useState, useCallback } from "react";
1
+ import { useState, useCallback } from "react"
2
2
 
3
- export const usePageManagement = (initialTotalPages: number = 0) => {
4
- const [currentPage, setCurrentPage] = useState<number>(1);
5
- const [totalPages, setTotalPages] = useState<number>(initialTotalPages);
3
+ export const usePageManagement = (
4
+ initialTotalPages: number = 0,
5
+ initialPage: number = 1
6
+ ) => {
7
+ const [currentPage, setCurrentPage] = useState<number>(initialPage)
8
+ const [totalPages, setTotalPages] = useState<number>(initialTotalPages)
6
9
 
7
10
  const actions = {
8
11
  nextPage: useCallback(() => {
9
12
  setCurrentPage((prev) => {
10
- return prev < totalPages ? prev + 1 : prev;
11
- });
13
+ return prev < totalPages ? prev + 1 : prev
14
+ })
12
15
  }, [totalPages]),
13
16
  prevPage: useCallback(() => {
14
- setCurrentPage((prev) => Math.max(prev - 1, 1));
17
+ setCurrentPage((prev) => Math.max(prev - 1, 1))
15
18
  }, []),
16
19
  goToPage: useCallback(
17
20
  (page: number) => {
18
- setCurrentPage(() => Math.max(1, Math.min(page, totalPages)));
21
+ setCurrentPage(() => Math.max(1, Math.min(page, totalPages)))
19
22
  },
20
- [totalPages],
23
+ [totalPages]
21
24
  ),
22
25
  setTotalPages: useCallback((pages: number) => {
23
- setTotalPages(pages);
24
- setCurrentPage((prev) => Math.min(prev, pages));
26
+ setTotalPages(pages)
27
+ setCurrentPage((prev) => Math.min(prev, pages))
25
28
  }, []),
26
- };
29
+ }
27
30
 
28
- return [{ currentPage, totalPages }, actions] as const;
29
- };
31
+ return [{ currentPage, totalPages }, actions] as const
32
+ }
@@ -7,6 +7,7 @@ const StoryPage = () => {
7
7
  <div className="w-[600px] h-[800px] p-8">
8
8
  <ImageViewer
9
9
  totalPages={100}
10
+ initialPage={10}
10
11
  mainCanvasClassname="max-h-[650px]"
11
12
  title="Image Viewer"
12
13
  getImageSrc={(page) =>