UNPKG

@square/maker

Version:

Maker Design System by Square

1 lines 9.55 kB
{"version":3,"file":"styles.css","mappings":"AAmUA,gBAGA,YAFA,kBACA,UAEA,CAEA,gBAMA,uDALA,cAEA,YACA,mCACA,6CAHA,UA2BA,CArBA,+BACA,0DACA,CAEA,+BACA,eACA,CAEA,+BACA,sCACA,CAEA,+BACA,2CACA,2CACA,CAEA,+BACA,6CACA,oCACA","sources":["webpack://@square/maker/./src/components/Image/src/Image.vue"],"sourcesContent":["<template>\n\t<div\n\t\t:class=\"$s.ImageWrapper\"\n\t\t:style=\"imageWrapperStyles\"\n\t>\n\t\t<m-skeleton-block\n\t\t\tv-if=\"!loaded\"\n\t\t\t:class=\"[\n\t\t\t\t$s.Image,\n\t\t\t\t$s[`shape_${resolvedShape}`],\n\t\t\t]\"\n\t\t/>\n\t\t<!-- Need to use a template. Using an actual element (e.g span)\n\t\tand needing to style it causes the performance issue in Safari. -->\n\t\t<template v-if=\"shouldDisableTransition\">\n\t\t\t<img\n\t\t\t\tv-show=\"loaded\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t[$s.Image]: true,\n\t\t\t\t\t[$s[`shape_${resolvedShape}`]]: resolvedShape,\n\t\t\t\t\t[$s.thumbnail]: isThumbnail,\n\t\t\t\t}\"\n\t\t\t\t:style=\"style\"\n\t\t\t\t:srcset=\"calculatedSrcSet\"\n\t\t\t\t:sizes=\"sizes\"\n\t\t\t\t:src=\"calculatedSrc\"\n\t\t\t\t:alt=\"alt\"\n\t\t\t\tv-bind=\"$attrs\"\n\t\t\t\t@load=\"onLoaded\"\n\t\t\t\tv-on=\"$listeners\"\n\t\t\t>\n\t\t</template>\n\t\t<m-transition-fade-in\n\t\t\tv-else\n\t\t\t@after-enter=\"afterEnter\"\n\t\t>\n\t\t\t<img\n\t\t\t\tv-show=\"loaded\"\n\t\t\t\t:class=\"{\n\t\t\t\t\t[$s.Image]: true,\n\t\t\t\t\t[$s[`shape_${resolvedShape}`]]: resolvedShape,\n\t\t\t\t\t[$s.thumbnail]: isThumbnail,\n\t\t\t\t}\"\n\t\t\t\t:style=\"style\"\n\t\t\t\t:srcset=\"calculatedSrcSet\"\n\t\t\t\t:sizes=\"sizes\"\n\t\t\t\t:src=\"calculatedSrc\"\n\t\t\t\t:alt=\"alt\"\n\t\t\t\tv-bind=\"$attrs\"\n\t\t\t\t@load=\"onLoaded\"\n\t\t\t\tv-on=\"$listeners\"\n\t\t\t>\n\t\t</m-transition-fade-in>\n\t\t<pseudo-window\n\t\t\t@resize=\"throttledResizeHandler\"\n\t\t/>\n\t</div>\n</template>\n\n<script>\nimport PseudoWindow from 'vue-pseudo-window';\nimport { throttle } from 'lodash';\nimport { MTransitionFadeIn } from '@square/maker/components/TransitionFadeIn';\nimport { MSkeletonBlock } from '@square/maker/components/Skeleton';\nimport { MThemeKey, defaultTheme, resolveThemeableProps } from '@square/maker/components/Theme';\nimport cssValidator from '@square/maker/utils/css-validator';\n\nconst hexagon = 'polygon(50% 0, 93.3012701892219% 25%, 93.3012701892219% 75%, 50% 100%, 6.69872981077807% 75%, 6.69872981077807% 25%)';\n\n/** @constructor */\nfunction SharedIntersectionObserver() {\n\tconst callbacks = new WeakMap();\n\tconst o = new IntersectionObserver((entries) => {\n\t\tentries.forEach((entry) => callbacks.get(entry.target)?.(entry));\n\t});\n\n\treturn {\n\t\twatch(element, callback) {\n\t\t\tcallbacks.set(element, callback);\n\t\t\to.observe(element);\n\t\t},\n\t\tunwatch(element) {\n\t\t\to.unobserve(element);\n\t\t\tcallbacks.delete(element);\n\t\t},\n\t};\n}\n\nconst THUMBNAIL_MAX_WIDTH = '150';\nconst THROTTLE_DELAY = 200;\n\n/** @type {SharedIntersectionObserver?} */\nlet observer;\n\n/**\n * @inheritAttrs img\n * @inheritListeners img\n */\nexport default {\n\tcomponents: {\n\t\tPseudoWindow,\n\t\tMTransitionFadeIn,\n\t\tMSkeletonBlock,\n\t},\n\n\tinject: {\n\t\ttheme: {\n\t\t\tdefault: defaultTheme(),\n\t\t\tfrom: MThemeKey,\n\t\t},\n\t},\n\n\tinheritAttrs: false,\n\n\tprops: {\n\t\tsrc: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tsrcset: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\tsizes: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t},\n\t\t/**\n\t\t * Original applies theme's border radius, square applies border radius of 0\n\t\t */\n\t\tshape: {\n\t\t\ttype: String,\n\t\t\tdefault: undefined,\n\t\t\tvalidator: (shape) => ['original', 'square', 'circle', 'arch', 'hexagon'].includes(shape),\n\t\t},\n\t\tlazyload: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * [Object fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)\n\t\t */\n\t\tobjectFit: {\n\t\t\ttype: String,\n\t\t\tvalidator: cssValidator('object-fit'),\n\t\t\tdefault: 'cover',\n\t\t},\n\t\t/**\n\t\t * [Object position](https://developer.mozilla.org/en-US/docs/Web/CSS/object-position)\n\t\t */\n\t\tobjectPosition: {\n\t\t\ttype: String,\n\t\t\tvalidator: cssValidator('object-position'),\n\t\t\tdefault: 'center',\n\t\t},\n\t\tshouldDisableTransition: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/* Should only be needed for Safari */\n\t\tshouldUseStaticSizeStyles: {\n\t\t\ttype: Boolean,\n\t\t\tdefault: false,\n\t\t},\n\t\t/**\n\t\t * Alternative text for the image, for accessibility.\n\t\t */\n\t\talt: {\n\t\t\ttype: String,\n\t\t\tdefault: '',\n\t\t},\n\t},\n\n\tdata() {\n\t\treturn {\n\t\t\tshouldLoad: false,\n\t\t\tloaded: false,\n\t\t\tthrottledResizeHandler: throttle(this.getImageDimensions, THROTTLE_DELAY),\n\t\t\theight: 0,\n\t\t\twidth: 0,\n\t\t\tgetImageDimensionsFnAttemptsLeft: 20,\n\t\t\tgetImageDimensionsTimeout: undefined,\n\t\t};\n\t},\n\n\tcomputed: {\n\t\t...resolveThemeableProps('image', [\n\t\t\t'shape',\n\t\t]),\n\n\t\tcalculatedSrc() {\n\t\t\treturn this.shouldLoad\n\t\t\t\t? this.src\n\t\t\t\t: '';\n\t\t},\n\n\t\tcalculatedSrcSet() {\n\t\t\treturn this.shouldLoad\n\t\t\t\t? this.srcset\n\t\t\t\t: '';\n\t\t},\n\n\t\timageWrapperStyles() {\n\t\t\treturn {\n\t\t\t\t'--maker-image-hexagon': hexagon,\n\t\t\t};\n\t\t},\n\n\t\tstyle() {\n\t\t\tconst imageStyle = {\n\t\t\t\t'--image-height': `${this.height}px`,\n\t\t\t\t'--image-object-fit': this.objectFit,\n\t\t\t\t'--image-object-position': this.objectPosition,\n\t\t\t};\n\t\t\t/*\n\t\t\t\tSafari doesn't seem to like `inherit` or `100%` for height/width.\n\t\t\t\tBy setting it static, the scrolling performance is vastly improved,\n\t\t\t\tand it does properly update on screen resize.\n\t\t\t*/\n\t\t\tif (this.shouldUseStaticSizeStyles && this.height && this.width) {\n\t\t\t\timageStyle.height = `${this.height}px`;\n\t\t\t\timageStyle.width = `${this.width}px`;\n\t\t\t}\n\n\t\t\treturn imageStyle;\n\t\t},\n\n\t\tisThumbnail() {\n\t\t\treturn this.width < THUMBNAIL_MAX_WIDTH;\n\t\t},\n\n\t\tshouldGetImageDimensions() {\n\t\t\treturn this.shouldUseStaticSizeStyles || (this.shape !== 'square' && this.shape !== 'original');\n\t\t},\n\t},\n\n\twatch: {\n\t\tsrc: 'load',\n\t\tsrcset: 'load',\n\t\tshape: {\n\t\t\timmediate: true,\n\t\t\thandler() {\n\t\t\t\tif (this.shouldGetImageDimensions && (!this.height || !this.width)) {\n\t\t\t\t\tthis.$nextTick(() => this.getImageDimensions());\n\t\t\t\t}\n\t\t\t},\n\t\t},\n\t},\n\n\tmounted() {\n\t\t// Emit image:visible right away if Image is cached,\n\t\t// since it will just render instead of transitioning in\n\t\t// If it doesn't have a transition, so we'll just trigger it here\n\t\tif (this.loaded || this.shouldDisableTransition) {\n\t\t\tthis.$emit('image:visible');\n\t\t}\n\n\t\tif (this.lazyload) {\n\t\t\tobserver ??= new SharedIntersectionObserver();\n\n\t\t\tobserver.watch(this.$el, ({ isIntersecting }) => {\n\t\t\t\tif (isIntersecting) {\n\t\t\t\t\tthis.load();\n\t\t\t\t}\n\t\t\t});\n\t\t} else {\n\t\t\tthis.load();\n\t\t}\n\n\t\t// Safari seems to really struggle with getImageDimensions, specifically calling\n\t\t// offsetHeight/offsetWidth which triggers a style recalculation. If you're\n\t\t// scrolling a list that has images, it just causes the main thread to get frozen.\n\t\t// Let's try and preload those values before the image is actually loaded.\n\t\tconst timeoutValue = 100;\n\t\tconst getImageDimensionsFn = () => {\n\t\t\tthis.getImageDimensions();\n\t\t\t// Just to ensure we don't have an infinite loop\n\t\t\tthis.getImageDimensionsFnAttemptsLeft -= 1;\n\t\t\tif (this.getImageDimensionsFnAttemptsLeft === 0) {\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tif (!this.height || !this.width) {\n\t\t\t\tthis.getImageDimensionsTimeout = setTimeout(getImageDimensionsFn, timeoutValue);\n\t\t\t}\n\t\t};\n\t\tif (this.shouldGetImageDimensions) {\n\t\t\tthis.$nextTick(getImageDimensionsFn);\n\t\t}\n\t},\n\n\tbeforeDestroy() {\n\t\tobserver?.unwatch(this.$el);\n\t\tclearTimeout(this.getImageDimensionsTimeout);\n\t},\n\n\tmethods: {\n\t\tload() {\n\t\t\tthis.shouldLoad = true;\n\t\t\tobserver?.unwatch(this.$el);\n\t\t},\n\n\t\tgetImageDimensions() {\n\t\t\tthis.height = this.$el?.offsetHeight || 0;\n\t\t\tthis.width = this.$el?.offsetWidth || 0;\n\t\t},\n\n\t\tafterEnter() {\n\t\t\tthis.$emit('image:visible');\n\t\t},\n\n\t\tonLoaded() {\n\t\t\tthis.loaded = true;\n\t\t\tif (this.shouldGetImageDimensions && (!this.height || !this.width)) {\n\t\t\t\t// We can't get the proper height of the image until after the DOM has been updated\n\t\t\t\t// The image will otherwise be hidden, and the offsetHeight will be 0\n\t\t\t\tthis.$nextTick(() => this.getImageDimensions());\n\t\t\t}\n\t\t},\n\t},\n};\n</script>\n\n<style module=\"$s\">\n.ImageWrapper {\n\tposition: relative;\n\twidth: 100%;\n\theight: 100%;\n}\n\n.Image {\n\tdisplay: block;\n\twidth: 100%;\n\theight: 100%;\n\tobject-fit: var(--image-object-fit);\n\tobject-position: var(--image-object-position);\n\tborder-radius: $maker-shape-image-border-radius;\n\n\t&.thumbnail {\n\t\tborder-radius: $maker-shape-thumbnail-border-radius;\n\t}\n\n\t&.shape_square {\n\t\tborder-radius: 0;\n\t}\n\n\t&.shape_circle {\n\t\tborder-radius: var(--image-height, 100%);\n\t}\n\n\t&.shape_arch {\n\t\tborder-top-left-radius: var(--image-height);\n\t\tborder-top-right-radius: var(--image-height);\n\t}\n\n\t&.shape_hexagon {\n\t\t-webkit-clip-path: var(--maker-image-hexagon);\n\t\tclip-path: var(--maker-image-hexagon);\n\t}\n}\n</style>\n"],"names":[],"sourceRoot":""}