# Element UI Administrator & Developer Guide

## 1. Architecture Overview

Element UI is a comprehensive Vue 2.x component library providing 67+ UI components, a theme system built on SCSS, an i18n framework supporting 50+ languages, and a set of internal utilities for DOM manipulation, popup management, and form validation. The library is published as `element-ui` on npm (v2.15.14) and distributed as both ES module and UMD bundles.

### Architecture Diagram

```text
element-ui (npm package)
├── src/index.js                 ← Auto-generated entry, registers all 67+ components
│   ├── Vue.use(ElementUI)       ← Global install: components + directives + prototypes
│   └── Vue.prototype.$ELEMENT   ← Global config (size, zIndex)
│
├── packages/                    ← 67+ component packages
│   ├── {component}/index.js     ← Package entry (imports src/main.vue, sets install())
│   └── {component}/src/         ← Component implementation (.vue + .js)
│
├── src/
│   ├── mixins/                  ← Shared behaviors (emitter, focus, locale, migrating)
│   ├── directives/              ← Internal directives (mousewheel, repeat-click)
│   ├── locale/                  ← i18n engine + 50+ lang packs
│   ├── transitions/             ← Collapse transition component
│   └── utils/                   ← DOM, date, popup, popper, scrollbar, types, etc.
│
├── packages/theme-chalk/        ← SCSS theme (compiled via gulp to CSS)
│   └── src/                     ← Per-component .scss files + shared variables
│
├── types/                       ← TypeScript declarations
├── examples/                    ← Demo site (webpack-dev-server)
├── test/                        ← Unit tests (karma + mocha + chai + sinon)
└── build/                       ← Webpack configs + build scripts
```

### Component Inventory

Element UI ships 67 registerable components plus the `CollapseTransition` utility component. They are organized into these categories:

| Category | Components |
|---|---|
| **Basic** | Button, ButtonGroup, Icon, Link |
| **Layout** | Container, Header, Aside, Main, Footer, Row, Col, Divider |
| **Form** | Input, InputNumber, Radio, RadioGroup, RadioButton, Checkbox, CheckboxButton, CheckboxGroup, Select, Option, OptionGroup, Switch, Slider, DatePicker, TimePicker, TimeSelect, Upload, Rate, ColorPicker, Transfer, Form, FormItem, Cascader, CascaderPanel, Autocomplete |
| **Data** | Table, TableColumn, Tag, Tree, Pagination, Badge, Avatar, Skeleton, SkeletonItem, Empty, Descriptions, DescriptionsItem, Result, Statistic, Progress |
| **Navigation** | Menu, Submenu, MenuItem, MenuItemGroup, Tabs, TabPane, Breadcrumb, BreadcrumbItem, PageHeader, Dropdown, DropdownMenu, DropdownItem, Steps, Step |
| **Notice** | Alert, Loading, Message, MessageBox, Notification |
| **Overlay** | Dialog, Drawer, Tooltip, Popover, Popconfirm |
| **Other** | Card, Carousel, CarouselItem, Collapse, CollapseItem, Timeline, TimelineItem, Calendar, Image, Backtop, InfiniteScroll, Scrollbar, Spinner |

> [!NOTE]
> Components like Message, Notification, MessageBox, and Loading are dual-mode: they can be used as template components AND as imperative service calls via `Vue.prototype` methods (`this.$message`, `this.$notify`, `this.$msgbox`, `this.$loading`).

### Technology Stack

| Technology | Version | Role |
|---|---|---|
| Vue | ^2.5.17 | Peer dependency, runtime framework |
| async-validator | ~1.8.1 | Form validation engine |
| deepmerge | ^1.2.0 | Deep object merging (i18n, config) |
| normalize-wheel | ^1.0.1 | Cross-browser mousewheel normalization |
| resize-observer-polyfill | ^1.5.0 | ResizeObserver for responsive components |
| throttle-debounce | ^1.0.1 | Event throttling/debouncing |
| babel-helper-vue-jsx-merge-props | ^2.0.0 | JSX prop merging in render functions |

