通过


小组件的基本样式

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022

小窍门

有关最新的扩展开发指南,包括主题处理以及从 VSS.SDK 的迁移,请参阅 Azure DevOps 扩展 SDK 开发人员门户

使用小组件 SDK 提供的基本样式,以便跨仪表板小组件保持一致的外观。

若要包括小组件样式,请在小组件初始化期间调用 WidgetHelpers.IncludeWidgetStyles()

WidgetHelpers.IncludeWidgetStyles();

这会将 sdk-widget.css 加载到小组件的 iframe 中,为字体系列、字号、边距、填充、标题和链接提供样式。

对于小组件配置面板,请改为调用 WidgetHelpers.IncludeWidgetConfigurationStyles()

WidgetHelpers.IncludeWidgetConfigurationStyles();

这会加载 sdk-widget-configuration.css,它为字体系列、字号和常见表单元素(例如 inputtextareaselect)提供样式。

注释

要应用这些样式,请在包含组件的 HTML 元素上添加 widget 类。 所有 sdk-widget.css 样式的范围都限定为此类。 同样,在包含小组件配置的元素上添加类 widget-configuration

有关工作示例,请参阅 扩展示例

小组件正文、标题和说明

通过在小组件的容器元素上添加 widget 类,可以自动获取小组件内容的填充、字体和颜色。

始终为小组件添加标题,以便用户可以一目了然地识别其用途。 使用<h2>title类。 这也有助于屏幕阅读器识别仪表板上的不同小组件。

带有标题和描述的小组件

设计原则: 小组件应具有标题。 将 <h2> 标记与 title 类一起使用。

若要添加描述,请在包含小组件描述的元素上使用 description 类。

设计原则:description 类用于小组件说明。 即使在小组件上下文外部读取时,说明也应该有意义。

	<div class="widget">
	    <h2 class="title">Widget title</h2>	
		<div class="description">The widget description is used to describe the widget. It makes sense even when read outside of the widget context.</div>
		<p>Place widget content here.</p>
	</div>

小组件标题和副标题

字幕补充标题,如果脱离上下文阅读,可能没有意义。

带标题和副标题的小组件

设计原则: 使用 subtitle 类提供有关控件的详细信息。

使用titleinner-titlesubtitle类,以获取标题和副标题组合的正确字体、颜色和边距。 副标题的颜色相对于标题更为低调。

	<div class="widget">
	    <h2 class="title">
			<div class="inner-title">Widget title</div>
			<div class="subtitle">Widget subtitle</div>
		</h2>
		<div class="content">
			Place widget content here.  
		</div>
	</div>

标题和副标题组合的建议:

  • 在副标题的同一行中使用类似于 <span> 的内联元素以与标题一起显示。
  • 要在新行上显示副标题,请使用块元素,例如 <div>

某些小组件包含带有图标、文字和子文字的链接。

带有图标及文本的链接小部件

设计原则: 使用带有图标和子文本的链接,使链接的用途明显于用户。 确保图标符号化链接的目标。

若要获得相同的外观,请使用以下 HTML 结构和类。

	<div class="widget">
	    <h2 class="title">Widget title</h2>
		<div class="content">
			<p>Place your content here.</p>
			<a class="link-with-icon-text" href="http://bing.com" target="_blank">
				<span class="icon-container" style="background-color: #68217A"></span>
				<div class="title">
					Primary link text
					<div class="subtitle">Link subtext</div>
				</div>
			</a>		
		</div>
	</div>

计数器

对于显示计数的小组件,请在包含数字的元素上添加 big-count 类。 查询磁贴和代码磁贴小组件使用相同的样式。

计数器小组件

设计原则: 使用 big-count 类以大字体显示数字。 不要将其与非数字字符一起使用。

<div class="widget">
    <h2 class="title">Counter widget</h2>
	<div class="big-count">223</div>
	<div>Additional text</div>
</div>

可单击的小组件

若要使小组件可单击,使其在任意位置点击即可导航到另一个页面:

  1. 将锚点标签作为小组件容器元素的子元素添加。
  2. 将所有小组件内容放入锚标签中。
  3. 添加 target="_blank" 到锚标签中,使链接在新选项卡中打开。
  4. clickable 类添加到 widget 容器。

如果没有clickable类名,默认的蓝色链接颜色将应用于小组件中的所有文本。 该 clickable 类还提供用于键盘导航的自定义焦点指示器。

