From d9462ab771ad63e0616bd7cb71f13a3490f2d458 Mon Sep 17 00:00:00 2001
From: Simona <36978416+SimonaliaChen@users.noreply.github.com>
Date: Fri, 19 Apr 2019 12:09:42 +0800
Subject: [PATCH] Image: add image component (#15117)
---
components.json | 3 +-
examples/demo-styles/image.scss | 78 ++++++++++++++++
examples/demo-styles/index.scss | 1 +
examples/docs/en-US/image.md | 132 ++++++++++++++++++++++++++++
examples/docs/es/image.md | 132 ++++++++++++++++++++++++++++
examples/docs/fr-FR/image.md | 132 ++++++++++++++++++++++++++++
examples/docs/zh-CN/image.md | 132 ++++++++++++++++++++++++++++
examples/nav.config.json | 16 ++++
packages/image/index.js | 8 ++
packages/image/src/main.vue | 123 ++++++++++++++++++++++++++
packages/theme-chalk/src/image.scss | 32 +++++++
packages/theme-chalk/src/index.scss | 1 +
src/index.js | 5 +-
src/locale/lang/af-ZA.js | 3 +
src/locale/lang/ar.js | 3 +
src/locale/lang/bg.js | 3 +
src/locale/lang/ca.js | 3 +
src/locale/lang/cs-CZ.js | 3 +
src/locale/lang/da.js | 3 +
src/locale/lang/de.js | 3 +
src/locale/lang/ee.js | 3 +
src/locale/lang/el.js | 3 +
src/locale/lang/en.js | 3 +
src/locale/lang/es.js | 3 +
src/locale/lang/eu.js | 3 +
src/locale/lang/fa.js | 3 +
src/locale/lang/fi.js | 3 +
src/locale/lang/fr.js | 3 +
src/locale/lang/he.js | 3 +
src/locale/lang/hr.js | 3 +
src/locale/lang/hu.js | 3 +
src/locale/lang/hy-AM.js | 3 +
src/locale/lang/id.js | 3 +
src/locale/lang/it.js | 3 +
src/locale/lang/ja.js | 3 +
src/locale/lang/kg.js | 3 +
src/locale/lang/km.js | 3 +
src/locale/lang/ko.js | 3 +
src/locale/lang/ku.js | 3 +
src/locale/lang/kz.js | 3 +
src/locale/lang/lt.js | 3 +
src/locale/lang/lv.js | 3 +
src/locale/lang/mn.js | 3 +
src/locale/lang/nb-NO.js | 3 +
src/locale/lang/nl.js | 3 +
src/locale/lang/pl.js | 3 +
src/locale/lang/pt-br.js | 3 +
src/locale/lang/pt.js | 3 +
src/locale/lang/ro.js | 3 +
src/locale/lang/ru-RU.js | 3 +
src/locale/lang/sk.js | 3 +
src/locale/lang/sl.js | 3 +
src/locale/lang/sr.js | 3 +
src/locale/lang/sv-SE.js | 3 +
src/locale/lang/ta.js | 3 +
src/locale/lang/th.js | 3 +
src/locale/lang/tk.js | 3 +
src/locale/lang/tr-TR.js | 3 +
src/locale/lang/ua.js | 3 +
src/locale/lang/ug-CN.js | 3 +
src/locale/lang/vi.js | 3 +
src/locale/lang/zh-CN.js | 3 +
src/locale/lang/zh-TW.js | 3 +
src/utils/dom.js | 53 +++++++++++
src/utils/types.js | 8 ++
test/unit/specs/image.spec.js | 68 ++++++++++++++
types/image.d.ts | 34 +++++++
67 files changed, 1106 insertions(+), 2 deletions(-)
create mode 100644 examples/demo-styles/image.scss
create mode 100644 examples/docs/en-US/image.md
create mode 100644 examples/docs/es/image.md
create mode 100644 examples/docs/fr-FR/image.md
create mode 100644 examples/docs/zh-CN/image.md
create mode 100644 packages/image/index.js
create mode 100644 packages/image/src/main.vue
create mode 100644 packages/theme-chalk/src/image.scss
create mode 100644 test/unit/specs/image.spec.js
create mode 100644 types/image.d.ts
diff --git a/components.json b/components.json
index f595fd87a..03f893b4d 100644
--- a/components.json
+++ b/components.json
@@ -70,5 +70,6 @@
"footer": "./packages/footer/index.js",
"timeline": "./packages/timeline/index.js",
"timeline-item": "./packages/timeline-item/index.js",
- "divider": "./packages/divider/index.js"
+ "divider": "./packages/divider/index.js",
+ "image": "./packages/image/index.js"
}
diff --git a/examples/demo-styles/image.scss b/examples/demo-styles/image.scss
new file mode 100644
index 000000000..9bf49967d
--- /dev/null
+++ b/examples/demo-styles/image.scss
@@ -0,0 +1,78 @@
+@keyframes dot {
+ 0% { width: 0; margin-right: 1em; }
+ 100% { width: 1em; margin-right: 0; }
+}
+
+.demo-image {
+ .block {
+ padding: 30px 0;
+ text-align: center;
+ border-right: solid 1px #eff2f6;
+ display: inline-block;
+ width: 20%;
+ box-sizing: border-box;
+ vertical-align: top;
+ &:last-child {
+ border-right: none;
+ }
+ }
+
+ .demonstration {
+ display: block;
+ color: #8492a6;
+ font-size: 14px;
+ margin-bottom: 20px;
+ }
+}
+
+.demo-image__placeholder, .demo-image__error {
+ @extend .demo-image;
+
+ .block {
+ width: 49%;
+ }
+
+ .el-image {
+ width: 300px;
+ height: 200px;
+ }
+
+ .image-slot {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ width: 100%;
+ height: 100%;
+ background: #f5f7fa;
+ color: #909399;
+ font-size: 14px;
+ }
+}
+
+.demo-image__placeholder {
+ .dot {
+ animation: dot 2s infinite steps(3, start);
+ overflow: hidden;
+ }
+}
+
+.demo-image__error {
+ .image-slot {
+ font-size: 30px;
+ }
+}
+
+.demo-image__lazy {
+ height: 400px;
+ overflow-y: auto;
+
+ .el-image {
+ display: block;
+ min-height: 200px;
+ margin-bottom: 10px;
+
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+}
diff --git a/examples/demo-styles/index.scss b/examples/demo-styles/index.scss
index 26e3ad7cd..026f06251 100644
--- a/examples/demo-styles/index.scss
+++ b/examples/demo-styles/index.scss
@@ -39,3 +39,4 @@
@import "./typography.scss";
@import "./upload.scss";
@import "./divider.scss";
+@import "./image.scss";
diff --git a/examples/docs/en-US/image.md b/examples/docs/en-US/image.md
new file mode 100644
index 000000000..0e621d0bd
--- /dev/null
+++ b/examples/docs/en-US/image.md
@@ -0,0 +1,132 @@
+## Image
+Besides the native features of img, support lazy load, custom placeholder and load failure, etc.
+
+### Basic Usage
+
+:::demo Indicate how the image should be resized to fit its container by `fit`, same as native [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)。
+```html
+
+
+
+```
+:::
+
+### Placeholder
+
+:::demo Custom placeholder content when image hasn't loaded yet by `slot = placeholder`
+```html
+
+
+ Default
+
+
+
+
Custom
+
+
+ Loading...
+
+
+
+
+
+
+```
+:::
+
+### Load Failed
+
+:::demo Custom failed content when error occurs to image load by `slot = error`
+```html
+
+```
+:::
+
+### Lazy Load
+
+:::demo Use lazy load by `lazy = true`. Image will load until scroll into view when set. You can indicate scroll container that adds scroll listener to by `scroll-container`. If undefined, will be the nearest parent container whose overflow property is auto or scroll.
+```html
+
+
+
+
+
+```
+:::
+
+### Attributes
+| Attribute | Description | Type | Accepted values | Default |
+|---------- |-------- |---------- |------------- |-------- |
+| src | Image source, same as native | string | — | - |
+| fit | Indicate how the image should be resized to fit its container, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) | fill / contain / cover / none / scale-down | — | - |
+| alt | Native alt | string | - | - |
+| lazy | Whether to use lazy load | boolean | — | false |
+| scroll-container | The container to add scroll listener when using lazy load | string / HTMLElement | — | The nearest parent container whose overflow property is auto or scroll |
+
+### Events
+| Event Name | Description | Parameters |
+|---------- |-------- |---------- |
+| load | Same as native load | (e: Event) |
+| error | Same as native error | (e: Error) |
+
+### Slots
+| Slot Name | Description |
+|---------|-------------|
+| placeholder | Triggers when image load |
+| error | Triggers when image load failed |
+
+
diff --git a/examples/docs/es/image.md b/examples/docs/es/image.md
new file mode 100644
index 000000000..0e621d0bd
--- /dev/null
+++ b/examples/docs/es/image.md
@@ -0,0 +1,132 @@
+## Image
+Besides the native features of img, support lazy load, custom placeholder and load failure, etc.
+
+### Basic Usage
+
+:::demo Indicate how the image should be resized to fit its container by `fit`, same as native [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)。
+```html
+
+
+
+```
+:::
+
+### Placeholder
+
+:::demo Custom placeholder content when image hasn't loaded yet by `slot = placeholder`
+```html
+
+
+ Default
+
+
+
+
Custom
+
+
+ Loading...
+
+
+
+
+
+
+```
+:::
+
+### Load Failed
+
+:::demo Custom failed content when error occurs to image load by `slot = error`
+```html
+
+```
+:::
+
+### Lazy Load
+
+:::demo Use lazy load by `lazy = true`. Image will load until scroll into view when set. You can indicate scroll container that adds scroll listener to by `scroll-container`. If undefined, will be the nearest parent container whose overflow property is auto or scroll.
+```html
+
+
+
+
+
+```
+:::
+
+### Attributes
+| Attribute | Description | Type | Accepted values | Default |
+|---------- |-------- |---------- |------------- |-------- |
+| src | Image source, same as native | string | — | - |
+| fit | Indicate how the image should be resized to fit its container, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) | fill / contain / cover / none / scale-down | — | - |
+| alt | Native alt | string | - | - |
+| lazy | Whether to use lazy load | boolean | — | false |
+| scroll-container | The container to add scroll listener when using lazy load | string / HTMLElement | — | The nearest parent container whose overflow property is auto or scroll |
+
+### Events
+| Event Name | Description | Parameters |
+|---------- |-------- |---------- |
+| load | Same as native load | (e: Event) |
+| error | Same as native error | (e: Error) |
+
+### Slots
+| Slot Name | Description |
+|---------|-------------|
+| placeholder | Triggers when image load |
+| error | Triggers when image load failed |
+
+
diff --git a/examples/docs/fr-FR/image.md b/examples/docs/fr-FR/image.md
new file mode 100644
index 000000000..0e621d0bd
--- /dev/null
+++ b/examples/docs/fr-FR/image.md
@@ -0,0 +1,132 @@
+## Image
+Besides the native features of img, support lazy load, custom placeholder and load failure, etc.
+
+### Basic Usage
+
+:::demo Indicate how the image should be resized to fit its container by `fit`, same as native [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)。
+```html
+
+
+
+```
+:::
+
+### Placeholder
+
+:::demo Custom placeholder content when image hasn't loaded yet by `slot = placeholder`
+```html
+
+
+ Default
+
+
+
+
Custom
+
+
+ Loading...
+
+
+
+
+
+
+```
+:::
+
+### Load Failed
+
+:::demo Custom failed content when error occurs to image load by `slot = error`
+```html
+
+```
+:::
+
+### Lazy Load
+
+:::demo Use lazy load by `lazy = true`. Image will load until scroll into view when set. You can indicate scroll container that adds scroll listener to by `scroll-container`. If undefined, will be the nearest parent container whose overflow property is auto or scroll.
+```html
+
+
+
+
+
+```
+:::
+
+### Attributes
+| Attribute | Description | Type | Accepted values | Default |
+|---------- |-------- |---------- |------------- |-------- |
+| src | Image source, same as native | string | — | - |
+| fit | Indicate how the image should be resized to fit its container, same as [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) | fill / contain / cover / none / scale-down | — | - |
+| alt | Native alt | string | - | - |
+| lazy | Whether to use lazy load | boolean | — | false |
+| scroll-container | The container to add scroll listener when using lazy load | string / HTMLElement | — | The nearest parent container whose overflow property is auto or scroll |
+
+### Events
+| Event Name | Description | Parameters |
+|---------- |-------- |---------- |
+| load | Same as native load | (e: Event) |
+| error | Same as native error | (e: Error) |
+
+### Slots
+| Slot Name | Description |
+|---------|-------------|
+| placeholder | Triggers when image load |
+| error | Triggers when image load failed |
+
+
diff --git a/examples/docs/zh-CN/image.md b/examples/docs/zh-CN/image.md
new file mode 100644
index 000000000..055df56bd
--- /dev/null
+++ b/examples/docs/zh-CN/image.md
@@ -0,0 +1,132 @@
+## Image 图片
+图片容器,在保留原生img的特性下,支持懒加载,自定义占位、加载失败等
+
+### 基础用法
+
+:::demo 可通过`fit`确定图片如何适应到容器框,同原生 [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit)。
+```html
+
+
+
+```
+:::
+
+### 占位内容
+
+:::demo 可通过`slot = placeholder`可自定义占位内容
+```html
+
+
+
+```
+:::
+
+### 加载失败
+
+:::demo 可通过`slot = error`可自定义加载失败内容
+```html
+
+```
+:::
+
+### 懒加载
+
+:::demo 可通过`lazy`开启懒加载功能,当图片滚动到可视范围内才会加载。可通过`scroll-container`来设置滚动容器,若未定义,则为最近一个`overflow`值为`auto`或`scroll`的父元素。
+```html
+
+
+
+
+
+```
+:::
+
+### Attributes
+| 参数 | 说明 | 类型 | 可选值 | 默认值 |
+|---------- |-------- |---------- |------------- |-------- |
+| src | 图片源,同原生 | string | — | - |
+| fit | 确定图片如何适应容器框,同原生 [object-fit](https://developer.mozilla.org/en-US/docs/Web/CSS/object-fit) | fill / contain / cover / none / scale-down | — | - |
+| alt | 原生 alt | string | - | - |
+| lazy | 是否开启懒加载 | boolean | — | false |
+| scroll-container | 开启懒加载后,监听 scroll 事件的容器 | string / HTMLElement | — | 最近一个 overflow 值为 auto 或 scroll 的父元素 |
+
+### Events
+| 事件名称 | 说明 | 回调参数 |
+|---------- |-------- |---------- |
+| load | 图片加载成功触发 | (e: Event) |
+| error | 图片加载失败触发 | (e: Error) |
+
+### Slots
+| 名称 | 说明 |
+|---------|-------------|
+| placeholder | 图片未加载的占位内容 |
+| error | 加载失败的内容 |
+
+
diff --git a/examples/nav.config.json b/examples/nav.config.json
index 40a3e3de9..0ae34df88 100644
--- a/examples/nav.config.json
+++ b/examples/nav.config.json
@@ -255,6 +255,10 @@
{
"path": "/divider",
"title": "Divider 分割线"
+ },
+ {
+ "path": "/image",
+ "title": "Image"
}
]
}
@@ -517,6 +521,10 @@
{
"path": "/divider",
"title": "Divider"
+ },
+ {
+ "path": "/image",
+ "title": "Image"
}
]
}
@@ -779,6 +787,10 @@
{
"path": "/divider",
"title": "Divider"
+ },
+ {
+ "path": "/image",
+ "title": "Image"
}
]
}
@@ -1041,6 +1053,10 @@
{
"path": "/divider",
"title": "Divider"
+ },
+ {
+ "path": "/image",
+ "title": "Image 图片"
}
]
}
diff --git a/packages/image/index.js b/packages/image/index.js
new file mode 100644
index 000000000..5e1d9656e
--- /dev/null
+++ b/packages/image/index.js
@@ -0,0 +1,8 @@
+import Image from './src/main';
+
+/* istanbul ignore next */
+Image.install = function(Vue) {
+ Vue.component(Image.name, Image);
+};
+
+export default Image;
diff --git a/packages/image/src/main.vue b/packages/image/src/main.vue
new file mode 100644
index 000000000..b66a6e6dc
--- /dev/null
+++ b/packages/image/src/main.vue
@@ -0,0 +1,123 @@
+
+
+
+
+
+
+ {{ t('el.image.error') }}
+
+
+
+
+
+
diff --git a/packages/theme-chalk/src/image.scss b/packages/theme-chalk/src/image.scss
new file mode 100644
index 000000000..528707bb5
--- /dev/null
+++ b/packages/theme-chalk/src/image.scss
@@ -0,0 +1,32 @@
+@import "mixins/mixins";
+@import "common/var";
+
+%size {
+ width: 100%;
+ height: 100%;
+}
+
+@include b(image) {
+ display: inline-block;
+
+ @include e(inner) {
+ @extend %size;
+ vertical-align: top;
+ }
+
+ @include e(placeholder) {
+ @extend %size;
+ background: $--background-color-base;
+ }
+
+ @include e(error) {
+ @extend %size;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ font-size: 14px;
+ background: $--background-color-base;
+ color: $--color-text-placeholder;
+ vertical-align: middle;
+ }
+}
diff --git a/packages/theme-chalk/src/index.scss b/packages/theme-chalk/src/index.scss
index 4051e6434..0cd602b59 100644
--- a/packages/theme-chalk/src/index.scss
+++ b/packages/theme-chalk/src/index.scss
@@ -68,3 +68,4 @@
@import "./timeline.scss";
@import "./timeline-item.scss";
@import "./divider.scss";
+@import "./image.scss";
diff --git a/src/index.js b/src/index.js
index ef603ee86..a388f369c 100644
--- a/src/index.js
+++ b/src/index.js
@@ -72,6 +72,7 @@ import Footer from '../packages/footer/index.js';
import Timeline from '../packages/timeline/index.js';
import TimelineItem from '../packages/timeline-item/index.js';
import Divider from '../packages/divider/index.js';
+import Image from '../packages/image/index.js';
import locale from 'element-ui/src/locale';
import CollapseTransition from 'element-ui/src/transitions/collapse-transition';
@@ -144,6 +145,7 @@ const components = [
Timeline,
TimelineItem,
Divider,
+ Image,
CollapseTransition
];
@@ -254,5 +256,6 @@ export default {
Footer,
Timeline,
TimelineItem,
- Divider
+ Divider,
+ Image
};
diff --git a/src/locale/lang/af-ZA.js b/src/locale/lang/af-ZA.js
index 5f09d42e7..cbb513295 100644
--- a/src/locale/lang/af-ZA.js
+++ b/src/locale/lang/af-ZA.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Voer sleutelwoord in',
noCheckedFormat: '{total} items',
hasCheckedFormat: '{checked}/{total} gekies'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ar.js b/src/locale/lang/ar.js
index 251f68d4e..da074098b 100644
--- a/src/locale/lang/ar.js
+++ b/src/locale/lang/ar.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'ادخل كلمة',
noCheckedFormat: '{total} عناصر',
hasCheckedFormat: '{checked}/{total} مختار'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/bg.js b/src/locale/lang/bg.js
index a8ab93131..1dd8468bc 100644
--- a/src/locale/lang/bg.js
+++ b/src/locale/lang/bg.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ca.js b/src/locale/lang/ca.js
index 854432f45..6a4aa2b17 100644
--- a/src/locale/lang/ca.js
+++ b/src/locale/lang/ca.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Introdueix la paraula clau',
noCheckedFormat: '{total} ítems',
hasCheckedFormat: '{checked}/{total} seleccionats'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/cs-CZ.js b/src/locale/lang/cs-CZ.js
index 6529ac619..24c74e9a6 100644
--- a/src/locale/lang/cs-CZ.js
+++ b/src/locale/lang/cs-CZ.js
@@ -106,6 +106,9 @@ export default {
filterPlaceholder: 'Klíčové slovo',
noCheckedFormat: '{total} položek',
hasCheckedFormat: '{checked}/{total} vybráno'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/da.js b/src/locale/lang/da.js
index 3501e62ac..b8c867090 100644
--- a/src/locale/lang/da.js
+++ b/src/locale/lang/da.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Indtast søgeord',
noCheckedFormat: '{total} emner',
hasCheckedFormat: '{checked}/{total} valgt'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/de.js b/src/locale/lang/de.js
index 84877c494..17c7913fe 100644
--- a/src/locale/lang/de.js
+++ b/src/locale/lang/de.js
@@ -105,6 +105,9 @@ export default {
filterPlaceholder: 'Einträge filtern',
noCheckedFormat: '{total} Einträge',
hasCheckedFormat: '{checked}/{total} ausgewählt'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ee.js b/src/locale/lang/ee.js
index 1f7f1af77..5c097e2ad 100644
--- a/src/locale/lang/ee.js
+++ b/src/locale/lang/ee.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Sisesta märksõna',
noCheckedFormat: '{total} objekti',
hasCheckedFormat: '{checked}/{total} valitud'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/el.js b/src/locale/lang/el.js
index 4eae67fae..52688e072 100644
--- a/src/locale/lang/el.js
+++ b/src/locale/lang/el.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Αναζήτηση',
noCheckedFormat: '{total} Αντικείμενα',
hasCheckedFormat: '{checked}/{total} επιλεγμένα'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/en.js b/src/locale/lang/en.js
index 808bbf232..94d9c662f 100644
--- a/src/locale/lang/en.js
+++ b/src/locale/lang/en.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED'
}
}
};
diff --git a/src/locale/lang/es.js b/src/locale/lang/es.js
index 6067f427e..e20824499 100644
--- a/src/locale/lang/es.js
+++ b/src/locale/lang/es.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Ingresar palabra clave',
noCheckedFormat: '{total} artículos',
hasCheckedFormat: '{checked}/{total} revisados'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/eu.js b/src/locale/lang/eu.js
index 8caa109f1..dfa5d9301 100644
--- a/src/locale/lang/eu.js
+++ b/src/locale/lang/eu.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Sartu gako-hitza', // to be translated
noCheckedFormat: '{total} elementu', // to be translated
hasCheckedFormat: '{checked}/{total} hautatuta' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/fa.js b/src/locale/lang/fa.js
index 8ffc0e57b..b1255179d 100644
--- a/src/locale/lang/fa.js
+++ b/src/locale/lang/fa.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'کلید واژه هارو وارد کن',
noCheckedFormat: '{total} مورد',
hasCheckedFormat: '{checked} مورد از {total} مورد انتخاب شده است'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/fi.js b/src/locale/lang/fi.js
index 544455077..0ae38e482 100644
--- a/src/locale/lang/fi.js
+++ b/src/locale/lang/fi.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Syötä hakusana',
noCheckedFormat: '{total} kohdetta',
hasCheckedFormat: '{checked}/{total} valittu'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/fr.js b/src/locale/lang/fr.js
index 41ac3f3b6..98b9a3429 100644
--- a/src/locale/lang/fr.js
+++ b/src/locale/lang/fr.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Entrer un mot clef',
noCheckedFormat: '{total} elements',
hasCheckedFormat: '{checked}/{total} coché(s)'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/he.js b/src/locale/lang/he.js
index 7a5f8ffc4..2cb92ca0a 100644
--- a/src/locale/lang/he.js
+++ b/src/locale/lang/he.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'הקלד',
noCheckedFormat: 'פריטים {total}',
hasCheckedFormat: ' אישור {checked}/{total}'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/hr.js b/src/locale/lang/hr.js
index afd348a5a..ec341834b 100644
--- a/src/locale/lang/hr.js
+++ b/src/locale/lang/hr.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Unesite ključnu riječ', // to be translated
noCheckedFormat: '{total} stavki', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/hu.js b/src/locale/lang/hu.js
index d1840555a..89b87f46d 100644
--- a/src/locale/lang/hu.js
+++ b/src/locale/lang/hu.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Kulcsszó',
noCheckedFormat: '{total} elem',
hasCheckedFormat: '{checked}/{total} kiválasztva'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/hy-AM.js b/src/locale/lang/hy-AM.js
index 306a464ca..7b60d040a 100644
--- a/src/locale/lang/hy-AM.js
+++ b/src/locale/lang/hy-AM.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Մուտքագրեք բանալի բառ',
noCheckedFormat: '{total} միաւոր',
hasCheckedFormat: '{checked}/{total} ընտրուած է'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/id.js b/src/locale/lang/id.js
index 9194b7866..2163b1c98 100644
--- a/src/locale/lang/id.js
+++ b/src/locale/lang/id.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Masukan kata kunci',
noCheckedFormat: '{total} butir',
hasCheckedFormat: '{checked}/{total} terpilih'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/it.js b/src/locale/lang/it.js
index 6fa262ad2..b4006421d 100644
--- a/src/locale/lang/it.js
+++ b/src/locale/lang/it.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Inserisci filtro',
noCheckedFormat: '{total} elementi',
hasCheckedFormat: '{checked}/{total} selezionati'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ja.js b/src/locale/lang/ja.js
index ff08f1f1c..fa9e0d103 100644
--- a/src/locale/lang/ja.js
+++ b/src/locale/lang/ja.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'キーワードを入力',
noCheckedFormat: '総計 {total} 件',
hasCheckedFormat: '{checked}/{total} を選択した'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/kg.js b/src/locale/lang/kg.js
index 03420776e..470a8f4a6 100644
--- a/src/locale/lang/kg.js
+++ b/src/locale/lang/kg.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Сураныч, издөө кирет',
noCheckedFormat: 'бүтүндөй {total} сан',
hasCheckedFormat: 'Тандалган {checked}/{total} сан'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/km.js b/src/locale/lang/km.js
index 97d2fc371..eb8251bd4 100644
--- a/src/locale/lang/km.js
+++ b/src/locale/lang/km.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'បញ្ចូលពាក្យ',
noCheckedFormat: '{total} ធាតុ',
hasCheckedFormat: '{checked}/{total} បានគូសធីក'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ko.js b/src/locale/lang/ko.js
index d203366c4..aafd3d63a 100644
--- a/src/locale/lang/ko.js
+++ b/src/locale/lang/ko.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: ' 입력하세요',
noCheckedFormat: '{total} 항목',
hasCheckedFormat: '{checked}/{total} 선택됨'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ku.js b/src/locale/lang/ku.js
index 88328ffcb..97a150c1a 100644
--- a/src/locale/lang/ku.js
+++ b/src/locale/lang/ku.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Binivîse',
noCheckedFormat: '{total} lib',
hasCheckedFormat: '{checked}/{total} bijartin'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/kz.js b/src/locale/lang/kz.js
index 01c43823e..81e2ee3d2 100644
--- a/src/locale/lang/kz.js
+++ b/src/locale/lang/kz.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Кілт сөзді енгізіңіз',
noCheckedFormat: '{total} элэмэнт',
hasCheckedFormat: '{checked}/{total} құсбелгісі қойылды'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/lt.js b/src/locale/lang/lt.js
index f8cb51754..156e248f1 100644
--- a/src/locale/lang/lt.js
+++ b/src/locale/lang/lt.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Įvesk raktažodį',
noCheckedFormat: 'Viso: {total}',
hasCheckedFormat: 'Pažymėta {checked} iš {total}'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/lv.js b/src/locale/lang/lv.js
index ae4554251..f8afe29db 100644
--- a/src/locale/lang/lv.js
+++ b/src/locale/lang/lv.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Ievadīt atslēgvārdu',
noCheckedFormat: '{total} vienības',
hasCheckedFormat: '{checked}/{total} atzīmēti'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/mn.js b/src/locale/lang/mn.js
index df563b599..e85019af3 100644
--- a/src/locale/lang/mn.js
+++ b/src/locale/lang/mn.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Утга оруул',
noCheckedFormat: '{total} өгөгдөл',
hasCheckedFormat: '{checked}/{total} сонгосон'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/nb-NO.js b/src/locale/lang/nb-NO.js
index 91c8ffe78..e8692b410 100644
--- a/src/locale/lang/nb-NO.js
+++ b/src/locale/lang/nb-NO.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/nl.js b/src/locale/lang/nl.js
index 6c76f20ce..1715e9223 100644
--- a/src/locale/lang/nl.js
+++ b/src/locale/lang/nl.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Geef zoekwoerd',
noCheckedFormat: '{total} items',
hasCheckedFormat: '{checked}/{total} geselecteerd'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/pl.js b/src/locale/lang/pl.js
index 8cc5c06f3..37b02b381 100644
--- a/src/locale/lang/pl.js
+++ b/src/locale/lang/pl.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Wpisz szukaną frazę',
noCheckedFormat: 'razem: {total}',
hasCheckedFormat: 'wybranych: {checked}/{total}'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/pt-br.js b/src/locale/lang/pt-br.js
index 5b0009a40..6f6f37748 100644
--- a/src/locale/lang/pt-br.js
+++ b/src/locale/lang/pt-br.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Digite uma palavra-chave',
noCheckedFormat: '{total} itens',
hasCheckedFormat: '{checked}/{total} selecionados'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/pt.js b/src/locale/lang/pt.js
index e8aacad3c..89a4e4f37 100644
--- a/src/locale/lang/pt.js
+++ b/src/locale/lang/pt.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ro.js b/src/locale/lang/ro.js
index 16a7ad15b..8fb218c35 100644
--- a/src/locale/lang/ro.js
+++ b/src/locale/lang/ro.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Introduceți cuvântul cheie',
noCheckedFormat: '{total} elemente',
hasCheckedFormat: '{checked}/{total} verificate'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ru-RU.js b/src/locale/lang/ru-RU.js
index 890f111bd..c6a936c3f 100644
--- a/src/locale/lang/ru-RU.js
+++ b/src/locale/lang/ru-RU.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Введите ключевое слово',
noCheckedFormat: '{total} пунктов',
hasCheckedFormat: '{checked}/{total} выбрано'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/sk.js b/src/locale/lang/sk.js
index 0ef62c4e3..8aa383260 100644
--- a/src/locale/lang/sk.js
+++ b/src/locale/lang/sk.js
@@ -106,6 +106,9 @@ export default {
filterPlaceholder: 'Filtrovať podľa',
noCheckedFormat: '{total} položiek',
hasCheckedFormat: '{checked}/{total} označených'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/sl.js b/src/locale/lang/sl.js
index f6000a071..b6cd253d3 100644
--- a/src/locale/lang/sl.js
+++ b/src/locale/lang/sl.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Vnesi ključno besedo',
noCheckedFormat: '{total} elementov',
hasCheckedFormat: '{checked}/{total} izbranih'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/sr.js b/src/locale/lang/sr.js
index fe2f108e7..7d3e7b048 100644
--- a/src/locale/lang/sr.js
+++ b/src/locale/lang/sr.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Унеси кључну реч', // to be translated
noCheckedFormat: '{total} ставки', // to be translated
hasCheckedFormat: '{checked}/{total} обележених' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/sv-SE.js b/src/locale/lang/sv-SE.js
index 0be73a0b2..aed00aea3 100644
--- a/src/locale/lang/sv-SE.js
+++ b/src/locale/lang/sv-SE.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ta.js b/src/locale/lang/ta.js
index 7b458112f..694501adf 100644
--- a/src/locale/lang/ta.js
+++ b/src/locale/lang/ta.js
@@ -103,6 +103,9 @@ export default {
filterPlaceholder: 'சொல்லை உள்ளீடு செய்',
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} தேர்வு செய்யப்பட்டவைகள்'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/th.js b/src/locale/lang/th.js
index e45a392e7..0475f51e2 100644
--- a/src/locale/lang/th.js
+++ b/src/locale/lang/th.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/tk.js b/src/locale/lang/tk.js
index 6db1e0cba..6b8bb6282 100644
--- a/src/locale/lang/tk.js
+++ b/src/locale/lang/tk.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Gözleg sözlerini giriziň',
noCheckedFormat: '{total} sany',
hasCheckedFormat: '{checked}/{total} saýlanan'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/tr-TR.js b/src/locale/lang/tr-TR.js
index de5e68fb2..6e3cb629e 100644
--- a/src/locale/lang/tr-TR.js
+++ b/src/locale/lang/tr-TR.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Anahtar kelimeleri gir',
noCheckedFormat: '{total} adet',
hasCheckedFormat: '{checked}/{total} seçildi'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ua.js b/src/locale/lang/ua.js
index 45118931b..56022259c 100644
--- a/src/locale/lang/ua.js
+++ b/src/locale/lang/ua.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Введіть ключове слово',
noCheckedFormat: '{total} пунктів',
hasCheckedFormat: '{checked}/{total} вибрано'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/ug-CN.js b/src/locale/lang/ug-CN.js
index 6db539251..0c94b08fd 100644
--- a/src/locale/lang/ug-CN.js
+++ b/src/locale/lang/ug-CN.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'ئىزدىمەكچى بولغان مەزمۇننى كىرگۈزۈڭ',
noCheckedFormat: 'جەمئىي {total} تۈر',
hasCheckedFormat: 'تاللانغىنى {checked}/{total} تۈر'
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/vi.js b/src/locale/lang/vi.js
index a09d68e09..24fd444f4 100644
--- a/src/locale/lang/vi.js
+++ b/src/locale/lang/vi.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Nhập từ khóa',
noCheckedFormat: '{total} mục',
hasCheckedFormat: '{checked}/{total} đã chọn '
+ },
+ image: {
+ error: 'FAILED' // to be translated
}
}
};
diff --git a/src/locale/lang/zh-CN.js b/src/locale/lang/zh-CN.js
index 6d25fd240..fa4b74799 100644
--- a/src/locale/lang/zh-CN.js
+++ b/src/locale/lang/zh-CN.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: '请输入搜索内容',
noCheckedFormat: '共 {total} 项',
hasCheckedFormat: '已选 {checked}/{total} 项'
+ },
+ image: {
+ error: '加载失败'
}
}
};
diff --git a/src/locale/lang/zh-TW.js b/src/locale/lang/zh-TW.js
index 03b257289..9b87d2649 100644
--- a/src/locale/lang/zh-TW.js
+++ b/src/locale/lang/zh-TW.js
@@ -104,6 +104,9 @@ export default {
filterPlaceholder: 'Enter keyword', // to be translated
noCheckedFormat: '{total} items', // to be translated
hasCheckedFormat: '{checked}/{total} checked' // to be translated
+ },
+ image: {
+ error: '加載失敗'
}
}
};
diff --git a/src/utils/dom.js b/src/utils/dom.js
index 0221295f5..8d2c66807 100644
--- a/src/utils/dom.js
+++ b/src/utils/dom.js
@@ -172,3 +172,56 @@ export function setStyle(element, styleName, value) {
}
}
};
+
+export const isScroll = (el, vertical) => {
+ if (isServer) return;
+
+ const determinedDirection = vertical !== null || vertical !== undefined;
+ const overflow = determinedDirection
+ ? vertical
+ ? getStyle(el, 'overflow-y')
+ : getStyle(el, 'overflow-x')
+ : getStyle(el, 'overflow');
+
+ return overflow.match(/(scroll|auto)/);
+};
+
+export const getScrollContainer = (el, vertical) => {
+ if (isServer) return;
+
+ let parent = el;
+ while (parent) {
+ if ([window, document, document.documentElement].includes(parent)) {
+ return window;
+ }
+ if (isScroll(parent, vertical)) {
+ return parent;
+ }
+ parent = parent.parentNode;
+ }
+
+ return parent;
+};
+
+export const isInContainer = (el, container) => {
+ if (isServer || !el || !container) return false;
+
+ const elRect = el.getBoundingClientRect();
+ let containerRect;
+
+ if ([window, document, document.documentElement, null, undefined].includes(container)) {
+ containerRect = {
+ top: 0,
+ right: window.innerWidth,
+ bottom: window.innerHeight,
+ left: 0
+ };
+ } else {
+ containerRect = container.getBoundingClientRect();
+ }
+
+ return elRect.top < containerRect.bottom &&
+ elRect.bottom > containerRect.top &&
+ elRect.right > containerRect.left &&
+ elRect.left < containerRect.right;
+};
diff --git a/src/utils/types.js b/src/utils/types.js
index 828773341..a5d449231 100644
--- a/src/utils/types.js
+++ b/src/utils/types.js
@@ -1,3 +1,11 @@
+export function isString(obj) {
+ return Object.prototype.toString.call(obj) === '[object String]';
+}
+
export function isObject(obj) {
return Object.prototype.toString.call(obj) === '[object Object]';
}
+
+export function isHtmlElement(node) {
+ return node && node.nodeType === Node.ELEMENT_NODE;
+}
diff --git a/test/unit/specs/image.spec.js b/test/unit/specs/image.spec.js
new file mode 100644
index 000000000..6dca7ec59
--- /dev/null
+++ b/test/unit/specs/image.spec.js
@@ -0,0 +1,68 @@
+import { createTest, createVue, destroyVM, wait } from '../util';
+import Image from 'packages/image';
+
+const src = 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAAFmklEQVR4Xu2ba2wUVRTH/2cWtlaooFQwKpr4CkESTQBNUAkodGeaKFGD2u6WGPyAmmAEEZmpj1VhBghE/KKGBIztDIXAByWBnQ1oQREfARNiDDHiF1+ooBiksVt295hFiqSdxx3KdmcH5uv+z+3//O65c19TwgX+0AWePy4CuFgBISCQ3J6+DFLuVQKmg2k4gK3xuvwr6+9e+Xe57YViCCRttY1ALX2S/asIPLRB1jvLCSEUAFK2egKgYf0T5a6TxdhtmxqXfl8uCBUHMHfP4rqeE0OOeyS4w5T1hsgCmLNTvaWYp299EpxoyvpX5YBQ8QpotlvvkMBfeCbHvMpUjOejCSCjPSYROrySY/B+SzYmRRJA0tZWEfCcJwBGz81yvDZN6eL5hlDxIZCyta8BTPBLjIv5sVbjyp/8dEF/ryiAlL3kJkD6TsQ0STS5vWHZPhFtEE1FAYiUf28yBaZ7OpRle4IkJ6KtGIDZexfU1hyv/QXASBGjBeYpHYrxmYg2iKZiAFIZdSGIVouaLVJx0obE8v2ielFdRQA83pkemc/lDgE0StRopF6CSVuzCGgWTb6ku7T+aHztpLUng8SIaAe9ApJ265MEflvE3P8a/t2UjTHBYsTUgwqgKauOk4p0gAhxMXunVcwfmYpxX6AYQfGgAWjqTNdL3bndRDRe0NsZGYPXWLKxIGiciH5QAJye8r4UWfE5mWbCE1ZCXy+SUFBN2QEo2+fXjKK6zSDcH9Rcr55i0vj2mUsPnmu8V1xZAZxKXhq+G6A7z9U8Mx+zFOOKc433iysbgNKYj3XnNoHoXj8T3r/z+6ZsPDiwNtyjHQE07dTGSAU8QkX4LlSY6Ndh9UfWnT1Ht2QXjeZifC8INw7UOAMfE2MgB6NdhaFo65ih/+bkxRFAMqPuIaK7xM3zu6ZszO3Vt2S1CcwobXPD8TAfoZjU6LSb7AdgWmd6yLW5nqArrm5T1mtDC+A/Y3tNWe/XqY4VkLK1fwBcItp9DGZLNqQwA2DmgiUbQ0Hgs/NyBpBRD4PoqigBKOWSGxuv2XxruscXQNJWDxJoXJQAMPCnJev9XuouQ0D9PMjcXQ1DAIx9pqJP7tupLrOAZhMhEaUKAGOjqehNYgBsdSOBHo0UAOBlU9ZfFwOQUd8honmRAsA8y1SMrWIAbHUFgRZHCUCe6LqNiWU/igHIaCoR9KgAYMZRS9GvFF4Kp7LqU2B6KzoAeKulGLOEASRtrZkAK0IAVEsxlgsDaM6ojRLRtqgAIImntTcYu4UBpLKtU8D8aRQAMJD/uSZeu2t6Oi8MILldHU8SfRMFAG67wN7cHFeCcz5svaZ4koWvosO9FGbdlI1Wt850BNCSXTSMOX4iEhVAaDAT+o5AAEriVEYrgHBmj+8FI7QVwJzLjei+fPOUN0rnG46P66FoMqMdIUK9SBWEGIDvjZIrgFRGOyR6qBlWAMzQLEU3vDrRvQJsdR+BJlZzBYh8VuM1BHYSQehCMpwVwF1mwqjrewYotBk69RK0tS0AHq7eChC7UPEYAto6As6c9VfdLED8tJkwfL9DcH8J2upqgBZWbwXgalPWD/v59wCgvQTgNb8GSr+H7x3AB0zZuF3EuyuA5oz6jET0pkgjYQPAzEstxSh1oO/jVQFzALzn20IIK0CKFa5vm7niBxHvHgsh9QEQfSDSSP8KWDSaOe54GyvS3sA0vMuUjemibbgPgWzrVInZ8RChb+N9AQSdRkXNiul4qikbn4hp4f5/g7N3vDAiXpCOEcj/IwpG0VT02Nl/9NSOshjvGMinMaJJ9OqYeYulGLODxHkml7TVZ8GYT0Q3uDfKXQxaY8n6i06aZnvJDGKaB8JMAo0IYk5UW7r5BbAtNhRz22YYf4jGlXT+vRuktSrUXgRQhZ12Xi1f8BXwL38cy1+mrtJNAAAAAElFTkSuQmCC';
+
+describe('Image', () => {
+ let vm;
+
+ afterEach(() => {
+ destroyVM(vm);
+ });
+
+ it('create', async() => {
+ vm = createTest(Image, {
+ src,
+ fit: 'fill'
+ }, true);
+ const placeholder = vm.$el.querySelector('.el-image__placeholder');
+ const error = vm.$el.querySelector('.el-image__error');
+ let img = vm.$el.querySelector('.el-image__inner');
+ expect(placeholder).to.exist;
+ expect(error).to.be.null;
+ expect(img).to.be.null;
+
+ await wait();
+ img = vm.$el.querySelector('.el-image__inner');
+ expect(img.style.objectFit).to.equal('fill');
+ });
+
+ it('load failed', async() => {
+ vm = createTest(Image, true);
+ await wait();
+ const error = vm.$el.querySelector('.el-image__error');
+ expect(error).to.be.exist;
+ });
+
+ it('lazy load', async() => {
+ vm = createVue({
+ template: `
+
+
+
+ `,
+ data() {
+ return {
+ src
+ };
+ }
+ }, true);
+ const { image, wrapper } = vm.$refs;
+ const [image1, image2] = image;
+
+ await wait();
+ expect(image1.loading).to.be.false;
+ expect(image2.loading).to.be.true;
+ wrapper.scrollTop = 10;
+
+ await wait();
+ expect(image2.loading).to.be.false;
+ });
+});
+
diff --git a/types/image.d.ts b/types/image.d.ts
new file mode 100644
index 000000000..6cfa648e5
--- /dev/null
+++ b/types/image.d.ts
@@ -0,0 +1,34 @@
+import { VNode } from 'vue'
+import { ElementUIComponent } from './component'
+
+export type ObjectFit = 'fill' | 'contain' | 'cover' | 'none' | 'scale-down'
+
+export interface ImageSlots {
+ /** Placeholder content when image hasn't loaded yet */
+ placeholder: VNode[]
+
+ /** Error content when error occurs to image load */
+ error: VNode[]
+
+ [key: string]: VNode[]
+}
+
+/** Image Component */
+export declare class ElImage extends ElementUIComponent {
+ /** Image source */
+ src: string
+
+ /** Indicate how the image should be resized to fit its container, same as native 'object-fit' */
+ fit: ObjectFit
+
+ /** Whether to use lazy load */
+ lazy: boolean
+
+ /** Scroll container that to add scroll listener when using lazy load */
+ scrollContainer: string | HTMLElement
+
+ /** Native 'alt' attribute */
+ alt: string
+
+ $slots: ImageSlots
+}