### Data Flow

```text
Vue.use(ElementUI, options)
  │
  ├── locale.use(options.locale)          ← Set language
  ├── locale.i18n(options.i18n)           ← Set i18n handler
  ├── forEach component → Vue.component() ← Register all 67 components
  ├── Vue.use(InfiniteScroll)             ← Register directive
  ├── Vue.use(Loading.directive)          ← Register v-loading
  └── Vue.prototype.$ELEMENT = { size, zIndex }
      Vue.prototype.$loading = Loading.service
      Vue.prototype.$msgbox = MessageBox
      Vue.prototype.$alert = MessageBox.alert
      Vue.prototype.$confirm = MessageBox.confirm
      Vue.prototype.$prompt = MessageBox.prompt
      Vue.prototype.$notify = Notification
      Vue.prototype.$message = Message
```

## 2. System Requirements

| Requirement | Minimum | Recommended |
|---|---|---|
| Node.js | 10.x | 14.x+ |
| Vue | 2.5.17 | 2.6.x or 2.7.x |
| npm | 6.x | 8.x+ |
| Browsers | IE 10+ | Chrome, Firefox, Safari, Edge (latest) |

### Runtime Dependencies

| Package | Version | Purpose |
|---|---|---|
| `async-validator` | ~1.8.1 | Rule-based form validation |
| `babel-helper-vue-jsx-merge-props` | ^2.0.0 | JSX support in render functions |
| `deepmerge` | ^1.2.0 | Deep merge for locale + config objects |
| `normalize-wheel` | ^1.0.1 | Normalize mousewheel events cross-browser |
| `resize-observer-polyfill` | ^1.5.0 | ResizeObserver for Table, Scrollbar |
| `throttle-debounce` | ^1.0.1 | Event rate limiting |

### Dev/Build Dependencies (selected)

| Package | Version | Purpose |
|---|---|---|
| `webpack` | ^4.14.0 | Module bundling |
| `babel-cli` / `babel-core` | ^6.26.x | ES6+ transpilation |
| `node-sass` / `gulp-sass` | ^4.x | SCSS compilation for theme-chalk |
| `karma` / `mocha` / `chai` / `sinon` | Various | Unit testing |
| `vue-loader` | ^15.7.0 | Vue SFC compilation |
| `eslint` | 4.18.2 | Linting with `eslint-config-elemefe` |

> [!IMPORTANT]
> `node-sass` (used for building `theme-chalk`) is deprecated and may fail on Node 16+. If building themes locally, consider switching to `sass` (Dart Sass) or using the pre-built CSS from `lib/theme-chalk/`.

## 3. Configuration Reference

### Global Configuration Object

When calling `Vue.use(ElementUI, options)`, the options object is stored on `Vue.prototype.$ELEMENT`:

| Key | Type | Default | Description |
|---|---|---|---|
| `size` | `string` | `''` | Global component size. Values: `'medium'`, `'small'`, `'mini'`, `''` (default). Affects all size-aware components. |
| `zIndex` | `number` | `2000` | Base z-index for popup components (Dialog, Drawer, Popover, Tooltip, Select dropdown, etc.). Auto-incremented by `PopupManager`. |

### Locale Configuration

| Method | Signature | Description |
|---|---|---|
| `locale.use(lang)` | `use(langObject)` | Set the active language pack |
| `locale.i18n(fn)` | `i18n(translatorFunction)` | Override the default translation handler |

The `i18n` function receives `(key, options)` where `key` is a dot-separated path (e.g., `el.table.confirmFilter`) and `options` is an interpolation object.

### Environment Variables

| Variable | Context | Description |
|---|---|---|
| `NODE_ENV` | Build/Runtime | Controls development features. When `'production'`, the migrating mixin suppresses deprecation warnings |
| `VUE_ENV` | SSR test | Used in SSR test suite (`test/ssr/`) to configure server-side rendering |
| `PLAY_ENV` | Dev | When `true`, runs the playground dev server via `npm run dev:play` |
| `CI_ENV` | Test | Sets the base path for test resources in CI |
| `BABEL_ENV` | Build | Controls Babel preset selection (`utils` for lib build, `test` for test runs) |