设计原则: 使用 clickable 类和 <a> 标记使整个小组件可单击。 当小组件汇总另一页上可用的数据时,此模式非常有效。

<div class="widget clickable">
    <a href="https://bing.com"  target="_blank">
		<h2 class="title">Counter widget</h2>
		<div class="big-count">223</div>
		<div>Click me!</div>
	</a>
</div>

配置窗体元素

在小组件配置中使用以下类来设置常见的表单元素:

Form 元素 包装元素 准则
简单文本框 div 类名为“single-line-text-input”。 label使用元素在文本框旁边添加文本。 使用 input 元素创建文本框。 使用 placeholder 特性提供占位符文本。
复选框 fieldset 带有类名“复选框” 使用label元素在每个复选框旁边添加文本。 legend使用元素为复选框组添加标题。 在每个label元素上使用for属性,以帮助屏幕阅读器理解表单元素。
单选按钮 fieldset 具有类“radio” 使用label元素在每个单选按钮旁边添加文本。 legend使用元素为单选按钮组添加标题。 使用for属性在每个label元素上,以帮助屏幕阅读器理解表单元素。
下拉列表 div 类“下拉列表” 使用label元素在下拉列表旁边添加文本。 如果希望下拉列表占据宽度的一半,请将类“半”添加到包装 div 元素。 如果要使用 SDK 中的标准箭头图标,而不是浏览器提供的箭头图标,请使用 select 类“包装器”将元素包装到另一个 div 元素。
多行文本框 div 包含类“multi-line-text-input”。 使用 label 元素标记用作多行文本框的 textarea 元素。

以下示例使用表中列出的每个窗体元素。

小组件配置示例

<div class="widget-configuration">

    <div class="single-line-text-input" id="name-input">
        <label>Your name</label>
        <input type="text" value="Contoso"></input>
    </div>

    <div class="dropdown" id="query-path-dropdown">
        <label>Drop down</label>
        <div class="wrapper">
            <select>						
				<option value="Shared Queries/Feedback">Shared Queries/Feedback</option>
				<option value="Shared Queries/My Bugs">Shared Queries/My Bugs</option>
				<option value="Shared Queries/My Tasks">Shared Queries/My Tasks</option>							
			</select>
        </div>

        <fieldset class="checkbox" id="select-results">
            <legend>Select results to display</legend>
            <input type="checkbox" id="check-option1" value="id" name="check" checked="true">
            <label for="check-option1">Query ID</label><br/>
            <input type="checkbox" id="check-option2" value="name" name="check" checked="true">
            <label for="check-option2">Query Name</label><br/>
            <input type="checkbox" id="check-option3" value="createdBy" name="check" checked="true">
            <label for="check-option3">Created By</label><br/>
        </fieldset>

        <fieldset class="radio" id="display-options">
            <legend>Display as </legend>
            <input type="radio" id="radio-option1" value="ordered" name="radio" checked="true">
            <label for="radio-option1">Ordered List</label><br/>
            <input type="radio" id="radio-option2" value="unordered" name="radio">
            <label for="radio-option2">Unordered List</label><br/>
        </fieldset>

        <div class="multi-line-text-input">
            <label>Comments</label>
            <textarea></textarea>
        </div>
    </div>
</div>

验证错误消息

若要以与第一方小组件一致的方式显示表单元素下面的验证错误,请在每个窗体元素下添加以下代码片段:

<span class="validation-error">
	<span class="icon-error-exclamation"></span>
	<span class="validation-error-text"></span>
</span>

默认情况下,可见性处于隐藏状态。 若要显示错误消息,请查找相应的 validation-error-text 元素,设置其文本,并在其父元素上设置 visibility: visible

例如,若要在文本框为空时显示错误:

小组件配置错误示例

此代码的 html 为:

<div class="widget-configuration">
	<div class="single-line-text-input">
		<label>Your name</label>
		<input type="text" placeholder="Type Here">

		<span class="validation-error">
			<span class="icon-error-exclamation"></span>
			<span class="validation-error-text"></span>
		</span>
	</div>
</div>

以及 JavaScript:

const input = document.querySelector(".single-line-text-input input");
const errorText = document.querySelector(".single-line-text-input .validation-error-text");

input.addEventListener("input", function () {
    if (input.value === "") {
        errorText.textContent = "Please enter your name.";
        errorText.parentElement.style.visibility = "visible";
    } else {
        errorText.parentElement.style.visibility = "hidden";
    }
});