@abt-desk/realogy-mat-theme 中文文档教程
Realogy Angular Material Theme
该主题捕获应用于 Angular Material Components 的颜色,以便在构建 Realogy 产品时使用。
此外,还提供排版和组件样式覆盖,以帮助与我们的样式指南保持一致并提供实施的一致性。
Installation
安装 Angular Material 及其对等依赖项,如 material.angular.io
跳过包含预构建
主题 通过 npm 安装主题。 npm install @abt-desk/realogy-mat-theme
将以下代码添加到您的全局 style.scss
@import '~@abt-desk/realogy-mat-theme/src/theme'; @include angular-material-theme();
的全局 style.scss 文件
Rebranding
将 components.scss 的内容复制到您 material 主题,请注意以下几点:
建立你的主色、重音色和警告色(可选)。 如果您的品牌调色板缺少强调色,您可以在主要颜色中使用相同的值作为强调色。 确保您的颜色值采用十六进制格式。
测试您选择的颜色的对比度以确保可访问性。 将值放在前景色字段中,然后在字段外单击以返回对比度。
该值必须为 4.5:1 或更大,以确保以符合可访问性标准的方式应用调色板。 如果低于该比率,请与创意团队合作,为未通过检查的颜色获取较暗的值。
访问材料调色板生成器
单击左侧框右上角的颜色字段页。 用您自己的原色替换文本字段中的十六进制值,然后单击选择。
单击颜色字段左侧的复制图标,然后选择适当的输出格式(在我们的例子中,它是 Angular JS2)。 复制调色板以在主题的 scss 文件中使用。
对你的口音和警告颜色重复这个过程。
分叉主题并将 realogy-theme.scss 中的调色板替换为您自己的。
Guidance on Specific Component Usage
Forms
使用表单时,确保字段使用下面显示的概述变体以获得理想的可读性和可读性。 可访问性:
<mat-form-field appearance="outline">
当字段有字符限制时,确保提示包括字符限制,并在字段下方对齐,以便用户了解他们离达到限制有多近。 以下示例:
<mat-form-field appearance="outline">
<mat-label>Last Name</mat-label>
<input matInput #nickname placeholder="Enter last name" maxlength="50" />
<mat-hint align="end">
{{nickname.value.length}} / 50
</mat-hint>
</mat-form-field >
如果将字符限制提示应用到文本区域字段,请在标记中包含 ng-trim="false" 以确保提示显示无误。 下面的示例:
<mat-form-field appearance="outline">
<mat-label>Comments</mat-label>
<textarea matInput name="CommentsBox" placeholder="Leave comments" maxlength="256" #Comments ng-trim="false"></textarea>
<mat-hint align="end">{{Comments?.value?.length}} / 256</mat-hint>
</mat-form-field>
Buttons
使用按钮时,我们为任何按钮(包括文本)使用 3 种标准样式。 在下面的示例标记中,有主要、次要和第三样式。
<button class="app-button" mat-raised-button color="primary">Filled</button>
<button class="app-button" mat-stroked-button mat-tooltip="This is a tooltip!" color="primary">Outlined</button>
<button class="app-button" color="primary" mat-button>Text</button>
填充按钮 使用 .mat-raised-button 和原色。 它们应该仅限于页面上的主要操作。
Outlined buttons 使用 .mat-stroked-button 和 primary 颜色。 它们应该包括屏幕上的任何辅助操作,其中较大的可见触摸目标是合适的。
文本按钮 使用原色的 .mat-button。 它们应该包括取消和; 关闭对话框和类似用例的操作。
Select
使用材料选择菜单时,如果选项包括 4 个或更多项目,请执行此操作。
如果存在的项目较少,并且有足够的空间预先显示项目,则按钮切换可能更合适。
如果组件需要多选,请在组件上包含多个属性,如下所示:
<mat-select [formControl]="states" multiple>
Dialog
使用对话框时,尝试将包含的操作限制为主要操作以及取消/关闭对话框的能力。
在对话框的右下角显示主要操作,在其左侧显示取消操作。 请参见下面的示例:
<div matDialogActions>
<button mat-button color="primary" [matDialogClose]="dialogInput.value">Cancel</button>
<button mat-raised-button color="primary"[matDialogClose]="dialogInput.value">Call to action</button>
</div>
Tables
当使用具有多列的表格时,其中的数据旨在跨多行进行比较 - 将第一列设为粘性。 为第一列提供不超过 40vw 的最大宽度,以确保跨多个列的数据可以在较小的视口中进行比较,并且用户不会错过其他列中的数据。
具有粘性列的示例表可能如下所示:
<div class="example-container mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
<!-- Name Column -->
<ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef> Weight </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Symbol </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
理想情况下,如果特定列的内容包含字母或数字字符串,您将启用用户对列的排序。 为此,表格需要包含 matSort 属性,标签行中的列标题需要 mat-sort-header。 由于排序标题被视为按钮,因此请确保列标题标签文本简洁,因为它不会换行。 当这些标签超出可用空间时,它们会在切断之前尽可能地水平延伸。
Floating Action Buttons
使用浮动操作按钮时,请确保它用于页面上的主要附加操作,或用于在您的应用程序中提供持久访问的一组通用操作。 使用主要颜色以确保它从内容中脱颖而出。 如果您希望浮动操作按钮包含子项,就像您在 Google 日历上看到的那样 - 请参阅自定义快速拨号实现< /a>。 Angular Material 库的组件缺少开箱即用的功能。 有关快速拨号行为的其他指南,请参阅 Google 文档。
下面是一个简单的浮动操作按钮示例:
<button mat-fab class="app-fab"color="primary">
<mat-icon aria-label="Help">help</mat-icon>
</button>
Extended Floating Action Buttons
当使用扩展浮动操作按钮时,我们将它们定位到页面的右上角,但不固定它们的位置 -这样用户就可以将它们滚动到视图之外。 此处的目的是让操作在页面上脱颖而出,但不会造成页面上的多个持久 ui 元素阻碍内容的场景。 虽然谷歌建议将它们放置在页面的左上角或右下角,但它们与右下角的标准浮动操作按钮的位置冲突,并且通常带有沉重的标题和左上角的顶级导航。
Datepickers
确保日期选择器像其他表单字段一样包含轮廓外观。 以下示例:
<mat-form-field appearance="outline">
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Sliders
更改数值时始终在滑块上显示缩略图标签。 如果表示的值包含大量数字,请使用简写 (500k) 或使用标签描述该值以千/百万等为单位。下面是一个示例:
<mat-card>
<mat-card-content>
<h2 class="example-h2">Slider</h2>
<mat-slider class="example-margin" color="primary" thumbLabel>
</mat-slider>
</mat-card-content>
<mat-card-content>
<h2 class="example-h2">Slide Toggle</h2>
<mat-slide-toggle color="primary" [disabled]="slider.disabled" [checked]="slider.checked" (change)="slider.checked = !slider.checked">Slide me!</mat-slide-toggle>
</mat-card-content>
</mat-card>
Chips
使用筹码时,我们需要注意一些样式覆盖(请参阅 app.component.scss)。 为了保持使用的一致性,我们将纸条中的所有文本保持小写,并应用一些样式更改以确保纸条与标准按钮区分开来。 除了传统上用作所应用过滤器的指示符之外,您还可以使用条码表示适用于一段内容的标签和类别。 在这些情况下,请务必将 selectable 设置为 false。 例如:
<mat-card>
<mat-card-content>
<h2 class="example-h2">Material Chips</h2>
<mat-chip-list [selectable]="false">
<mat-chip [selectable]="false">
Chip
</mat-chip>
<mat-chip [selectable]="false">
Another Chip
</mat-chip>
</mat-chip-list>
</mat-card-content>
</mat-card>
Checkboxes
当使用复选框时,将颜色设置为原色,这样它们看起来是一致的叉积。 示例:
<mat-checkbox color="primary">Unchecked</mat-checkbox>
Radio Buttons
与复选框一样,将单选按钮颜色设置为主要颜色以保持一致性。 此外,为单选组内的项目赋予值,以便在页面可能有多个组的情况下,它们的行为符合预期。 参考如下:
<mat-radio-group>
<mat-radio-button color="primary" name="symbol" value="1">Option 1</mat-radio-button>
<br><br>
<mat-radio-button color="primary" name="symbol" value="2">Option 2</mat-radio-button>
<br><br>
<mat-radio-button color="primary" name="symbol" value="3">Option 3</mat-radio-button>
</mat-radio-group>
Icon Buttons
使用图标按钮时,建议将它们与工具提示一起使用,并确保提供 aria-labels 以实现辅助功能。 在我们的产品套件中,我们通常使用 fontawesome pro 图标字体的常规变体。 对于可供您使用的字形列表,您可以使用此备忘单作为参考。
Button Toggles
在单选组的位置使用按钮切换,其中一些值的触摸友好选择会更合适。 在应用默认选择的情况下使用,并尽量避免空状态。 当可供用户选择的项目少于 4 个时,请使用按钮切换而不是选择菜单。 按钮切换中的文本应保持简洁。 我们的组件样式覆盖将组中的焦点项目设置为我们主题的主要颜色:
.mat-button-toggle-button:focus {
background-color:mat-color($primary, 500);
color:white;
}
Progress Indicators
根据上下文,可以使用 Progress Spinners 和 Progress Bars。 如果它不会影响性能或需要比其价值更多的工作,则确定性进展优于不确定性。 在内容通常会在 1 秒或更短时间内加载的情况下,不确定是完全可以接受的。
Spinners 通常用于在页面上用户位置下方加载其他内容,例如,如果列表以 10 个为一组显示。如果内容没有框架加载占位符,spinners 是一个很好的选择.
进度条 通常在指示器位于与内容相邻的固定位置时使用,并且比那些涉及内容消费的应用程序更适合面向任务的应用程序。
在这两种情况下,我们都在实施时应用了原色以确保它们被注意到。 见下文:
<mat-card>
<mat-card-content>
<mat-progress-spinner class="example-margin" color="primary" mode="indeterminate">
</mat-progress-spinner>
</mat-card-content>
</mat-card>
<mat-card>
<mat-card-content>
<label>
<mat-progress-bar class="app-progress" mode="indeterminate" aria-label="Indeterminate progress-bar example"></mat-progress-bar>
</label>
<label>
<mat-progress-bar class="app-progress" color="primary" mode="determinate" [value]="progress" aria-label="Determinate progress-bar example"></mat-progress-bar>
</label>
</mat-card-content>
</mat-card>
Typography
我们的排版 scss 文件包含 Angular Material 中常用的排版类。 .mat-h1 - .mat-5、.mat-body、.mat-display-2 - .mat-display-4 等。我们使用 REM 单位进行排版,以确保用户在不同浏览器缩放级别下的可读性. 如果用户的浏览器/设置为 100% 缩放,我们的相对单位假定默认字体大小为 16pt。 要更改应用程序中特定元素的字体大小,请根据需要在您的 CSS 中提供它们。 建议在段落、按钮、选项卡等常用元素上使用确定的字体大小,以确保所有用户都可以快速扫描功能并轻松阅读内容。
Elevation
为了赋予对象深度,材料设计可以在对象上使用高度属性,该属性可以为该对象提供阴影,而不是提供框阴影样式。 要使用提升,请确保您的主题已导入并使用以下帮助器指定: '''
.some-component{ @include垫高(2); } ''' 使用不同的值会改变对象的感知深度,其中 8 可能会提供比 2 更重的阴影。 了解海拔助手。
Realogy Angular Material Theme
This theme captures colors applied to Angular Material Components for use when building Realogy products.
Additionally, typography and component style overrides are provided to help align with our style guide and provide consistency in implementation.
See Angular Material component documentation
See example styles applied on StackBlitz ⚡️
See Google's guidelines on best practices
Installation
Install Angular Material and it's peer dependencies as described on material.angular.io
Skip including a prebuild theme
Install theme via npm. npm install @abt-desk/realogy-mat-theme
Add following code to your global style.scss
@import '~@abt-desk/realogy-mat-theme/src/theme'; @include angular-material-theme();
Copy the contents of components.scss to your global style.scss file
Rebranding
If you'd like to apply a new brand to make use of a material theme, please note the following:
Establish your primary, accent and warn (optional) colors. If your brand palette lacks an accent color, you can use the same values in primary for your accent. Make sure you have your color values in hex format.
Test the contrast of your chosen colors for accessibility. Put the values in the foreground color field and click outside the field to return a contrast ratio.
That value must be 4.5:1 or greater to ensure the palette will be applied in a way that's compliant with accessibility standards. If it's under that ratio, work with creative teams to acquire a darker value for colors that don't pass the check.
Visit the Material Palette Generator
Click on the color field in the top right of the box on the left of the page. Replace the hex value in the text field with your own for your primary color and click choose.
Click the copy icon to the left of the color field, and select the appropriate output format (in our case, it's Angular JS2). Copy the palette to use in your theme's scss file.
Repeat the process for your accent and warn colors.
Fork the theme and replace the palettes in realogy-theme.scss with your own.
Guidance on Specific Component Usage
Forms
When using forms, ensure fields are using the outlined variation shown below for ideal readability & accessibility:
<mat-form-field appearance="outline">
When fields have character limits, ensure the hint includes the character limit, aligned at the end below the field so that users understand how close they are to reaching the limit. Example below:
<mat-form-field appearance="outline">
<mat-label>Last Name</mat-label>
<input matInput #nickname placeholder="Enter last name" maxlength="50" />
<mat-hint align="end">
{{nickname.value.length}} / 50
</mat-hint>
</mat-form-field >
If applying a character limit hint to a textarea field, include ng-trim="false" in the markup to ensure the hint displays without errors. Example below:
<mat-form-field appearance="outline">
<mat-label>Comments</mat-label>
<textarea matInput name="CommentsBox" placeholder="Leave comments" maxlength="256" #Comments ng-trim="false"></textarea>
<mat-hint align="end">{{Comments?.value?.length}} / 256</mat-hint>
</mat-form-field>
Buttons
When using buttons, we're making use 3 standard styles for any buttons including text. In the example markup below there's a primary, secondary and tertiary style.
<button class="app-button" mat-raised-button color="primary">Filled</button>
<button class="app-button" mat-stroked-button mat-tooltip="This is a tooltip!" color="primary">Outlined</button>
<button class="app-button" color="primary" mat-button>Text</button>
Filled buttons use .mat-raised-button with a color of primary. They should be limited to the primary action on the page.
Outlined buttons use .mat-stroked-button with a color of primary. They should include any secondary actions on a screen where a larger visible touch target is appropriate.
Text buttons use .mat-button with a color of primary. They should include cancel & close actions on dialogs and similar use cases.
Select
When using the material select menu, do so in cases where the options include 4 or more items.
If fewer items exist, a button toggle may be more appropriate if there's room to display items upfront.
In cases where multiple select is needed on the component, include the multiple property on the component as referenced below:
<mat-select [formControl]="states" multiple>
Dialog
When using the dialog, try to limit included actions to a primary action and the ability to cancel/close the dialog.
Display the primary action on the bottom right of the dialog, with the cancel action to its left. See example below:
<div matDialogActions>
<button mat-button color="primary" [matDialogClose]="dialogInput.value">Cancel</button>
<button mat-raised-button color="primary"[matDialogClose]="dialogInput.value">Call to action</button>
</div>
Tables
When using tables with multiple columns where the data is intended to be compared across multiple rows - make the first column sticky. Give that first column a max-width of no more than 40vw to ensure data across multiple columns can be compared in smaller viewports and a user doesn't miss out on data in other columns.
An example table with sticky columns might look like the following:
<div class="example-container mat-elevation-z8">
<table mat-table [dataSource]="dataSource">
<!-- Name Column -->
<ng-container matColumnDef="name" sticky>
<th mat-header-cell *matHeaderCellDef> Name </th>
<td mat-cell *matCellDef="let element"> {{element.name}} </td>
</ng-container>
<!-- Position Column -->
<ng-container matColumnDef="position">
<th mat-header-cell *matHeaderCellDef> No. </th>
<td mat-cell *matCellDef="let element"> {{element.position}} </td>
</ng-container>
<!-- Weight Column -->
<ng-container matColumnDef="weight">
<th mat-header-cell *matHeaderCellDef> Weight </th>
<td mat-cell *matCellDef="let element"> {{element.weight}} </td>
</ng-container>
<!-- Symbol Column -->
<ng-container matColumnDef="symbol">
<th mat-header-cell *matHeaderCellDef> Symbol </th>
<td mat-cell *matCellDef="let element"> {{element.symbol}} </td>
</ng-container>
<tr mat-header-row *matHeaderRowDef="displayedColumns"></tr>
<tr mat-row *matRowDef="let row; columns: displayedColumns;"></tr>
</table>
</div>
Ideally, if the contents of a particular column contain alpha or numeric strings, you would enable user sorting on the columns. To do so, the table would need to include the matSort property, and column headers in the label row would need mat-sort-header. Because sort headers are treated like buttons, be sure to keep the column header label text succinct, as it will not wrap to a second line. When those labels exceed available space, they extend as much as they can horizontally before cutting off.
Floating Action Buttons
When using the floating action button, ensure it's for either a primary additive action on a page, or a common set of actions that would provide persistent access within your application. Use a color of primary to ensure it stands out from content. If you would like the floating action button to contain children, as you might see on Google Calendar - refer to custom speed dial implementations. The Angular Material library's component lacks that functionality out of the box. For additional guidance on speed dial behavior, refer to Google documentation.
Here's an example of a simple floating action button:
<button mat-fab class="app-fab"color="primary">
<mat-icon aria-label="Help">help</mat-icon>
</button>
Extended Floating Action Buttons
When using extended floating action buttons, we're positioning them towards the top right of the page, but not fixing their position - so users can scroll them out of view. The intent here is to have an action that stands out on the page, but wouldn't create a scenario where multiple persistent ui elements on the page obstruct content. While Google recommends placing these towards the top left or bottom right of the page, they conflict with positioning of standard floating actions buttons in the bottom right, and often with heavy headers and top level navigation towards the top left.
Datepickers
Ensure datepickers include an outlined appearance like other form fields. Example below:
<mat-form-field appearance="outline">
<input matInput [matDatepicker]="picker" placeholder="Choose a date">
<mat-datepicker-toggle matSuffix [for]="picker"></mat-datepicker-toggle>
<mat-datepicker #picker></mat-datepicker>
</mat-form-field>
Sliders
Always show a thumb label on sliders when changing numerical values. If that values represented include large numbers, use shorthand (500k) or have the label describe that the value is in thousands/millions/etc.. Below is an example:
<mat-card>
<mat-card-content>
<h2 class="example-h2">Slider</h2>
<mat-slider class="example-margin" color="primary" thumbLabel>
</mat-slider>
</mat-card-content>
<mat-card-content>
<h2 class="example-h2">Slide Toggle</h2>
<mat-slide-toggle color="primary" [disabled]="slider.disabled" [checked]="slider.checked" (change)="slider.checked = !slider.checked">Slide me!</mat-slide-toggle>
</mat-card-content>
</mat-card>
Chips
When using chips, we have a few style overrides to be aware of (see app.component.scss). For consistency in use, we're keeping all text in chips lowercase, as well as applying some style changes to ensure that chips are distinguished from standard buttons. In addition to their traditional use as signifiers of applied filters, you can also use chips as representations of tags and categories applicable to a piece of content. In those cases, be sure to set selectable to false. For example:
<mat-card>
<mat-card-content>
<h2 class="example-h2">Material Chips</h2>
<mat-chip-list [selectable]="false">
<mat-chip [selectable]="false">
Chip
</mat-chip>
<mat-chip [selectable]="false">
Another Chip
</mat-chip>
</mat-chip-list>
</mat-card-content>
</mat-card>
Checkboxes
When using checkboxes, set the color to primary, so they appear consistent cross-product. Examples:
<mat-checkbox color="primary">Unchecked</mat-checkbox>
Radio Buttons
As with checkboxes, set radio button colors to primary for consistency. Additionally, give items within radio groups values, so that in cases where a page may have multiple groups, they behave as expected. Reference below:
<mat-radio-group>
<mat-radio-button color="primary" name="symbol" value="1">Option 1</mat-radio-button>
<br><br>
<mat-radio-button color="primary" name="symbol" value="2">Option 2</mat-radio-button>
<br><br>
<mat-radio-button color="primary" name="symbol" value="3">Option 3</mat-radio-button>
</mat-radio-group>
Icon Buttons
When using icon buttons, it's advised to use them with tooltips and ensure aria-labels are provided for accessibility. Within our product suite, we're typically using the regular variant of the fontawesome pro icon font. For a list of glyphs at your disposal, you can use this cheatsheet as reference.
Button Toggles
Use button toggles in places of a radio group where a touch friendly selection of a few values would be more appropriate. Use in cases where there's a default selection applied and try to avoid an empty state. When there are fewer than 4 items for a user to choose from, use a button toggle instead of a select menu. Text in button toggles should be kept succinct. Our component style overrides sets the focused item in a group to our theme's primary color:
.mat-button-toggle-button:focus {
background-color:mat-color($primary, 500);
color:white;
}
Progress Indicators
Depending on the context, both Progress Spinners and Progress Bars can be used. If it wouldn't affect performance or require more work than its worth, determinate progress is preferred to indeterminate. In cases where content would typically load within 1 second or less, indeterminate is perfectly acceptable.
Spinners are typically used when loading additional content below a user's position on the page, for example, if listings are revealed in sets of 10. In cases where content has no skeleton loading placeholder, spinners make a good alternative.
Progress bars are typically used when the indicator is in a fixed position adjacent to content, and is more suited to task oriented applications than those involving content consumption.
In both cases, we're applying a primary color on implementation to ensure they're noticed. See below:
<mat-card>
<mat-card-content>
<mat-progress-spinner class="example-margin" color="primary" mode="indeterminate">
</mat-progress-spinner>
</mat-card-content>
</mat-card>
<mat-card>
<mat-card-content>
<label>
<mat-progress-bar class="app-progress" mode="indeterminate" aria-label="Indeterminate progress-bar example"></mat-progress-bar>
</label>
<label>
<mat-progress-bar class="app-progress" color="primary" mode="determinate" [value]="progress" aria-label="Determinate progress-bar example"></mat-progress-bar>
</label>
</mat-card-content>
</mat-card>
Typography
Our typography scss file includes commonly used typographic classes in Angular Material. .mat-h1 - .mat-5, .mat-body, .mat-display-2 - .mat-display-4, etc.. We are using REM units for typography to ensure readability for users of drastically varying browser zoom levels. Our relative units assume a default font size of 16pt if a user has their browser/settings at a 100% zoom. To change font sizing on specific elements in your application, provide them in your css as needed. It's recommended to use established font sizes on common elements such as paragraphs, buttons, tabs and others to ensure all users can quickly scan for functionality and easily read content.
Elevation
In order to give objects depth, material design can make use of an elevation property on an object that would serve to give that object a shadow in lieu of providing box-shadow styling. To use elevation, ensure your theme is imported and specify using the following helper: '''
.some-component{ @include mat-elevation(2); } ''' Using different values will change the perceived depth of the object, where 8 might provide a much heavier shadow than a 2 would. Learn about elevation helpers.
你可能也喜欢
- @-0/utils 中文文档教程
- @1amageek/tradable 中文文档教程
- @1ziton/react-native-share-qr 中文文档教程
- @365werk/threesixfive-vue-library 中文文档教程
- @3fv/atlassian-oauth-connect 中文文档教程
- @3kles/kles-mi-service 中文文档教程
- @a-sync/opencv-build 中文文档教程
- @aalu1418/sponsored-erc721 中文文档教程
- @abcaustralia/postcss-to-camel-case 中文文档教程
- @abcum/ember-popups 中文文档教程