> [!TIP]
> The `migrating` mixin (in `src/mixins/migrating.js`) logs console warnings for deprecated props and events. These only run when `NODE_ENV !== 'production'`, so they help during development but have zero overhead in production.

### Build Scripts

| Script | Command | Description |
|---|---|---|
| `dev` | `npm run dev` | Start demo site with webpack-dev-server (port 8085) |
| `dev:play` | `npm run dev:play` | Start playground dev server |
| `dist` | `npm run dist` | Full production build (clean + lint + webpack + utils + UMD + theme) |
| `build:file` | `npm run build:file` | Generate icon list, entry file, i18n files, version file |
| `build:theme` | `npm run build:theme` | Compile SCSS → CSS via gulp, copy to `lib/theme-chalk/` |
| `build:utils` | `npm run build:utils` | Transpile `src/` utilities to `lib/` with Babel |
| `build:umd` | `npm run build:umd` | Build UMD locale bundles |
| `test` | `npm run test` | Lint + build theme + run karma unit tests |
| `test:watch` | `npm run test:watch` | Run tests in watch mode |
| `lint` | `npm run lint` | ESLint across src, test, packages, build |
| `pub` | `npm run pub` | Publish: bootstrap + git release + npm release + algolia index |

### Build Outputs

| Output | Path | Format | Description |
|---|---|---|---|
| Full bundle | `lib/index.js` | UMD | Unpkg entry, all components |
| CommonJS bundle | `lib/element-ui.common.js` | CJS | npm `main` field entry |
| Per-component | `lib/{component}.js` | CJS | Individual component for tree-shaking |
| Utils | `lib/utils/`, `lib/mixins/`, `lib/locale/`, etc. | CJS | Transpiled source utilities |
| Theme CSS | `lib/theme-chalk/index.css` | CSS | Full compiled theme |
| Per-component CSS | `lib/theme-chalk/{component}.css` | CSS | Individual component styles |
| UMD locales | `lib/umd/locale/*.js` | UMD | Per-language packs for CDN |
| TypeScript | `types/*.d.ts` | TS | Type declarations |

## 4. Deployment & Scaling

### Distribution

Element UI is consumed as an npm package. It does not run as a service or require server deployment. Distribution considerations:

**Full import (~700KB unminified JS + ~230KB CSS):**

```javascript
import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
Vue.use(ElementUI);
```

**Partial import (recommended for production):**

Use `babel-plugin-component` to import only needed components and their styles. This can reduce the bundle to under 100KB for typical applications.

**CDN deployment:**

```html
<link rel="stylesheet" href="https://unpkg.com/element-ui@2.15.14/lib/theme-chalk/index.css">
<script src="https://unpkg.com/element-ui@2.15.14/lib/index.js"></script>
```

### SSR Considerations

Element UI supports server-side rendering with Vue SSR. Key points:

- All service components (Message, Notification, MessageBox, Loading service) include `Vue.prototype.$isServer` guards and no-op on the server
- The popup manager skips z-index management on the server
- DOM utilities (`src/utils/dom.js`) check for `document` existence before accessing it

> [!WARNING]
> The `v-loading` directive and `InfiniteScroll` directive access DOM APIs directly. When using Nuxt or other SSR frameworks, register Element UI as a client-only plugin.

### Performance Optimization

| Strategy | How |
|---|---|
| Partial imports | Use `babel-plugin-component` for tree-shaking |
| Lazy-load tabs | Set `lazy` prop on `<el-tab-pane>` |
| Virtual scroll for tables | Use `append` slot with custom infinite-scroll logic |
| Image lazy loading | Set `lazy` prop on `<el-image>` |
| Skeleton loading | Use `<el-skeleton>` with `throttle` to avoid flash |
| Table `doLayout()` | Call after visibility changes to prevent layout thrash |

## 5. Operations

### Theme Customization System

