@boyernick/standard-ui-react 0.4.2-canary.69 → 0.4.2-canary.70

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 (2) hide show
  1. package/package.json +1 -1
  2. package/src/modal.tsx +10 -46
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@boyernick/standard-ui-react",
3
- "version": "0.4.2-canary.69",
3
+ "version": "0.4.2-canary.70",
4
4
  "description": "React components for StandardUI",
5
5
  "license": "MIT",
6
6
  "type": "module",
package/src/modal.tsx CHANGED
@@ -36,8 +36,6 @@ import {
36
36
  IconArrowDownSmall,
37
37
  IconChevronRightSmall,
38
38
  IconCrossSmall,
39
- IconZoomIn,
40
- IconZoomOut,
41
39
  } from "./icons"
42
40
  import { cn } from "./lib/cn"
43
41
  import { focusRing, focusRingBorder } from "./lib/focus"
@@ -89,10 +87,7 @@ export type ModalContentProps = Omit<
89
87
  downloadName?: string
90
88
  imgProps?: Omit<ImgHTMLAttributes<HTMLImageElement>, "src" | "alt">
91
89
  children?: ReactNode
92
- /**
93
- * Magnification when the image is clicked or the zoom control pressed.
94
- * `false` turns zoom off. Default 2.
95
- */
90
+ /** Magnification when the image is clicked. `false` turns zoom off. Default 2. */
96
91
  zoom?: number | false
97
92
  }
98
93
 
@@ -234,7 +229,10 @@ const ModalImage = ({
234
229
  ? "motion-safe:[transition:opacity_var(--duration-lg)_linear,scale_var(--duration-md)_var(--ease-move),translate_var(--duration-md)_var(--ease-move)] motion-safe:data-[panning]:[transition-property:opacity,scale]"
235
230
  : "transition-opacity duration-[var(--duration-lg)] ease-linear motion-reduce:transition-none",
236
231
  !loaded && "opacity-0",
237
- "rounded-lg object-contain shadow-lg select-none",
232
+ // Sized by the image itself: width and height attributes with
233
+ // separate max caps made a box of another shape, which object-contain
234
+ // letterboxed, leaving the rounded corners on empty space.
235
+ "h-auto w-auto rounded-lg object-contain shadow-lg select-none",
238
236
  // Scaled from the top-left, so the pan lands the image exactly where
239
237
  // it is measured.
240
238
  zoom && "origin-top-left",
@@ -325,34 +323,6 @@ const ModalDismiss = () => (
325
323
  </ModalControlTooltip>
326
324
  )
327
325
 
328
- const ModalZoom = ({
329
- zoomed,
330
- onToggle,
331
- }: {
332
- zoomed: boolean
333
- onToggle: () => void
334
- }) => (
335
- <ModalControlTooltip label={zoomed ? "Zoom out" : "Zoom in"}>
336
- <GlassButton
337
- type="button"
338
- config={mediaGlass}
339
- size="md"
340
- iconOnly
341
- rounded
342
- aria-label={zoomed ? "Zoom out" : "Zoom in"}
343
- aria-pressed={zoomed}
344
- onClick={onToggle}
345
- className={cn(
346
- modalControlClassName,
347
- // Beside Download: 16px inset, a 36px control and an 8px gap.
348
- "absolute top-4 left-15 z-20",
349
- )}
350
- >
351
- {zoomed ? <IconZoomOut aria-hidden /> : <IconZoomIn aria-hidden />}
352
- </GlassButton>
353
- </ModalControlTooltip>
354
- )
355
-
356
326
  const ModalCaption = ({ children, hidden }: { children: ReactNode; hidden?: boolean }) => (
357
327
  <p
358
328
  className={cn(
@@ -367,8 +337,8 @@ const ModalCaption = ({ children, hidden }: { children: ReactNode; hidden?: bool
367
337
  )
368
338
 
369
339
  /**
370
- * Zoom for one image: magnify at a point, then pan under the pointer. A
371
- * mouse or pen pans by moving; a finger drags the image.
340
+ * Zoom for one image: a click magnifies at the point, then the image pans
341
+ * under the pointer. A mouse or pen pans by moving; a finger drags.
372
342
  */
373
343
  function useImageZoom(scale: number | false) {
374
344
  const [zoomed, setZoomed] = useState(false)
@@ -378,22 +348,17 @@ function useImageZoom(scale: number | false) {
378
348
  const aim = useRef({ x: 0, y: 0 })
379
349
 
380
350
  const toggle = useCallback(
381
- (x?: number, y?: number) => {
351
+ (x: number, y: number) => {
382
352
  const image = imageRef.current
383
353
  const frame = frameRef.current
384
354
  if (!scale || !image || !frame) return
385
- const bounds = frame.getBoundingClientRect()
386
355
  // The zoom itself eases, towards the point.
387
356
  delete image.dataset.panning
388
357
  if (zoomed) {
389
358
  image.style.translate = "0px 0px"
390
359
  } else {
391
- // No point (the control): open on the middle.
392
- aim.current = {
393
- x: x ?? bounds.left + bounds.width / 2,
394
- y: y ?? bounds.top + bounds.height / 2,
395
- }
396
- panZoomedImage(image, bounds, aim.current.x, aim.current.y, scale)
360
+ aim.current = { x, y }
361
+ panZoomedImage(image, frame.getBoundingClientRect(), x, y, scale)
397
362
  }
398
363
  setZoomed(!zoomed)
399
364
  },
@@ -507,7 +472,6 @@ export const ModalContent = ({
507
472
  src={downloadSrc ?? src}
508
473
  name={downloadName}
509
474
  />
510
- {zoom ? <ModalZoom zoomed={zoomed} onToggle={() => toggle()} /> : null}
511
475
  </GlassRoot>
512
476
  </TooltipProvider>
513
477
  </DialogPopup>