@atlaskit/tile
Version:
A tile is a rounded square that takes an asset and represents a noun.
186 lines (181 loc) • 7.95 kB
JavaScript
/* tile.tsx generated by @compiled/babel-plugin v3.0.2 */
/* eslint-disable @atlaskit/ui-styling-standard/no-important-styles */
import "./tile.compiled.css";
import * as React from 'react';
import { ax, ix } from "@compiled/react/runtime";
import { useEffect, useRef } from 'react';
import { bind } from 'bind-event-listener';
// Pixel sizes per tile size, used for retina validation
const tileSizePx = {
xxsmall: 16,
xsmall: 20,
small: 24,
medium: 32,
large: 40,
xlarge: 48
};
const styles = {
root: "_2rkol0p1 _1reo15vq _18m915vq _kqswh2mm _1e0c116y _vchhusvi _4cvr1h6o _1bah1h6o _1o9zidpf _16jlidpf _1ul9idpf _1tkeidpf _s7n4nkob",
border: "_189ee4h9 _1dqonqa1 _1h6d1l7x",
inset: "_1iia1wug _bna71wug _1xjx1wug _17521wug",
nonInset: "_1qwg1osq _mezj1osq _e2oo1osq _w8l51osq _1iia1osq _bna71osq _1xjx1osq _17521osq _1jpx1dfr"
};
const sizeMap = {
xxsmall: "_1bsb7vkz _4t3i7vkz _1wyb19bv",
xsmall: "_1bsbgktf _4t3igktf _1wyb1crf",
small: "_1bsb1tcg _4t3i1tcg _1wybdlk8",
medium: "_1bsbzwfg _4t3izwfg _1wyb7vkz",
large: "_1bsb1ylp _4t3i1ylp _1wybgktf",
xlarge: "_1bsbckbl _4t3ickbl _1wyb1tcg"
};
const insetSizeMap = {
xxsmall: "_1qwg19bv _mezj19bv _e2oo19bv _w8l519bv _5ile19el _1hdc19el _1pc719el _pkax19el",
xsmall: "_1qwg1crf _mezj1crf _e2oo1crf _w8l51crf _5ilemccc _1hdcmccc _1pc7mccc _pkaxmccc",
small: "_1qwgdlk8 _mezjdlk8 _e2oodlk8 _w8l5dlk8 _5ilewk7l _1hdcwk7l _1pc7wk7l _pkaxwk7l",
medium: "_1qwg7vkz _mezj7vkz _e2oo7vkz _w8l57vkz _5ile1gpt _1hdc1gpt _1pc71gpt _pkax1gpt",
large: "_1qwggktf _mezjgktf _e2oogktf _w8l5gktf _5ile1txs _1hdc1txs _1pc71txs _pkax1txs",
xlarge: "_1qwg1tcg _mezj1tcg _e2oo1tcg _w8l51tcg _5ilea982 _1hdca982 _1pc7a982 _pkaxa982"
};
const backgroundColorMap = {
white: "_bfhku67f",
black: "_bfhkr3uz",
transparent: "_bfhk1j28",
'color.background.accent.lime.subtlest': "_bfhkm890",
'color.background.accent.lime.subtler': "_bfhkz2ec",
'color.background.accent.lime.subtle': "_bfhkbq5w",
'color.background.accent.lime.bolder': "_bfhktde4",
'color.background.accent.red.subtlest': "_bfhk1vk5",
'color.background.accent.red.subtler': "_bfhk1rtt",
'color.background.accent.red.subtle': "_bfhkkrt9",
'color.background.accent.red.bolder': "_bfhkuibq",
'color.background.accent.orange.subtlest': "_bfhkf5uh",
'color.background.accent.orange.subtler': "_bfhk165s",
'color.background.accent.orange.subtle': "_bfhk1kkj",
'color.background.accent.orange.bolder': "_bfhk1qg1",
'color.background.accent.yellow.subtlest': "_bfhkibhp",
'color.background.accent.yellow.subtler': "_bfhk1773",
'color.background.accent.yellow.subtle': "_bfhk8y3s",
'color.background.accent.yellow.bolder': "_bfhk1vop",
'color.background.accent.green.subtlest': "_bfhkn729",
'color.background.accent.green.subtler': "_bfhk1wnw",
'color.background.accent.green.subtle': "_bfhk1rsu",
'color.background.accent.green.bolder': "_bfhk1e5c",
'color.background.accent.teal.subtlest': "_bfhk7xuz",
'color.background.accent.teal.subtler': "_bfhk1a17",
'color.background.accent.teal.subtle': "_bfhktdv8",
'color.background.accent.teal.bolder': "_bfhk2c8p",
'color.background.accent.blue.subtlest': "_bfhk1s93",
'color.background.accent.blue.subtler': "_bfhk1dy8",
'color.background.accent.blue.subtle': "_bfhk115i",
'color.background.accent.blue.bolder': "_bfhk16e3",
'color.background.accent.purple.subtlest': "_bfhkp2ly",
'color.background.accent.purple.subtler': "_bfhk1nm4",
'color.background.accent.purple.subtle': "_bfhk18ah",
'color.background.accent.purple.bolder': "_bfhkya33",
'color.background.accent.magenta.subtlest': "_bfhk8tvm",
'color.background.accent.magenta.subtler': "_bfhkv9ra",
'color.background.accent.magenta.subtle': "_bfhk1mi6",
'color.background.accent.magenta.bolder': "_bfhkc3uk",
'color.background.accent.gray.subtlest': "_bfhkysee",
'color.background.accent.gray.subtler': "_bfhk7qp0",
'color.background.accent.gray.subtle': "_bfhk18j9",
'color.background.accent.gray.bolder': "_bfhk1i45",
'color.background.inverse.subtle': "_bfhk1vck",
'color.background.neutral': "_bfhki8nm",
'color.background.neutral.bold': "_bfhk1aqn",
'color.background.brand.subtlest': "_bfhk1gmr",
'color.background.brand.bold': "_bfhk1856",
'color.background.brand.boldest': "_bfhk1o4i",
'color.background.danger': "_bfhk1gly",
'color.background.danger.bold': "_bfhkybec",
'color.background.warning': "_bfhk1917",
'color.background.warning.bold': "_bfhk1kmu",
'color.background.success': "_bfhk1y9u",
'color.background.success.bold': "_bfhkkcmj",
'color.background.discovery': "_bfhk6vm6",
'color.background.discovery.bold': "_bfhku5tj",
'color.background.information': "_bfhk19ip",
'color.background.information.bold': "_bfhkx4w0"
};
/**
* __Tile__
*
* A tile is a rounded square that takes an asset and represents a noun.
*
*/
export default function Tile(props) {
const {
children,
label,
size = 'medium',
backgroundColor,
hasBorder,
isInset = true,
testId
} = props;
const containerRef = useRef(null);
// Dev-mode only: validate that raster images passed into the tile
// are square and retina-compatible (at least 2x the rendered tile size).
useEffect(() => {
var _tileSizePx$size;
if (process.env.NODE_ENV !== 'development') {
return;
}
const container = containerRef.current;
if (!container) {
return;
}
const images = container.querySelectorAll('img');
const defaultSizePx = tileSizePx['medium'];
const tilePx = (_tileSizePx$size = tileSizePx[size]) !== null && _tileSizePx$size !== void 0 ? _tileSizePx$size : defaultSizePx;
const unbinds = [];
images.forEach(img => {
const isRaster = /\.(png|jpe?g|gif|webp|avif)(\?|$)/i.test(img.src);
if (!isRaster) {
return;
}
const onLoad = () => {
const {
naturalWidth,
naturalHeight
} = img;
// naturalWidth/naturalHeight are 0 when the image fails to load
// (e.g. broken src, CORS error). Skip validation in that case to
// avoid misleading warnings about a non-existent image.
if (naturalWidth === 0 || naturalHeight === 0) {
return;
}
// Warn when the image is not square
if (naturalWidth !== naturalHeight) {
// eslint-disable-next-line no-console
console.warn(`[Tile] The image "${img.src}" passed into a Tile is not square (${naturalWidth}x${naturalHeight}px). ` + `Non-square images will be cropped to a square with object-fit: cover. ` + `Use a square image to ensure the correct portion is shown.`);
}
// Warn when the image is not retina-compatible (natural size < 2x tile size)
const requiredPx = tilePx * 2;
if (naturalWidth < requiredPx || naturalHeight < requiredPx) {
// eslint-disable-next-line no-console
console.warn(`[Tile] The image "${img.src}" passed into a Tile may appear blurry on retina displays. ` + `For a "${size}" tile (${tilePx}px), the image should be at least ${requiredPx}x${requiredPx}px. ` + `Provided image is ${naturalWidth}x${naturalHeight}px.`);
}
};
if (img.complete) {
onLoad();
} else {
unbinds.push(bind(img, {
type: 'load',
listener: onLoad,
options: {
once: true
}
}));
}
});
return () => unbinds.forEach(fn => fn());
}, [children, size]);
return /*#__PURE__*/React.createElement("span", {
ref: containerRef,
"data-testid": testId,
"aria-label": label !== '' ? label : undefined,
role: label !== '' ? 'img' : undefined,
className: ax([styles.root, sizeMap[size], isInset ? styles.inset : styles.nonInset, isInset && insetSizeMap[size], backgroundColorMap[backgroundColor || 'color.background.neutral'], hasBorder && styles.border])
}, children);
}