Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 14 additions & 8 deletions packages/vue-component-library/src/lib-components/ImageSlider.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts" setup>
import { ref } from 'vue'
import { computed, ref } from 'vue'
import SvgIconCaretLeft from 'ucla-library-design-tokens/assets/svgs/icon-caret-left.svg'
import SvgIconCaretRight from 'ucla-library-design-tokens/assets/svgs/icon-caret-right.svg'

Expand All @@ -18,6 +18,13 @@ const sliderContainer = ref<HTMLElement | null>(null)
const slider = ref<HTMLInputElement | null>(null)
const beforeImageElement = ref<HTMLImageElement | null>(null)

// sets height of slider based on image aspect ratio
const parsedSliderAspectRatio = computed(() => {
// calculate aspect ratio
const aspectRatio = beforeImage?.width / beforeImage?.height
return `${aspectRatio}`
})

function handleSliderInput(event: Event) {
const target = event.target as HTMLInputElement
if (sliderContainer.value && slider.value && beforeImageElement.value)
Expand All @@ -26,8 +33,8 @@ function handleSliderInput(event: Event) {
</script>

<template>
<div ref="sliderContainer" class="image-slider">
<div class="image-container">
<div ref="sliderContainer" class="image-slider" :style="{ aspectRatio: parsedSliderAspectRatio }">
<div class="image-container" :style="{ aspectRatio: parsedSliderAspectRatio }">
<img class="after-image slider-image" :src="afterImage.src" :alt="afterImage.alt">
<img ref="beforeImageElement" class="before-image slider-image" :src="beforeImage.src" :alt="beforeImage.alt">
<div class="image-labels">
Expand Down Expand Up @@ -70,7 +77,7 @@ function handleSliderInput(event: Event) {
position: relative;
display: grid;
width: 100%;
height: 400px;
// height: 400px;
max-width: 1160px;
place-content: center;
position: relative;
Expand All @@ -79,14 +86,13 @@ function handleSliderInput(event: Event) {
.image-container {
width: 100%;
max-width: 1160px;
max-height: 90vh;
// max-height: 90vh;
overflow: hidden;
aspect-ratio: 2/1;
// aspect-ratio: 2/1;

:deep(img) {
display: block;
max-width: 100%;

}
}
}
Expand Down Expand Up @@ -116,7 +122,7 @@ function handleSliderInput(event: Event) {
resize: horizontal;
width: 100%;
height: 100%;
object-fit: cover;
// object-fit: cover;
object-position: center;
}

Expand Down
97 changes: 89 additions & 8 deletions packages/vue-component-library/src/stories/ImageSlider.stories.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,78 @@ export function Default() {
}
}

const mockSquareImage = [
{
id: '3280520',
src: 'https://static.library.ucla.edu/craftassetstest/_fullscreen/lostlake.jpeg',
height: 1500,
width: 1500,
srcset: 'https://static.library.ucla.edu/craftassetstest/_fullscreen/lostlake.jpeg',
alt: 'Lostlake',
focalPoint: [
0.5,
0.5
]
}
]

const mockSquareImageCarousel = [{
id: '37072',
caption: 'Before and After Image Slider caption #1',
beforeImage: mockSquareImage[0],
afterImage: mockSquareImage[0]
}]

const mockTallImage = [
{
id: '3280520',
src: 'https://static.library.ucla.edu/craftassetstest/FTVA/film-reel_4_18.jpg',
height: 350,
width: 250,
srcset: 'https://static.library.ucla.edu/craftassetstest/FTVA/_375xAUTO_crop_center-center_none/film-reel_4_18.jpg 375w, https://static.library.ucla.edu/craftassetstest/FTVA/_960xAUTO_crop_center-center_none/film-reel_4_18.jpg 960w, https://static.library.ucla.edu/craftassetstest/FTVA/_1280xAUTO_crop_center-center_none/film-reel_4_18.jpg 1280w, https://static.library.ucla.edu/craftassetstest/FTVA/_1920xAUTO_crop_center-center_none/film-reel_4_18.jpg 1920w, https://static.library.ucla.edu/craftassetstest/FTVA/_2560xAUTO_crop_center-center_none/film-reel_4_18.jpg 2560w',
alt: 'Lostlake',
focalPoint: [
0.5,
0.5
]
}
]

const mockTallImageCarousel = [{
id: '37072',
caption: 'Before and After Image Slider caption #1',
beforeImage: mockTallImage[0],
afterImage: mockTallImage[0]
}]

export function TallImage() {
return {
data() {
return {
...mockTallImageCarousel[0],
}
},
components: { ImageSlider },
template: `
<component is="style" type="text/css">
.before-image {
filter: grayscale(100%)
}
</component>
<div style="padding: 1rem; max-width: 1160px;">
<image-slider
:before-image="beforeImage"
:after-image="afterImage"
>
<template #captionText>
{{ caption }}
</template>
</image-slider>
</div>
`,
}
}

export function WithCustomLabels() {
return {
data() {
Expand Down Expand Up @@ -92,7 +164,9 @@ export function WithScrollWrapperCarousel() {
return {
data() {
return {
...mockBeforeAfterImageCarousel[0],
firstImage: mockBeforeAfterImageCarousel[0],
secondImage: mockTallImageCarousel[0],
thirdImage: mockSquareImageCarousel[0],
}
},
components: { ImageSlider, ScrollWrapper },
Expand All @@ -106,20 +180,27 @@ export function WithScrollWrapperCarousel() {
<ScrollWrapper :single-item="true" :initial-slide="1">
<template #item-1>
<image-slider
:before-image="beforeImage"
:after-image="afterImage"
/>
:before-image="firstImage.beforeImage"
:after-image="firstImage.afterImage"
>
<template #beforeLabel>
Custom Before Label
</template>
<template #afterLabel>
Custom After Label
</template>
</image-slider>
</template>
<template #item-2>
<image-slider
:before-image="beforeImage"
:after-image="afterImage"
:before-image="secondImage.beforeImage"
:after-image="secondImage.afterImage"
/>
</template>
<template #item-3>
<image-slider
:before-image="beforeImage"
:after-image="afterImage"
:before-image="thirdImage.beforeImage"
:after-image="thirdImage.afterImage"
/>
</template>
</ScrollWrapper>
Expand Down