生态产品多个设计器现已发布候选版本

查看生态总览
Skip to content

ImageViewer ​

Data display component. This page is the API reference, generated from the source code. Usage guidance and live examples are on the Chinese page.

Anatomy ​

Parts in bold are required.

data-scope="image-viewer": trigger · backdrop · positioner · content · viewport · image · toolbar · zoom-in-trigger · zoom-out-trigger · rotate-left-trigger · rotate-right-trigger · flip-horizontal-trigger · flip-vertical-trigger · reset-trigger · prev-trigger · next-trigger · counter · close-trigger

API reference ​

Descriptions of individual props, events and slots are written in Chinese and appear on the Chinese page.

Artifacts ​

LayerValue
Custom element<xh-image-viewer>
Vue componentsXhImageViewerCloseTrigger XhImageViewerContent XhImageViewerCounter XhImageViewerFlipHorizontalTrigger XhImageViewerFlipVerticalTrigger XhImageViewerImage XhImageViewerNextTrigger XhImageViewerPrevTrigger XhImageViewerResetTrigger XhImageViewerRoot XhImageViewerRotateLeftTrigger XhImageViewerRotateRightTrigger XhImageViewerToolbar XhImageViewerTrigger XhImageViewerViewport XhImageViewerZoomInTrigger XhImageViewerZoomOutTrigger
ComposableuseImageViewer
State machineimageViewerMachine
Skin@xihan-ui/styles/image-viewer.css

Props ​

PropTypeRequired
collectionImageViewerItem[]
openboolean
defaultOpenboolean
indexnumber
defaultIndexnumber
loopboolean
zoomStepnumber
minScalenumber
maxScalenumber
closeOnEscapeboolean
closeOnInteractOutsideboolean
restoreFocusboolean
variantOverlayBackdropVariant
sizeSize
translationsPartial<ImageViewerTranslations>
onOpenChange(details: ImageViewerOpenChangeDetails) => void
onIndexChange(details: ImageViewerIndexChangeDetails) => void

ImageViewerItem ​

Elements of collection.

FieldTypeRequired
srcstringYes
altstring

Events ​

Custom elements put the payload in detail; Vue emits an event of the same name.

EventPayload
open-changeImageViewerOpenChangeDetails
index-changeImageViewerIndexChangeDetails

Slots ​

Only slots with a payload are listed.

Vue componentSlotPayload
XhImageViewerRootdefaultImageViewerRootSlotProps

React adapter props ​

Only the props each component declares itself: DOM attributes inherited from ComponentPropsWithRef are left out, and root props already listed in the Props table are not repeated. The Vue counterpart is the slot table above.

React componentPropTypeRequired
XhImageViewerContentcontainer() => Element | null
XhImageViewerRootchildrenSlotChildren<ImageViewerRootSlotProps>

State ​

Public state is written to data-state.

PartValues
trigger'open' | 'closed'
backdrop'open' | 'closed'
positioner'open' | 'closed'
content'open' | 'closed'
viewport'open' | 'closed'
image'open' | 'closed'
toolbar'open' | 'closed'
counter'open' | 'closed'

The following names are internal to the state machine.

States: open · closed

Events: OPEN · CLOSE · INDEX.SET · INDEX.NEXT · INDEX.PREV · ZOOM.BY · ZOOM.SET · ROTATE.BY · FLIP · TRANSFORM.RESET · IMAGE.LOAD · IMAGE.ERROR · PAN.MOVE · POINTERS.DOWN · POINTERS.CHANGE · POINTERS.END · PAN.END · CONTROLLED.OPEN · CONTROLLED.CLOSE · PRESS.START · PRESS.END

Guards: isOpenControlled · canPress

connect API ​

getXxxProps() returns the host attributes of the matching part.

