@h2qutc/angular-material-components 日期时间选择器和 SVG/third-party 图标

@h2qutc/angular-material-components datetime-picker and SVG/third-party icons

我从事的项目使用 Font Awesome SVG 图标和@hgho(组件作者)的 Angular Material 图标 as described here, so far so good. It requires a datetime picker, and since Angular Material does not provide the component yet I opted for @angular-material-components/datetime-picker suggested in this SO answer

问题是时间选择器uses Material font icons,与上述方法冲突。在未加载网络字体的情况下,mat-icon 将连字显示为纯文本,我认为这是不可接受的:

我正在寻找一个解决方案:

  1. 以某种方式修复了图标。
  2. 允许使用 Font Awesome 图标代替 "expand_more" / "expand_less" / "done" 以实现应用程序范围内的一致性。
  3. 最小化额外数据量。当然,我可以只包含三个图标的整个 Material 图标字体,但这只是作为最后的手段。

我评估了几种方法:

  1. 查看 mat-iconMatIconRegistry API 是否提供任何合适的东西,注册 SVG 图标以用作字体图标连字的选项将是完美的。找到了a relevant issue,但是还没有解决
  2. 分叉组件,修改模板。这应该绝对有效,但您现在必须支持分叉,并且依赖项更新会变得不那么顺利。
  3. 看看是否the component API has inputs for custom icon ng-template. The answer is "no", but the sibling file input component does support custom icon, so maybe something similar will be added to the time picker too? Here's an issue tracking this.
  4. 生成带有三个图标的自定义轻量级字体。 This issue suggests to use Fontello for such cases, but it does not support Material Icons yet, so I used Icomoon 代替。生成的 WOFF 是 1.8kb 非 gzipped。

自定义字体解决方案(#4)详解:

  1. 转到Icomoon, choose icons from the set or upload your own.
  2. 确保导出的字形连字符合您的用例。
  3. 将字体加载到您的应用中,添加缺少的样式。样式与 what's loaded from Google Fonts 相同,但使用 @font-face {src: }.
  4. 中的自定义字体文件
// @angular-material-components/datetime-picker requires Angular Material icon ligatures font,
// but we use Font Awesome SVG icons.

// The custom font includes only three icons required for datetime-picker:
// 1. expand_more
// 2. expand_less
// 3. done
@font-face {
  font-family: 'custom-material';
  src: url('assets/fonts/custom-material.woff') format('woff');
  font-weight: normal;
  font-style: normal;
  font-display: block;
}

ngx-mat-datetime-content {
  // The same style as from Material Icons from Google Fonts, which we don't import
  .material-icons {
    font-family: 'custom-material';
    font-weight: normal;
    font-style: normal;
    font-size: 24px;
    line-height: 1;
    letter-spacing: normal;
    text-transform: none;
    display: inline-block;
    white-space: nowrap;
    word-wrap: normal;
    direction: ltr;
    -webkit-font-feature-settings: 'liga';
    -webkit-font-smoothing: antialiased;
  }
  .mat-icon {
    background-repeat: no-repeat;
    display: inline-block;
    fill: currentColor;
    height: 24px;
    width: 24px;
  }
}

结果:

另一种方法是使用以下方式导入图标:

npm install material-design-icons

然后通过以下方式在 style.css 中声明:

@import '~material-design-icons/iconfont/material-icons.css';

我无法包含 repo,因为将 angular-design-icons 添加到 stackblitz 的依赖项时出现问题。