Element UI's theme is built with SCSS and lives in `packages/theme-chalk/`:

```text
packages/theme-chalk/
├── src/
│   ├── common/
│   │   └── var.scss          ← Master variable file (all design tokens)
│   ├── mixins/
│   │   ├── config.scss       ← BEM naming configuration
│   │   ├── function.scss     ← SCSS utility functions
│   │   └── mixins.scss       ← Shared component mixins
│   ├── fonts/                ← Icon font files
│   ├── index.scss            ← Main entry (imports all component styles)
│   ├── {component}.scss      ← Per-component stylesheet
│   └── date-picker/*.scss    ← Date picker sub-styles
├── gulpfile.js               ← Build: sass → autoprefixer → cssmin → lib/
└── package.json              ← Published as `element-theme-chalk`
```

**Key theme variables (from `src/common/var.scss`):**

| Variable | Default | Controls |
|---|---|---|
| `$--color-primary` | `#409EFF` | Primary brand color |
| `$--color-success` | `#67C23A` | Success state color |
| `$--color-warning` | `#E6A23C` | Warning state color |
| `$--color-danger` | `#F56C6C` | Danger/error state color |
| `$--color-info` | `#909399` | Info state color |
| `$--color-text-primary` | `#303133` | Primary text |
| `$--color-text-regular` | `#606266` | Regular text |
| `$--font-size-base` | `14px` | Base font size |
| `$--border-radius-base` | `4px` | Default border radius |
| `$--border-color-base` | `#DCDFE6` | Default border color |

**Theme build pipeline:**

```bash
# In packages/theme-chalk/
gulp build
# Steps: sass → autoprefixer → cssmin → lib/
```

> [!NOTE]
> The theme uses BEM naming convention: `el-{component}`, `el-{component}__{element}`, `el-{component}--{modifier}`. The `$namespace` defaults to `el`.

### Online Theme Editor

The demo site includes a theme configurator at `examples/components/theme-configurator/`. It allows:

- Live editing of SCSS variables
- Real-time preview of component styles
- Download of compiled custom theme
- Local storage persistence of user theme configs

Theme constants are stored via `ELEMENT_THEME_USER_CONFIG` and `ELEMENT_THEME_PREVIEW_CONFIG` localStorage keys.

### i18n System

**Architecture:**

```text
src/locale/
├── index.js        ← Locale engine: use(), i18n(), t()
├── format.js       ← String template interpolation
└── lang/           ← 50+ language packs (zh-CN, en, es, fr-FR, ja, ko, etc.)
```

**How translation works:**

1. Each component uses the `locale` mixin which provides `this.t(key, options)`
2. `t()` first tries the custom `i18n` handler (if registered via `locale.i18n(fn)`)
3. Falls back to dot-path lookup in the active language pack
4. Interpolates `{placeholders}` via the format engine

**Supported languages include:** zh-CN (default), zh-TW, en, es, fr, de, ja, ko, pt, pt-br, ru, ar, it, nl, pl, sv, tr, vi, th, and 30+ more.

> [!TIP]
> To add a new language, create a new file in `src/locale/lang/` following the structure of any existing pack. The keys match the `el.*` namespace used throughout components.

### Popup and Z-Index Management

The `PopupManager` (`src/utils/popup/popup-manager.js`) manages global z-index ordering for all overlay components:

- Base z-index starts from `Vue.prototype.$ELEMENT.zIndex` (default 2000)
- Each popup increments the global counter via `PopupManager.nextZIndex()`
- Modals register/deregister for body scroll locking
- The manager tracks a stack of open modals for correct ESC-key handling

## 6. Performance

### Bundle Size

| Bundle | Size (approx.) |
|---|---|
| `lib/index.js` (UMD, unminified) | ~700KB |
| `lib/element-ui.common.js` (CJS) | ~680KB |
| `lib/theme-chalk/index.css` | ~230KB |
| Minified + gzipped (full) | ~90KB JS + ~45KB CSS |

Partial imports can significantly reduce this. A typical app using 15-20 components may end up with ~150KB total (minified + gzipped).