MemberType
openboolean
indexnumber
countnumber
currentItemImageViewerItem | null
transformImageViewerTransform
panningboolean
imageStatusImageViewerImageStatus
canPrevboolean
canNextboolean
setOpen(next: boolean) => void
setIndex(next: number) => void
next() => void
prev() => void
zoomIn() => void
zoomOut() => void
setScale(scale: number) => void
rotateLeft() => void
rotateRight() => void
flipHorizontal() => void
flipVertical() => void
reset() => void
getTriggerProps() => T['button']
getBackdropProps() => T['element']
getPositionerProps() => T['element']
getContentProps() => T['element']
getViewportProps() => T['element']
getImageProps() => T['img']
getToolbarProps() => T['element']
getZoomInTriggerProps() => T['button']
getZoomOutTriggerProps() => T['button']
getRotateLeftTriggerProps() => T['button']
getRotateRightTriggerProps() => T['button']
getFlipHorizontalTriggerProps() => T['button']
getFlipVerticalTriggerProps() => T['button']
getResetTriggerProps() => T['button']
getPrevTriggerProps() => T['button']
getNextTriggerProps() => T['button']
getCounterProps() => T['element']
getCloseTriggerProps() => T['button']

Accessibility ​

Keyboard ​

Specification: W3C APG. Each row is a stable behavior id that the conformance tests cover; the conditions and effects are described on the Chinese page.

KeysBehavior
Enter / Spaceimage-viewer.kbd.open-on-trigger
Escapeimage-viewer.kbd.escape
Tabimage-viewer.kbd.tab
Shift+Tabimage-viewer.kbd.shift-tab
ArrowLeftimage-viewer.kbd.prev
ArrowRightimage-viewer.kbd.next
Homeimage-viewer.kbd.first
Endimage-viewer.kbd.last
+ / =image-viewer.kbd.zoom-in
-image-viewer.kbd.zoom-out
0image-viewer.kbd.reset
Enter / Spaceimage-viewer.kbd.press

ARIA ​

These attributes are produced by connect.

PartAttributeValue
triggeraria-controlsid of the content part
triggeraria-expanded'true' | 'false'
triggeraria-haspopup'dialog'
backdroparia-hidden'true'
contentaria-hidden!open || undefined
contentaria-labelcurrentItem?.alt
contentaria-modal'true'
contentrole'dialog'
viewportaria-busyimageStatus === 'loading' || undefined
toolbararia-labellabel.toolbar
toolbarrole'group'
counteraria-live'polite'

Style reference ​

Skin ​

@xihan-ui/styles/image-viewer.css is written against [data-scope="image-viewer"][data-part="trigger"] part selectors; the published build uses the mount class .xh-scope-image-viewer in place of data-scope (same specificity) and sits in the xihan.components layer. Put overrides in xihan.overrides; the part selectors work as usual.

Data attributes ​

Produced by connect; valueless attributes are omitted while their condition does not hold.

