The CodeBlock is used to display, format, and highlight the syntax of code snippets.
Usage
When to use
- When displaying code examples and longer snippets of code that benefit from syntax highlighting.
When not to use
- As a full-blown code editor.
- As an embedded terminal or terminal emulator.
When to use a CodeBlock vs a Copy Snippet
There is some overlap in the copying functionality of the Copy Snippet and the CodeBlock. Which to use generally comes down to the complexity of the code/value displayed within the component, and whether the user benefits from seeing the larger context of the code example.
Use a CodeBlock:
- If viewing or displaying code is the primary purpose, and copying the code is secondary.
- If the example consists of a command, e.g., a
curl
andbash
script. These are oftentimes on a single line, but consist of multiple commands and functions.
Use a Copy Snippet:
- If copying the code is the primary purpose, and viewing the code is secondary.
- If allowing the user to copy an API key or other single value or string.
- If seeing the value in a larger context of where it's expected to be pasted into isn’t necessary.
Standalone
The isStandalone
property increases the portability of the CodeBlock to ensure that it can be used in different contexts. For example, a common use case of the CodeBlock is in a "standalone" context, which can be part of a form, multi-step process, and is generally a part of the normal layout flow.
Sometimes it may be necessary to use the CodeBlock in a more dense layout or nested within another component. In this circumstance, setting isStandalone
to false ensures that the CodeBlock fits alongside other elements, in a split view, or as part of a larger layout mechanism.
Header
Use a title
and/or description
in the header to provide additional information, instructions, or to label a CodeBlock. Both of these properties are optional, but including them can help to provide additional context about a specific block of code.
When not to use a header
There can be an overlap between content that you may choose to include in the header as a title
or description
, and content that is part of the normal layout flow in a headline or paragraph. If it is necessary to elevate this content in the hierarchy of the page, we recommend including it in the normal layout flow, rather than as a title
or description
within the CodeBlock.
CopyButton
Use a CopyButton within the CodeBlock to make copying the snippet a single action. More details can be found in the CopyButton guidelines.
Line selection
If a user needs to copy only a portion of the CodeBlock, the relevant portion can be selected with a cursor and copied via the keyboard or mouse.
Line numbers
Line numbers are displayed by default and can make longer blocks of code and snippets easier to parse. This is especially true in the case of logs and long configuration files that may have a higher degree of complexity.
Line highlighting
Use line highlighting to target and call attention to specific lines or multiple lines within a block of code.
Language
Language determines how syntax highlighting is applied and formatted within the block but is handled a bit differently between the Ember and Figma components.
The Ember component uses Prism.js to handle syntax highlighting and comes with a pre-defined set of languages.
In Figma we provide a handful of example languages that are intended to be representative of the end result in production. Syntax highlighting in Figma is a non-trivial process and requires the manual application of color styles to each "type" of code. Despite this, creating a custom code snippet with the CodeBlock is supported by typing/pasting into the text layer, but syntax highlighting will not be automatically applied.
Applying syntax highlighting
If you wish to create custom examples using the CodeBlock, we publish all of the relevant syntax highlighting styles in the HDS Foundations library. However, due to the number of languages supported by the component, the color styles use a generic naming schema (e.g., cyan, red, purple) to remain as agnostic as possible when being applied to different languages.
For more details around syntax visit the specifications.
How to use this component
The basic invocation requires a @value
argument. The component encodes this argument before displaying it.
<Hds::CodeBlock
@value="aws ec2 --region us-west-1 accept-vpc-peering-connection"
/>
Title and description
Optionally, you can pass a title and/or a description.
CodeBlock title
CodeBlock description
<Hds::CodeBlock
@language="bash"
@value="aws ec2 --region us-west-1 accept-vpc-peering-connection"
as |CB|>
<CB.Title>
CodeBlock title
</CB.Title>
<CB.Description>
CodeBlock description
</CB.Description>
</Hds::CodeBlock>
Language
The language
argument sets the syntax highlighting used. We only support the following languages: bash
, go
, hcl
, json
, log
, ruby
, shell-session
, and yaml
. If you need additional languages contact the Design Systems Team
<Hds::CodeBlock
@language="go"
@value="package main
import fmt
func main() {
fmt.Println(helloWorld)
}"
/>
Copy button
Set hasCopyButton
to true
to display a button for users to copy CodeBlock
content to their computer clipboard.
<Hds::CodeBlock
@language="javascript"
@hasCopyButton=
@value="let codeLang=`JavaScript`;
console.log(`I am ${codeLang} code`);"
/>
Line numbers
Line numbers are displayed by default. Set hasLineNumbers
to false
to hide them.
<Hds::CodeBlock
@language="javascript"
@hasLineNumbers=
@value="let codeLang=`JavaScript`;
console.log(`I am ${codeLang} code`);"
/>
Line wrapping
By default, long lines of code will overflow the CodeBlock
container requiring users to scroll to view the full content. Setting hasLineWrapping
to true
will wrap long lines of code instead.
<Hds::CodeBlock
@language="javascript"
@hasLineWrapping=
@value="console.log(`I am JavaScript code`, `Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam`);"
/>
Highlight lines
Highlight either individual code lines or a range of code lines. (Examples: 2, 4
, 6-10
)
<Hds::CodeBlock
@language="javascript"
@highlightLines=
@value="import Application from `@ember/application`;
import Resolver from `ember-resolver`;
import loadInitializers from `ember-load-initializers`;
import config from `dummy/config/environment`;
export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
}
loadInitializers(App, config.modulePrefix);"
/>
Limit height
Code content uses auto
height by default but you can opt to set a maxHeight
value to save space. Vertical scrolling is enabled as part of this feature allowing users to scroll vertically to view the overflowing content.
CodeBlock title
CodeBlock description
<Hds::CodeBlock
@language="javascript"
@maxHeight="105px"
@value="import Application from `@ember/application`;
import Resolver from `ember-resolver`;
import loadInitializers from `ember-load-initializers`;
import config from `dummy/config/environment`;
export default class App extends Application {
modulePrefix = config.modulePrefix;
podModulePrefix = config.podModulePrefix;
Resolver = Resolver;
}
loadInitializers(App, config.modulePrefix);"
as |CB|>
<CB.Title>
CodeBlock title
</CB.Title>
<CB.Description>
CodeBlock description
</CB.Description>
</Hds::CodeBlock>
Component API
This component uses prism.js under the hood.
value
string
CodeBlock
. The component encodes this argument before displaying it.
language
string
- bash
- go
- hcl
- json
- log
- ruby
- shell-session
- yaml
isStandalone
boolean
- true (default)
hasCopyButton
boolean
- false (default)
hasLineNumbers
boolean
- true (default)
@value
changes dynamically the line numbers will fail to update.
hasLineWrapping
boolean
- false (default)
true
, lines of code will wrap to fit the available space. Otherwise, horizontal scrolling is enabled if lines overflow the available space.
highlightLines
string
2, 4
, 6-10
)
maxHeight
string
- auto (default)
CodeBlock
content exceeds the maximum height a vertical scrollbar is enabled. This value applies to the code content only and does not include the header element (title and/or description).
Contextual components
<[A].Title>
yielded component
"title"
block. Content inherits its style.Accepts complex content, such as logic/conditionals, HTML elements, other Ember components, etc. Styling is applied for simple HTML elements, such as
strong
, em
, a
, code/pre
. Application teams will need to style the rest of the content.This component supports use of
...attributes
.
<[A].Description>
yielded component
"description"
block. Content inherits its style.Accepts complex content, such as logic/conditionals, HTML elements, other Ember components, etc. Styling is applied for simple HTML elements, such as
strong
, em
, a
, code/pre
. Application teams will need to style the rest of the content.This component supports use of
...attributes
.
Anatomy
Element | Usage |
---|---|
Title | Optional |
Description | Optional |
Line numbers | Optional |
Copy button | Optional |
Code snippet | Required |
Highlighted line | Optional |
Syntax highlighting
To aid in understanding how the highlighting theme is applied via Prism's tokens, we've provided a high-level, non-exhaustive list of token names and how they might be applied depending on the syntax.
Color | Usage |
---|---|
Cyan | Property, url, or operator |
Blue | Function, builtins |
Orange | Strings, characters |
Purple | Booleans, numbers |
Green | Keywords, class names, saving the world |
Red | Important items |
White | Default color within the code block, also used for punctuation (< , { } , = , etc) |
Gray | Used for comments across languages |
Working directly with an engineering partner can reveal exactly how a snippet will render in the component and should be the first course of action when creating custom snippets. Understanding Prism's token hierarchy can also be helpful when creating examples.
If you have questions or need assistance creating custom examples, don’t hesitate to reach out the the HDS team for support.
States
Focus with header content
Focus without header content
Conformance rating
When used as recommended, there should not be any WCAG conformance issues with this component.
Applicable WCAG Success Criteria
This section is for reference only. This component intends to conform to the following WCAG Success Criteria:
-
1.3.1
Info and Relationships (Level A):
Information, structure, and relationships conveyed through presentation can be programmatically determined or are available in text. -
1.3.2
Meaningful Sequence (Level A):
When the sequence in which content is presented affects its meaning, a correct reading sequence can be programmatically determined. -
1.4.1
Use of Color (Level A):
Color is not used as the only visual means of conveying information, indicating an action, prompting a response, or distinguishing a visual element. -
1.4.10
Reflow (Level AA):
Content can be presented without loss of information or functionality, and without requiring scrolling in two dimensions. -
1.4.11
Non-text Contrast (Level AA):
The visual presentation of the following have a contrast ratio of at least 3:1 against adjacent color(s): user interface components; graphical objects. -
1.4.12
Text Spacing (Level AA):
No loss of content or functionality occurs by setting all of the following and by changing no other style property: line height set to 1.5; spacing following paragraphs set to at least 2x the font size; letter-spacing set at least 0.12x of the font size, word spacing set to at least 0.16 times the font size. -
1.4.3
Minimum Contrast (Level AA):
The visual presentation of text and images of text has a contrast ratio of at least 4.5:1 -
1.4.4
Resize Text (Level AA):
Except for captions and images of text, text can be resized without assistive technology up to 200 percent without loss of content or functionality. -
2.1.1
Keyboard (Level A):
All functionality of the content is operable through a keyboard interface. -
2.1.2
No Keyboard Trap (Level A):
If keyboard focus can be moved to a component of the page using a keyboard interface, then focus can be moved away from that component using only a keyboard interface. -
2.4.3
Focus Order (Level A):
If a Web page can be navigated sequentially and the navigation sequences affect meaning or operation, focusable components receive focus in an order that preserves meaning and operability. -
2.4.7
Focus Visible (Level AA):
Any keyboard operable user interface has a mode of operation where the keyboard focus indicator is visible. -
4.1.2
Name, Role, Value (Level A):
For all user interface components, the name and role can be programmatically determined; states, properties, and values that can be set by the user can be programmatically set; and notification of changes to these items is available to user agents, including assistive technologies.
Support
If any accessibility issues have been found within this component, let us know by submitting an issue.