-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: Kiarokh Moattar <[email protected]> Co-authored-by: Lucy Chyzhova <[email protected]>
- Loading branch information
1 parent
e16cf63
commit 17633ab
Showing
10 changed files
with
435 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
export const helpAndDocumentation = ` | ||
### Help and Documentation | ||
_(Usability Heuristic #10)_ | ||
#### Summary | ||
Interface help comes in two forms: proactive and reactive. Proactive help is intended to get users familiar with an interface while reactive help is meant for troubleshooting and gaining system proficiency. | ||
#### Intro | ||
Websites and applications can offer two types of help: _proactive_ and _reactive_. | ||
- **Proactive help** is provided before the user has encountered a problem, in order to prevent issues. It includes [onboarding tutorials](https://www.nngroup.com/articles/mobile-app-onboarding/) and contextual tips. | ||
- **Reactive help** in contrast includes materials such as documentation, videos, or even tutorials for those situations when users have an issue and they seek out advice to address it. (Even though some users may consume such materials proactively, it is rare that they do so.) | ||
`; | ||
|
||
export const link = { | ||
href: 'https://www.nngroup.com/articles/help-and-documentation/', | ||
title: 'Opens in a new window', | ||
target: '_blank', | ||
text: 'Read more...', | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
import { Component, h } from '@stencil/core'; | ||
|
||
/** | ||
* Help with custom open direction | ||
*/ | ||
@Component({ | ||
tag: 'limel-example-open-direction', | ||
shadow: true, | ||
}) | ||
export class HelpOpenDirectionExample { | ||
public render() { | ||
return ( | ||
<limel-help | ||
openDirection="right" | ||
value="This popover is opened on the right side of the trigger." | ||
/> | ||
); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
:host(limel-example-placement) { | ||
--form-padding: 1rem; | ||
} | ||
|
||
ul, | ||
li { | ||
all: unset; | ||
display: flex; | ||
} | ||
|
||
ul { | ||
flex-direction: column; | ||
padding: 0 var(--form-padding); | ||
} | ||
|
||
li { | ||
position: relative; | ||
flex-direction: row; | ||
align-items: center; | ||
} | ||
|
||
hr { | ||
all: unset; | ||
display: block; | ||
margin: 1.5rem 0 0 0; | ||
border-bottom: 1px solid rgb(var(--contrast-600)); | ||
} | ||
|
||
limel-checkbox { | ||
margin-right: 0.5rem; | ||
} | ||
|
||
limel-help { | ||
&.pull-left { | ||
position: absolute; | ||
left: calc(var(--form-padding) * -1); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
import { Component, h } from '@stencil/core'; | ||
|
||
const helpAutoUpdates = | ||
'Automatically download and install updates, when the phone is connected to a Wi-Fi, is charging and is locked.'; | ||
const helpBetaUpdates = | ||
'Receive updates on this phone to test-drive pre-release versions of the operating system and provide feedback to help us become even better.'; | ||
|
||
/** | ||
* Placement of the trigger element and the layout | ||
* | ||
* The trigger element of the help component can be placed | ||
* before or after the element it is describing. | ||
* | ||
* However, to provide a consistent layout, we recommend placing the | ||
* trigger element on the left side of all elements. | ||
* | ||
* Just make sure the elements are aligned correctly, | ||
* even when there is no help component beside them. | ||
*/ | ||
@Component({ | ||
tag: 'limel-example-placement', | ||
shadow: true, | ||
styleUrl: 'help-placement.scss', | ||
}) | ||
export class HelpPlacementExample { | ||
public render() { | ||
return [ | ||
<h4>Better layout</h4>, | ||
<ul> | ||
<li> | ||
<limel-help value={helpAutoUpdates} class="pull-left" /> | ||
<limel-checkbox label="Automatic updates" /> | ||
</li> | ||
<li> | ||
<limel-help value={helpBetaUpdates} class="pull-left" /> | ||
<limel-checkbox label="Beta updates" /> | ||
</li> | ||
<li> | ||
<limel-checkbox label="Notify after update" /> | ||
</li> | ||
</ul>, | ||
<hr />, | ||
<h4>Worse layout</h4>, | ||
<ul> | ||
<li> | ||
<limel-checkbox label="Automatic updates" /> | ||
<limel-help value={helpAutoUpdates} /> | ||
</li> | ||
<li> | ||
<limel-checkbox label="Beta updates" /> | ||
<limel-help value={helpBetaUpdates} /> | ||
</li> | ||
<li> | ||
<limel-checkbox label="Notify after update" /> | ||
</li> | ||
</ul>, | ||
]; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { Component, h } from '@stencil/core'; | ||
import { helpAndDocumentation, link } from './help-and-documentation'; | ||
|
||
/** | ||
* Help with the read more link | ||
* If a `readMoreLink` supplied, it will render a "Read more" link at the bottom of the content. | ||
* | ||
* Even though you can add a link anywhere in the content, it is recommended to | ||
* use the read more link. Because it will always be displayed at the bottom | ||
* of the popover after the content, does not scroll away with the content, | ||
* and it will be styled in a consistent way. | ||
* @link help-and-documentation.ts | ||
*/ | ||
|
||
@Component({ | ||
tag: 'limel-example-read-more', | ||
shadow: true, | ||
}) | ||
export class HelpReadMoreExample { | ||
public render() { | ||
return <limel-help value={helpAndDocumentation} readMoreLink={link} />; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { Component, h } from '@stencil/core'; | ||
const markdown = ` | ||
#### Why providing contextual help is important | ||
1. **It promotes user engagement.** | ||
When users encounter assistance at strategic points within the interface, | ||
frustration diminishes, and satisfaction grows. | ||
This positive experience contributes to increased user retention, | ||
as individuals are more likely to continue using | ||
an app that aligns with their needs and supports them on their journey. | ||
2. **It help serves as a means of communication between the app and its users.** | ||
It enables developers to provide users with information about | ||
the app’s functionality, or about the actions that the user is expected to do, | ||
to complete a task or move to the next step in a process. | ||
`; | ||
|
||
/** | ||
* Basic example | ||
* This component accepts a string as a value and displays it in a popover. | ||
* This string can be in markdown format, enabling you to add links, lists, etc; | ||
* providing a richer experience for the user. | ||
*/ | ||
@Component({ | ||
tag: 'limel-example-help', | ||
shadow: true, | ||
}) | ||
export class HelpExample { | ||
public render() { | ||
return <limel-help value={markdown} />; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import { Component, Prop, h } from '@stencil/core'; | ||
import { Link } from '../../interface'; | ||
|
||
/** | ||
* Help content | ||
* This is scrollable content that is placed in the popover of the Help component. | ||
* Moved here mostly to avoid having inlined styles in the parent component. | ||
* Since you cannot send styles to the Portal component, we need to have this | ||
* child component. | ||
* @private | ||
*/ | ||
@Component({ | ||
tag: 'limel-help-content', | ||
shadow: true, | ||
styleUrl: 'limel-help-content.scss', | ||
}) | ||
export class HelpContent { | ||
@Prop() | ||
public value: string; | ||
|
||
@Prop() | ||
public readMoreLink?: Link; | ||
|
||
public render() { | ||
return [ | ||
<limel-markdown value={this.value} />, | ||
this.renderReadMoreLink(), | ||
]; | ||
} | ||
|
||
private renderReadMoreLink = () => { | ||
if (!this.readMoreLink) { | ||
return; | ||
} | ||
|
||
return ( | ||
<a | ||
href={this.readMoreLink?.href} | ||
target={this.readMoreLink?.target} | ||
title={this.readMoreLink?.title} | ||
tabindex="0" | ||
> | ||
<span>{this.readMoreLink?.text}</span> | ||
</a> | ||
); | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
@use '../../style/mixins'; | ||
|
||
limel-popover { | ||
display: flex; | ||
--popover-surface-width: min(calc(100vw - 4rem), 22rem); | ||
} | ||
|
||
button[slot='trigger'] { | ||
all: unset; | ||
|
||
@include mixins.is-flat-clickable( | ||
$color--hovered: rgb(var(--color-sky-dark)), | ||
$background-color: var(--lime-elevated-surface-background-color) | ||
); | ||
@include mixins.visualize-keyboard-focus; | ||
|
||
box-sizing: border-box; | ||
display: flex; | ||
align-items: center; | ||
justify-content: center; | ||
color: rgb(var(--color-sky-default)); | ||
border-radius: 50%; | ||
box-shadow: 0 0 0 1px rgb(var(--color-sky-lighter), 0.7); | ||
width: 0.875rem; | ||
height: 0.875rem; | ||
font-size: 0.75rem; | ||
|
||
&.is-open { | ||
color: rgb(var(--color-white)); | ||
background-color: rgb(var(--color-sky-default)); | ||
box-shadow: var(--button-shadow-inset); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
import { Component, h, Prop, State } from '@stencil/core'; | ||
import { OpenDirection } from '../menu/menu.types'; | ||
import { Link } from '../../interface'; | ||
|
||
/** | ||
* A good design is self-explanatory! However, sometimes concepts are | ||
* too complex to understand, no matter how well-designed a user interface is. | ||
* In such cases, contextual help can be a great way to provide users with | ||
* help precisely where and when users need it. | ||
* | ||
* In app interface design, providing contextual help emerges as a viable practice | ||
* for enhancing user experience and usability. | ||
* Contextual help serves as a quick-to-access guiding, | ||
* empowering users to more easily understand and navigate through | ||
* the intricacies of an application. | ||
* | ||
* Using this component designers empower users to grasp the functionality | ||
* of an app more effortlessly, minimizes the learning curve, | ||
* transforming complex features into accessible opportunities for exploration. | ||
* @exampleComponent limel-example-help | ||
* @exampleComponent limel-example-read-more | ||
* @exampleComponent limel-example-open-direction | ||
* @exampleComponent limel-example-placement | ||
*/ | ||
@Component({ | ||
tag: 'limel-help', | ||
shadow: true, | ||
styleUrl: 'help.scss', | ||
}) | ||
export class Help { | ||
/** | ||
* The markdown content that will be displayed in the popover. | ||
*/ | ||
@Prop() | ||
public value: string; | ||
|
||
/** | ||
* Visualizes the trigger element. Defaults to: **?** | ||
* :::important | ||
* Be consistent across the product if you want to change it to a custom character. | ||
* All instances of the help component should have the same trigger visualization. | ||
* ::: | ||
*/ | ||
@Prop() | ||
public trigger: string = '?'; | ||
|
||
/** | ||
* If supplied, it will render a "Read more" link at the bottom of the content. | ||
* Even though you can add a link anywhere in the content, it is recommended to | ||
* use the read more link. Because it will always be displayed at the bottom | ||
* of the popover after the content, does not scroll away with the content, | ||
* and it will be styled in a consistent way. | ||
*/ | ||
@Prop() | ||
public readMoreLink?: Link; | ||
|
||
/** | ||
* Decides the popover's location in relation to the trigger. | ||
*/ | ||
@Prop({ reflect: true }) | ||
public openDirection: OpenDirection = 'top-start'; | ||
|
||
@State() | ||
private isOpen = false; | ||
|
||
public render() { | ||
return [ | ||
<limel-popover | ||
open={this.isOpen} | ||
onClose={this.onPopoverClose} | ||
openDirection={this.openDirection} | ||
> | ||
<button | ||
slot="trigger" | ||
onClick={this.openPopover} | ||
class={{ | ||
'is-open': this.isOpen, | ||
}} | ||
> | ||
{this.trigger} | ||
</button> | ||
<limel-help-content | ||
value={this.value} | ||
readMoreLink={this.readMoreLink} | ||
/> | ||
</limel-popover>, | ||
]; | ||
} | ||
|
||
private openPopover = (event: MouseEvent) => { | ||
event.stopPropagation(); | ||
this.isOpen = true; | ||
}; | ||
|
||
private onPopoverClose = (event: CustomEvent) => { | ||
event.stopPropagation(); | ||
this.isOpen = false; | ||
}; | ||
} |
Oops, something went wrong.