PartAttributeValue
triggerdata-state'open' | 'closed'
backdropdata-instant'' (present only while the condition holds)
backdropdata-state'open' | 'closed'
backdropdata-variantprops.variant
positionerdata-positioned''
positionerdata-state'open' | 'closed'
positionerdata-xh-backdropundefined | 'dark'
contentdata-instant'' (present only while the condition holds)
contentdata-state'open' | 'closed'
contentdata-xh-ink'light'
viewportdata-dragging'' (present only while the condition holds)
viewportdata-error'' (present only while the condition holds)
viewportdata-loading'' (present only while the condition holds)
viewportdata-state'open' | 'closed'
viewportdata-xh-loading-ring''
imagedata-animating'' (present only while the condition holds)
imagedata-dragging'' (present only while the condition holds)
imagedata-error'' (present only while the condition holds)
imagedata-loading'' (present only while the condition holds)
imagedata-state'open' | 'closed'
toolbardata-state'open' | 'closed'
toolbardata-xh-ink-surface''
toolbardata-xh-liquid''
zoom-in-triggerdata-pressed'' (present only while the condition holds)
zoom-in-triggerdata-xh-action-control''
zoom-in-triggerdata-xh-action-display'always'
zoom-in-triggerdata-xh-action-profile'icon'
zoom-in-triggerdata-xh-action-size'xs'
zoom-out-triggerdata-pressed'' (present only while the condition holds)
zoom-out-triggerdata-xh-action-control''
zoom-out-triggerdata-xh-action-display'always'
zoom-out-triggerdata-xh-action-profile'icon'
zoom-out-triggerdata-xh-action-size'xs'
rotate-left-triggerdata-pressed'' (present only while the condition holds)
rotate-left-triggerdata-xh-action-control''
rotate-left-triggerdata-xh-action-display'always'
rotate-left-triggerdata-xh-action-profile'icon'
rotate-left-triggerdata-xh-action-size'xs'
rotate-right-triggerdata-pressed'' (present only while the condition holds)
rotate-right-triggerdata-xh-action-control''
rotate-right-triggerdata-xh-action-display'always'
rotate-right-triggerdata-xh-action-profile'icon'
rotate-right-triggerdata-xh-action-size'xs'
flip-horizontal-triggerdata-pressed'' (present only while the condition holds)
flip-horizontal-triggerdata-xh-action-control''
flip-horizontal-triggerdata-xh-action-display'always'
flip-horizontal-triggerdata-xh-action-profile'icon'
flip-horizontal-triggerdata-xh-action-size'xs'
flip-vertical-triggerdata-pressed'' (present only while the condition holds)
flip-vertical-triggerdata-xh-action-control''
flip-vertical-triggerdata-xh-action-display'always'
flip-vertical-triggerdata-xh-action-profile'icon'
flip-vertical-triggerdata-xh-action-size'xs'
reset-triggerdata-pressed'' (present only while the condition holds)
reset-triggerdata-xh-action-control''
reset-triggerdata-xh-action-display'always'
reset-triggerdata-xh-action-profile'icon'
reset-triggerdata-xh-action-size'xs'
prev-triggerdata-pressed'' (present only while the condition holds)
prev-triggerdata-xh-action-control''
prev-triggerdata-xh-action-display'always'
prev-triggerdata-xh-action-profile'floating'
prev-triggerdata-xh-action-sizeprops.size
prev-triggerdata-xh-liquid''
next-triggerdata-pressed'' (present only while the condition holds)
next-triggerdata-xh-action-control''
next-triggerdata-xh-action-display'always'
next-triggerdata-xh-action-profile'floating'
next-triggerdata-xh-action-sizeprops.size
next-triggerdata-xh-liquid''
counterdata-countString(count)
counterdata-indexString(index + 1)
counterdata-state'open' | 'closed'
counterdata-xh-liquid''
close-triggerdata-pressed'' (present only while the condition holds)
close-triggerdata-xh-action-control''
close-triggerdata-xh-action-display'always'
close-triggerdata-xh-action-profile'floating'
close-triggerdata-xh-action-sizeprops.size
close-triggerdata-xh-liquid''

CSS variables ​

The public override slots, generated from what the standalone skin actually consumes.