### Table Performance

The Table component (`packages/table/src/`) is the most complex component at 91KB of source across 12 files. Performance considerations:

- **Fixed columns** create shadow DOM copies of the table, doubling render cost
- **Large datasets** (1000+ rows) benefit from fixed `height` which enables virtual scrolling
- **`doLayout()`** should be called after visibility changes (tab switches, accordion opens) to recalculate column widths
- **Memory leaks** can occur if tables are shown/hidden with `v-show` instead of `v-if` — the layout observers may not clean up (issue #22980)

> [!NOTE]
> The Table component uses a dedicated Vuex-like store (`packages/table/src/store/`) to manage column state, sorting, filtering, expansion, and selection. Each Table instance gets its own store.

### Rendering Optimizations Built In

- **Throttled scroll handlers** in Table and InfiniteScroll via `throttle-debounce`
- **ResizeObserver** polyfill for responsive Table columns and Scrollbar
- **Lazy rendering** for TabPane (`lazy` prop) and Image (`lazy` prop)
- **Virtual scrolling** in Scrollbar component
- **Transition caching** via the CollapseTransition component
- **Mouse event normalization** via `normalize-wheel` for consistent scroll behavior

## 7. Security

### XSS Prevention

Several components support `dangerouslyUseHTMLString` for rendering raw HTML:

| Component | Prop | Default |
|---|---|---|
| Message | `dangerouslyUseHTMLString` | `false` |
| Notification | `dangerouslyUseHTMLString` | `false` |
| MessageBox | `dangerouslyUseHTMLString` | `false` |

> [!CAUTION]
> When `dangerouslyUseHTMLString` is set to `true`, the content is rendered via `v-html`. Never pass unsanitized user input through these options. Always sanitize HTML before rendering to prevent cross-site scripting attacks.

### Dependency Security

| Concern | Detail |
|---|---|
| lodash (devDependency) | Version 4.17.17 has known prototype pollution vulnerabilities. Upgrade to 4.17.21+ if using the build system (issues #23127, #23132) |
| node-sass (devDependency) | Deprecated; binary downloads may fail on newer OS/Node combinations. Consider migrating theme builds to Dart Sass |
| async-validator 1.8.x | Pinned to legacy version. Later versions changed validation behavior |

### Content Security Policy

Element UI injects styles dynamically for:
- Loading overlay positioning
- Theme configurator live preview
- Popup z-index management

If your application enforces strict CSP (`style-src` without `'unsafe-inline'`), the Loading directive's inline style injection will fail. Use the service API with pre-defined classes instead.

## 8. Developer Internals

### Repository Structure

```text
.
├── build/                          ← Build scripts and webpack configs
│   ├── bin/
│   │   ├── build-entry.js          ← Auto-generates src/index.js from components.json
│   │   ├── iconInit.js             ← Generates icon list from theme-chalk
│   │   ├── i18n.js                 ← Generates i18n page data
│   │   ├── version.js              ← Writes version file
│   │   ├── gen-cssfile.js          ← Generates per-component CSS imports
│   │   └── build-locale.js         ← Builds UMD locale bundles
│   ├── webpack.conf.js             ← UMD full bundle config
│   ├── webpack.common.js           ← CommonJS full bundle config
│   ├── webpack.component.js        ← Per-component CommonJS bundles
│   └── webpack.demo.js             ← Demo site dev server config
├── examples/                       ← Demo website (Vue SPA)
│   ├── app.vue                     ← Root component
│   ├── entry.js                    ← Webpack entry
│   ├── route.config.js             ← Router (loads doc pages from examples/docs/)
│   ├── nav.config.json             ← Navigation structure
│   ├── docs/                       ← Markdown documentation (zh-CN, en-US, es, fr-FR)
│   ├── components/                 ← Theme editor, search, demo components
│   └── i18n/                       ← Demo site i18n (page titles, labels)
├── packages/                       ← Component packages (67+)
│   ├── {component}/
│   │   ├── index.js                ← Package entry: imports + sets install()
│   │   └── src/
│   │       ├── main.vue            ← Component implementation (SFC)
│   │       └── *.js                ← Supporting logic
│   └── theme-chalk/                ← SCSS theme package
├── src/                            ← Shared infrastructure
│   ├── index.js                    ← Master entry (auto-generated)
│   ├── mixins/                     ← Shared component behaviors
│   ├── directives/                 ← Internal directives
│   ├── locale/                     ← i18n engine + language packs
│   ├── transitions/                ← Animation components
│   └── utils/                      ← Utility library (17 files, ~100KB)
├── test/                           ← Test suites
│   ├── unit/                       ← Karma + Mocha unit tests
│   │   ├── karma.conf.js           ← Karma configuration
│   │   ├── index.js                ← Test entry (requires all spec files)
│   │   ├── specs/                  ← Per-component test specs
│   │   └── mocks/                  ← Test mocks
│   └── ssr/                        ← Server-side rendering tests
├── types/                          ← TypeScript declarations
│   ├── index.d.ts                  ← Master type entry
│   ├── element-ui.d.ts             ← Main module types
│   └── {component}.d.ts            ← Per-component types
├── components.json                 ← Component registry (name → path mapping)
├── web-types.json                  ← JetBrains IDE component metadata
├── package.json                    ← Package manifest
├── Makefile                        ← Build shortcuts
└── .travis.yml                     ← CI configuration (Node 10, Chrome)
```

### Component Architecture Pattern

Every component follows the same pattern:

**1. Package entry (`packages/{name}/index.js`):**

```javascript
import Component from './src/main';

Component.install = function(Vue) {
  Vue.component(Component.name, Component);
};

export default Component;
```

**2. Component SFC (`packages/{name}/src/main.vue`):**

- Uses `componentName` (internal) for the emitter mixin's dispatch/broadcast
- Injects parent context where needed (e.g., `inject: ['elForm']`)
- Provides context to children (e.g., `provide() { return { elFormItem: this } }`)
- Uses the `locale` mixin for `this.t()` translations
- Uses the `emitter` mixin for cross-component communication
- Uses the `migrating` mixin for deprecation warnings

**3. Service components** (Message, Notification, Loading, MessageBox) follow a constructor pattern:

```javascript
const Constructor = Vue.extend(MainComponent);
const instance = new Constructor({ data: options });
instance.$mount();
document.body.appendChild(instance.$el);
```

### Mixin System

| Mixin | File | Purpose |
|---|---|---|
| `emitter` | `src/mixins/emitter.js` | Cross-component event dispatch (up) and broadcast (down) by `componentName` |
| `focus` | `src/mixins/focus.js` | Factory that returns a mixin adding `focus()` method targeting a `$ref` |
| `locale` | `src/mixins/locale.js` | Adds `this.t()` for i18n translations |
| `migrating` | `src/mixins/migrating.js` | Logs deprecation warnings for renamed props/events (dev only) |

The `emitter` mixin is critical infrastructure — it replaces Vue's removed `$dispatch` and `$broadcast` by walking the component tree via `$parent` / `$children` and matching on `componentName`.

### Utility Library

The `src/utils/` directory (17 files, ~100KB) provides:

| Module | Purpose |
|---|---|
| `dom.js` | DOM manipulation: `addClass`, `removeClass`, `getStyle`, `setStyle`, `on`, `off`, `once` |
| `util.js` | General utilities: `generateId`, `kebabCase`, `getPropByPath`, `escapeRegexpString`, `isIE`, `isMac` |
| `date.js` | Date formatting/parsing (`fecha` library fork) |
| `types.js` | Type checking: `isString`, `isObject`, `isHtmlElement`, `isFunction`, `isDefined`, `isUndefined`, `isKorean` |
| `merge.js` | Object merge utility |
| `vdom.js` | VNode utilities: `isVNode` |
| `resize-event.js` | ResizeObserver-based element resize detection |
| `scrollbar-width.js` | Native scrollbar width measurement |
| `scroll-into-view.js` | Scroll element into visible area |
| `clickoutside.js` | Click-outside directive implementation |
| `after-leave.js` | Callback after CSS transition leave |
| `aria-dialog.js` | ARIA dialog accessibility utilities |
| `aria-utils.js` | Focus trap and ARIA attribute management |
| `popper.js` | Popper.js v1 (vendored, ~30KB) for tooltip/popover positioning |
| `popup/` | Popup manager: z-index management, modal stacking, body scroll locking |

### Error Messages Reference

The following error messages are thrown from source code:

| Error | Source | Cause |
|---|---|---|
| `Can not find table layout.` | `packages/table/src/layout-observer.js:17` | TableColumn used outside Table |
| `for nested data item, row-key is required.` | `packages/table/src/table-body.js:432` | Tree data without `row-key` |
| `table is required for Table Layout` | `packages/table/src/table-layout.js:36` | TableLayout instantiated without table ref |
| `store is required for Table Layout` | `packages/table/src/table-layout.js:39` | TableLayout instantiated without store ref |
| `Table Layout don't have this column` | `packages/table/src/table-layout.js:243` | Column reference mismatch |
| `row is required when get row identity` | `packages/table/src/util.js:108` | `getRowIdentity` called with null row |
| `instance & callback is required` | `src/utils/after-leave.js:10` | `afterLeave` called without required args |
| `Dialog() requires a DOM element with ARIA role of dialog.` | `src/utils/aria-dialog.js:26` | ARIA dialog utility passed non-dialog element |
| `Invalid Date in fecha.format` | `src/utils/date.js:267` | Invalid date passed to formatter |
| `Invalid format in fecha.parse` | `src/utils/date.js:300` | Invalid format string for date parsing |
| `className should not contain space.` | `src/utils/dom.js:69` | Multiple classes in single `addClass` call |
| `Cannot convert first argument to object` | `src/utils/popper.js:1250` | Invalid reference element for Popper |
| `please transfer a valid prop path to form item!` | `src/utils/util.js:61` | Invalid `prop` path on FormItem |

### Directives

**Public directives (registered via `Vue.use`):**

| Directive | Description |
|---|---|
| `v-loading` | Show loading overlay. Modifiers: `.body` (append to body), `.fullscreen`, `.lock` (prevent scroll). Attributes: `element-loading-text`, `element-loading-spinner`, `element-loading-background`, `element-loading-custom-class` |
| `v-infinite-scroll` | Trigger function when scrolling to bottom. Attributes: `infinite-scroll-disabled`, `infinite-scroll-delay`, `infinite-scroll-distance`, `infinite-scroll-immediate` |
| `v-popover` | Associate a trigger element with a named Popover instance |

**Internal directives (not publicly registered):**

| Directive | File | Purpose |
|---|---|---|
| `v-mousewheel` | `src/directives/mousewheel.js` | Normalized mousewheel events (Firefox `DOMMouseScroll` handling) |
| `v-repeat-click` | `src/directives/repeat-click.js` | Repeated action on mousedown hold (used in InputNumber, Slider) |
| `v-clickoutside` | `src/utils/clickoutside.js` | Close popups on outside click |

### Testing Strategy

**Framework:** Karma + Mocha + Chai + Sinon

**Configuration:** `test/unit/karma.conf.js` configures Chrome headless, webpack preprocessing, Istanbul coverage, and spec reporter.

**Test entry:** `test/unit/index.js` requires all `*.spec.js` files from `test/unit/specs/`.

**Coverage:** Istanbul instrumentation via `babel-plugin-istanbul`, output to `test/unit/coverage/`.

**SSR tests:** `test/ssr/require.test.js` verifies that all components can be required in a Node.js environment without DOM errors.

**Running tests:**

```bash
# Full test suite (lint + build theme + karma)
npm test

# Watch mode (auto-rerun on changes)
npm run test:watch
```

> [!NOTE]
> Tests require Chrome (via `karma-chrome-launcher`). The `.travis.yml` configures `addons: chrome: stable` for CI.

### Code Patterns and Conventions

**BEM naming:** All CSS classes follow `el-{block}__{element}--{modifier}` pattern.

**Component naming:** PascalCase in JS (`ElButton`), kebab-case in templates (`<el-button>`). Internal `componentName` property used by the emitter mixin.

**JSX render functions:** Table, Select, Autocomplete, and several other complex components use JSX render functions (via `babel-plugin-transform-vue-jsx`) instead of templates for dynamic rendering.

**Component communication:**
- Parent → Child: props
- Child → Parent: `$emit` events
- Cross-level: `emitter` mixin's `dispatch` (bubbles up to named ancestor) and `broadcast` (propagates down to named descendant)
- Dependency injection: `provide`/`inject` for Form → FormItem, Select → Option, etc.

**Auto-generated files:**
- `src/index.js` — generated by `build/bin/build-entry.js` from `components.json`
- Icon list — generated by `build/bin/iconInit.js` from theme-chalk icon font
- i18n pages — generated by `build/bin/i18n.js`

### Potential Improvements

Based on the current codebase and community issues:

1. **Upgrade lodash to 4.17.21+** — current devDependency has known prototype pollution vulnerabilities (issues #23127, #23132)
2. **Migrate from node-sass to Dart Sass** — `node-sass` is deprecated and causes build failures on modern Node versions
3. **Table memory leak mitigation** — ResizeObserver and event listeners in Table may not properly clean up (issue #22980)
4. **Fixed column + summary scrollbar fix** — Known interaction bug between fixed columns and summary row (issues #23142, #20515)
5. **Upgrade async-validator** — Pinned to ~1.8.1; newer versions include important fixes but may change validation behavior
6. **Babel 6 → 7 migration** — Build toolchain uses Babel 6 which is EOL
7. **Webpack 4 → 5 migration** — Webpack 4 is in maintenance mode

## 9. Integration Points

### Vue Router Integration

The `<el-menu>` component supports `router` mode — setting `router` prop causes menu items to navigate using their `index` as the route path:

```html
<el-menu router :default-active="$route.path">
  <el-menu-item index="/dashboard">Dashboard</el-menu-item>
  <el-menu-item index="/settings">Settings</el-menu-item>
</el-menu>
```

`<el-breadcrumb-item>` supports the `:to` prop for Vue Router navigation.

### vue-i18n Integration

Element UI integrates with `vue-i18n` through the `i18n` install option. The handler receives the translation key and interpolation options, allowing Element UI's internal translations to merge with your application's translations.

### Form Validation (async-validator)

Element UI's Form component uses `async-validator` v1.8.x for validation rules. Rules support:

| Rule Property | Description |
|---|---|
| `required` | Field is required |
| `type` | Value type: `string`, `number`, `boolean`, `email`, `url`, `array`, etc. |
| `min` / `max` | Length constraints (string) or value constraints (number) |
| `pattern` | Regular expression match |
| `validator` | Custom validation function: `(rule, value, callback) => {}` |
| `trigger` | When to validate: `'blur'`, `'change'`, or array of both |
| `message` | Error message string |

### TypeScript Support

Type declarations ship in the `types/` directory:

```typescript
import Vue from 'vue';
import ElementUI from 'element-ui';

Vue.use(ElementUI);

// Component types
import { ElButton } from 'element-ui/types/button';

// Service types
import { ElMessageBox } from 'element-ui/types/message-box';
```

The `types/index.d.ts` augments `Vue` with the `$ELEMENT`, `$message`, `$notify`, `$msgbox`, `$alert`, `$confirm`, `$prompt`, and `$loading` prototype methods.

### JetBrains IDE Support

The `web-types.json` file at the package root provides component metadata (props, events, slots, descriptions) for JetBrains IDEs (WebStorm, IntelliJ). This enables auto-completion and inline documentation for all Element UI components.

> [!TIP]
> VS Code users can get similar auto-completion through the Vetur extension, which reads component type definitions and the `web-types.json` file.

---

_Generated June 2026 from ElemeFE/element at c345bb4. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