VariablePartCSS propertyStateDefault from
--xh-image-viewer-action-bg-activeclose-trigger
content
next-trigger
prev-trigger
toolbar
background-colordisabled
is(:active, [data-pressed])
loading
material=liquid
not([data-disabled])
not([data-loading])
pressed
where([data-material='liquid'])
xh-liquid
--xh-_liquid-bg-pressed
--xh-bg-media-chrome-active
--xh-bg-subtle-hover
--xh-image-viewer-action-bg-hoverclose-trigger
content
next-trigger
prev-trigger
toolbar
background-colordisabled
hover
loading
material=liquid
not([data-disabled])
not([data-loading])
where([data-material='liquid'])
xh-liquid
--xh-_liquid-bg-hover
--xh-bg-media-chrome-hover
--xh-bg-subtle
--xh-image-viewer-backdrop-bgbackdropbackgrounddefault--xh-bg-overlay
--xh-image-viewer-backdrop-blurbackdrop-webkit-backdrop-filter
backdrop-filter
variant=blur--xh-overlay-backdrop-blur
--xh-image-viewer-backdrop-layerbackdropz-indexdefault--xh-_layer
--xh-image-viewer-chrome-bgclose-trigger
content
counter
next-trigger
prev-trigger
toolbar
--xh-ink-surface
background
background-color
default
disabled
focus-visible
material=liquid
where([data-material='liquid'])
xh-ink-surface
xh-liquid
--xh-_liquid-bg
--xh-bg-media-chrome
--xh-material-liquid-focus-surface
--xh-image-viewer-close-bg-activeclose-triggerbackground-colordisabled
is(:active, [data-pressed])
loading
material=liquid
not([data-disabled])
not([data-loading])
pressed
where([data-material='liquid'])
xh-liquid
--xh-_image-viewer-chrome-bg-active
--xh-_liquid-bg-pressed
--xh-image-viewer-close-bg-hoverclose-triggerbackground-colordisabled
hover
loading
material=liquid
not([data-disabled])
not([data-loading])
where([data-material='liquid'])
xh-liquid
--xh-_image-viewer-chrome-bg-hover
--xh-_liquid-bg-hover
--xh-image-viewer-close-fgclose-triggercolordefault
disabled
focus-visible
hover
is(:active, [data-pressed])
loading
material=liquid
not([data-disabled])
not([data-loading])
pressed
where([data-material='liquid'])
xh-liquid
--xh-material-liquid-fg
currentColor
--xh-image-viewer-close-radiusclose-triggerborder-radiusdefault
material=liquid
where([data-material='liquid'])
xh-liquid
--xh-shape-circle
--xh-image-viewer-close-sizeclose-triggerblock-size
inline-size
min-inline-size
default
xh-action-profile=floating
xh-action-profile=icon
--xh-_image-viewer-nav-size
--xh-image-viewer-counter-paddingcounterpaddingdefault--xh-space-1
--xh-image-viewer-counter-radiuscounterborder-radiusdefault
material=liquid
where([data-material='liquid'])
xh-liquid
--xh-image-viewer-overlay-radius
--xh-image-viewer-error-fgviewportbackground-colorerror--xh-fg-danger
--xh-image-viewer-fgcontentcolordefault--xh-fg-on-media-chrome
--xh-image-viewer-icon-sizeclose-trigger
content
next-trigger
prev-trigger
toolbar
--xh-icon-sizedefault--xh-_action-profile-glyph-size
--xh-_image-viewer-nav-glyph
--xh-glyph-size-md
--xh-image-viewer-layerpositionerz-indexdefault--xh-_layer
--xh-image-viewer-nav-sizenext-trigger
prev-trigger
block-size
inline-size
min-inline-size
default
xh-action-profile=floating
xh-action-profile=icon
--xh-_image-viewer-nav-size
--xh-image-viewer-overlay-radiuscounter
next-trigger
prev-trigger
toolbar
border-radiusdefault
material=liquid
where([data-material='liquid'])
xh-liquid
--xh-_action-profile-radius
--xh-shape-control
--xh-shape-pill
--xh-shape-surface
--xh-image-viewer-status-sizeviewport--xh-icon-sizedefault--xh-glyph-size-lg
--xh-image-viewer-toolbar-bgtoolbar--xh-ink-surface
background
default--xh-_image-viewer-page-surface
--xh-image-viewer-toolbar-gaptoolbargapdefault--xh-space-1
--xh-image-viewer-toolbar-paddingtoolbarpaddingdefault--xh-space-1_5
--xh-image-viewer-toolbar-radiustoolbarborder-radiusdefault--xh-_action-profile-radius
--xh-image-viewer-toolbar-radius-outertoolbarborder-radiusdefault
material=liquid
where([data-material='liquid'])
xh-liquid
--xh-image-viewer-overlay-radius

Released under The MIT License