# Mark DS Documentation
# App-menu
## Examples
### Default
```html
```
### CustomActivator
It's possible to use a custom activator by using the `activator` slot.
```html
Open app menu
```
### UsingSlotContent
Using the default slot to generate required markup. Especially useful if you need generate the markup with backend rendered data.
```html
```
## Component API
### Properties
- **open** (boolean): Controls whether the modal is open Default: false.
- **items** (AppMenuItems): The items to display in the app menu Default: [].
- **position** ("bottom" | "right"): Default: "bottom".
### Events
- **app-selected**: .
- **close**: Fired when the modal is closed.
### Slots
- **default**: Default content of the app menu.
- **header**: Default content of the app menu.
- **footer**: Default content of the app menu.
- **activator**: Default content of the app menu.
# App-promotion
App promotion banners are used to promote features of an app to users. They are typically displayed at the top of a page.
## Examples
```html
Heading
Default content in default slot
Action
```
### WithImage
Example showing the app promotion banner with an image in the image slot.
```html
Try our new feature
Check out this amazing new capability that will boost your productivity.
Get Started
```
### LongContent
Demonstrates how the ad banner component handles longer content and multiple action buttons in a constrained width container.
```html
Heading
This is a much longer promotional message that demonstrates how the
banner handles extended content and wrapping behavior within a
constrained container width. This is a much longer promotional message
that demonstrates how the banner handles extended content and wrapping
behavior within a constrained container width.
Learn MoreTry Now
```
## Component API
### Slots
- **heading**: Heading content with appropriate level.
- **image**: Image to display in the banner.
- **default**: Default content of the element.
- **actions**: Actions to display in the banner.
# Box
## Examples
### Default
```html
```
## Component API
### Properties
- **border** (string): Whether the box has a border Default: "weak".
- **shadow** (boolean): Whether the box has a shadow Default: false.
- **borderRadius** (boolean): Whether the box has rounded corners Default: false.
- **spacing** (BoxSpacing): The padding inside the box (e.g., "none", "xs", "s", "m", "l", "xl", "xxl") Default: none.
- **width** (BoxWidth): The maximum width of the box (e.g., "default", "narrow", "medium", "wide") Default: none.
- **background** (string): The background style of the box (e.g., "default", "raised", "transparent") Default: 'default'.
### Slots
- **default**: Default content inside the box.
# Button-group
Button group for grouping buttons together.
## Examples
### Default
```html
Button 1Button 1
```
### Left
```html
Button 1Button 2
```
### Center
```html
Button 1Button 2
```
### Right
```html
Button 1Button 2
```
### SpaceBetween
```html
Button 1Button 2
```
## Component API
### Properties
- **align** (ButtonGroupAlign): The alignment of the buttons in the group Default: none.
### Slots
- **default**: Default slot for content.
# Button
Buttons are used to trigger actions or events within the interface. They help users interact with the system, such as submitting forms, navigating to a new page, or performing specific tasks.
## Examples
### Default
```html
Click me
```
### WithIcon
```html
Click me
Click me
```
### Variants
Here are all the variants of the button component. Only use one primary variant per page/component.
```html
${Object.values(ButtonVariant).map(
(variant) => html`
${variant}
${variant}
${variant} link
${variant} link
`
)}
```
### Sizes
```html
${Object.values(ButtonSize).map(
(size) => html`
Size ${size}
`
)}
```
### IconOnly
```html
${Object.values(ButtonVariant).map(
(variant) => html`
${Object.values(ButtonSize).map(
(size) => html`
`
)}
`
)}
```
### Loading
This story demonstrates the button in a loading state with a spinner.
```html
Loading
```
### ClickedButton
```html
Click me
```
## Usage
- **Primary** variant: Used for the main action on a page, such as “Submit” or “Next.” Only one primary button should be used per section to emphasize the most important action (main call-to-action).
- **Default** variant: Used for less prominent actions, providing alternatives to the primary action.
- **Plain** variant: Used for actions that have the lowest emphasis or are less critical.
- **Danger** variant: Used for actions that have a high risk of negative outcomes, such as deleting data, stopping a service, or other irreversible actions. This button should be used sparingly and only when the user needs to be clearly warned about the consequences of the action.
- **Disabled**: Indicates an action that is not currently available. Disabled buttons are unclickable and visually distinct.
## Other Considerations
- **Text clarity:** Ensure the button text clearly describes the action it will trigger. Use verbs like “Save,” “Delete,” or “Learn more.”
- **Consistent text:** Button labels should be concise, ideally no more than 2-3 words.
- **Action-oriented:** Button text should be specific and action-oriented (e.g., use “Submit form” rather than just “Submit” when appropriate).
## Component API
### Properties
- **type** (ButtonType): The type of the button Default: none.
- **variant** (ButtonVariant): The visual style of the button Default: none.
- **size** (ButtonSize): Set the size of the button Default: none.
- **square** (boolean): Whether the button is square Default: false.
- **href** (string | undefined): Use button as a link Default: none.
- **target** (| "_self"
| "_blank"
| "_parent"
| "_top"): The target attribute for the link * @attribute {string} loading - Indicates whether the button is in a loading state Default: "_self".
- **loading** (boolean): Default: false.
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
- **error** (string | undefined): Default: none.
- **required** (boolean): Default: false.
### Events
- **click**: fired when the button is clicked.
- **input**: Fired as the user types into the input..
### Slots
- **default**: Default content of the button, the text for action.
- **start**: Slot before the default content.
- **end**: Slot after the default content.
# Checkbox
The Checkbox component allows users to select one or more options from a set. It supports various states including checked, indeterminate, disabled, and readonly, along with customizable labels and hints for better accessibility.
## Examples
### Default
```html
```
### States
```html
```
### WithHint
```html
```
### WithDescription
```html
```
### WithError
```html
This field is requiredThis field is required
```
### WithCustomContent
```html
Custom formatted labelCustom formatted hintCustom formatted error
```
## Usage
**Use a Checkbox to:**
- Allow users to select multiple options from a set.
- Enable or disable a specific feature or setting.
- Provide a binary choice (e.g., "I agree to the terms and conditions").
- Support independent selection where multiple checkboxes can be checked simultaneously.
**Do not use a Checkbox to:**
- Perform an action immediately when selected (use a toggle switch instead).
- Represent mutually exclusive choices (use radio buttons instead).
- Select all options at once without a clear way to deselect (consider an explicit "Select All" checkbox).
## Other Considerations
- Ensure the checkbox has a label that describes its purpose.
- Labels should be concise and clearly describe the option (e.g., "Receive email notifications").
- Avoid double negatives (e.g., "Do not disable notifications").
- Group related checkboxes under a clear heading.
## Design Rationale
- Checkboxes are a familiar UI pattern, making them easy to recognize and use.
- They offer clear affordance, showing whether an option is selected or not.
- They support bulk actions and multiple selections, making them flexible for many interfaces.
- Checkboxes align with accessibility guidelines, ensuring users with disabilities can interact with
## Component API
### Properties
- **label** (string | undefined): Default: none.
- **hint** (string | undefined): Default: none.
- **error** (string | undefined): Default: none.
- **checked** (boolean): Default: false.
- **labelHidden** (boolean): Default: false.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **required** (boolean): Default: false.
- **indeterminate** (boolean): Default: false.
- **description** (string | undefined): Default: none.
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **placeholder** (string | undefined): Input placeholder text Default: none.
### Events
- **change**: .
- **input**: Fired as the user types into the input..
# Date-picker
The Date Picker allows users to select a date from a calendar interface. It enhances user experience by providing a structured way to enter date values, reducing errors and ensuring consistency.
## Examples
### Default
```html
```
### WithError
```html
```
### WithHint
```html
```
### Required
```html
```
### Disabled
```html
```
### FullWidth
```html
```
## Component API
### Properties
- **buttonIcon** (String): Icon name for the calendar button Default: "calendar-blank".
- **buttonAriaLabel** (String): Aria label for the calendar button Default: "Open calendar".
- **selectedDate** (Date): Selected date Default: new Date().
- **displayedMonth** (Date): Displayed month Default: new Date().
- **locale** (String): Locale for the datepicker Default: "fi-FI".
- **format** (string): Default: "dd.MM.yyyy".
- **min** (string): Default: "1900-01-01".
- **max** (string): Default: "2100-12-31".
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
- **error** (string | undefined): Error message to display Default: none.
- **required** (boolean): Whether the input is required Default: false.
- **label** (string): Label text for the input Default: none.
- **description** (string): Description text below the label Default: none.
- **hint** (string): Hint text shown below the input Default: none.
- **labelHidden** (boolean): Whether to visually hide the label Default: false.
- **fullWidth** (boolean): Whether the input should take full width Default: false.
- **icon** (string): Icon to display before the input Default: none.
- **horizontal** (boolean): Default: false.
### Events
- **input**: Fired as the user types into the input..
- **change**: .
# Dialog
## Examples
### Default
```html
Open ModalModal Header
Default content of the modal
Default content of the modal
Default content of the modal
CancelConfirm
```
### WithoutFooter
```html
Open ModalModal Header
Default content of the modal
```
## Usage
Use the Dialog component for:
- Modal Dialogs: When you need to interrupt workflow for critical actions or confirmations (e.g., “Are you sure you want to delete this?”).
- Menu Pop-ups: For non-disruptive options or actions related to a selected item or section, such as context menus or dropdowns.
- Information Panels: When additional information or user input is required, but not critical, such as quick forms or read-only details.
## Focus Management
The dialog implements a focus management system that follows these rules:
1. When opened, the dialog will try to find and focus elements in this order:
- First element with `autofocus` and `tabindex="-1"` attributes in the content
- If no autofocus element is found, falls back to the dialog title
### Example with autofocus
```html
Dialog Title
This heading will receive focus
Other content...
```
### Example without autofocus
```html
Dialog Title
The dialog title will receive focus
```
This focus management system ensures proper accessibility by:
- Providing immediate context to screen reader users
- Preventing unwanted page scrolling
- Following WCAG 2.2 guidelines for modal dialogs
## Other Considerations
- Clear and Concise Content: Use clear titles and concise content to ensure users understand the dialog’s purpose immediately.
- Descriptive Button Labels: Use clear, action-oriented labels like “Save” or “Delete.”
- Minimal Disruption: Use non-modal dialogs for light interactions or additional options to avoid workflow interruptions.
## Design rationale
**Top-of-Viewport Positioning:**
The modal dialog is anchored at the top of the viewport to improve accessibility and predictability, especially for content that changes in size (dynamic content). This stable positioning prevents content "jumping" and minimizes the need for repositioning, helping users easily locate, read, and focus on the dialog content.
**2-Button rule for modal actions:**
The modal dialog footer should contain no more than two primary actions to keep the user experience clear and focused. If more than two actions are required, consider these alternatives:
1. Place Additional Actions in the Dialog Body: Add secondary actions within the content area if they provide context-specific options (e.g., “View Details” or “Learn More”).
2. Use Advanced Button Components: For related actions, consider an advanced button, like a split button, which combines a main action with a dropdown for additional subactions.
This approach ensures simplicity and helps users quickly identify key actions in the modal.
## Component API
### Properties
- **open** (boolean): Whether the dialog is open Default: false.
- **size** (DialogSize): The size of the dialog Default: none.
- **variant** (DialogVariant): The variant of the dialog Default: none.
- **hideTitle** (boolean): Whether to hide the title Default: false.
- **closable** (boolean): Whether the dialog has close button in header Default: true.
- **modal** (boolean): Whether the dialog is modal Default: false.
### Events
- **close**: Event fired when the dialog is closed.
### Slots
- **default**: Default content of the dialog.
- **header**: Slot for the header content.
- **footer**: Slot for the footer content.
# Editor
The Editor component is used to create rich text content.
## Examples
```html
${args.children ||
html`
`}
```
### SingleAIOption
```html
${args.children}
```
### MultipleAIOptions
```html
${args.children}
```
### CustomConfig
The editor can be configured with custom options using the `config` attribute. See the [Froala documentation](https://www.froala.com/wysiwyg-editor/docs/options) for more information.
```html
FISVNOEN
```
### UpdateContent
The editor content can be updated by clicking the button below, using the `updateContent` method.
```html
Initial content
Update Content
```
### UpdateSelection
The selected text can be updated by clicking the button below, using the `updateSelection` method.
```html
Select this text and click the button below
Another paragraph
Select text and click here
```
## Installation
As this is a addon component, you need to install the addon first.
```bash
npm install @mark/editor
```
You also need to include the css from froala editor directly to the page where you are using the editor component
```html
```
And finally also include or import the editor.
```javascript
// import from installed package
import "@mark/editor";
// import from the cdn
import 'https://cdn.grade.design/mark/editor/0.2.0/index.js';
```
## Usage
TODO
## Other Considerations
You have to handle the styling of the content with your local applications styles. Either global css or specifically targeted inside the editor.
```css
m-editor p,
m-editor ul,
m-editor ol {
margin: 0 0 var(--m-space-m);
}
```
# Empty-state
## Examples
```html
${args.content}
```
### RichContent
```html
No results found
Try adjusting your search or filter criteria
Clear filters
```
## Component API
### Properties
- **iconName** (IconName | undefined): Default: undefined.
- **iconSize** (IconSize): Default: "xxl".
- **autoFocus** (boolean): Default: false.
### Slots
- **default**: The main text content.
- **icon**: Optional slot for custom icon content.
# Feedback-dialog
## Examples
### Default
```html
Open Default Feedback Dialog {
const defaultDialog = document.querySelector("m-feedback-dialog");
if (defaultDialog) defaultDialog.open = false;
}}"
@feedback-submit="${async (e) => {
const defaultDialog = document.querySelector("m-feedback-dialog");
if (defaultDialog) {
defaultDialog.loading = true; // Set loading state
// Simulate an API call
await new Promise((resolve) => setTimeout(resolve, 2000)); // 2 seconds delay
defaultDialog.loading = false; // Reset loading state
defaultDialog.submitted = true; // Set submitted state
console.log(e.detail);
}
}}"
>
```
### CustomOptions
```html
Open Feedback Dialog With Custom Options {
const customOptionsDialog = document.getElementById("dialog-custom-options");
if (customOptionsDialog) customOptionsDialog.open = false;
}}"
>
```
## Component API
### Properties
- **options** (FeedbackDialogOptions): Default: DefaultFeedbackDialogOptions.
- **open** (boolean): Default: false.
- **loading** (boolean): Default: false.
- **submitted** (boolean): Default: false.
### Events
- **close**: .
- **feedback-submit**: .
- **feedback-error**: .
# Form
The Form component provides a wrapper to handle form-related tasks such as validation, data collection, and reset behavior for child inputs. It supports both native inputs and custom input components.
## Examples
### DefaultForm
```html
SubmitReset
```
### CustomInputs
This example shows a form with custom inputs like textarea, checkbox, and select, along with added button functionality.
```html
SubmitReset
```
## Component API
### Events
- **form-error**: Emitted when form validation fails..
- **form-submit**: Emitted when the form is successfully submitted with validated data..
- **form-reset**: Emitted when the form is reset to its initial state..
# Icon-list
## Examples
### Default
```html
Simple featureFeature with bold text
```
## Component API
### Properties
- **label** (string): Accessible label for the list Default: none.
### Slots
- **default**: Default slot for m-icon-list-item elements.
# Icon
Icon component for displaying SVG icons.
## Examples
### Default
```html
```
### Sizes
```html
${Object.values(IconSize).map(
(size) => html` `
)}
```
### WithLabel
```html
```
### IconGallery
```html
```
## Component API
### Properties
- **name** (IconName | undefined): The name of the icon to display. Default: none.
- **size** (IconSize | undefined): The size of the icon. Default: none.
- **color** (string | undefined): The color of the icon. Default: "currentColor".
- **label** (string | undefined): The accessible label for the icon. Default: none.
# Input-text
The Text Input allows users to enter and edit a single line of text. It is commonly used for capturing short responses such as names, email addresses, search queries, and other structured data.
## Examples
### Default
```html
```
### Required
```html
```
### Disabled
```html
```
### FullWidth
```html
```
### WithHint
```html
```
### WithDescription
```html
```
### WithError
```html
```
### WithIcon
```html
```
### WithPlaceholder
```html
```
### WithLongText
```html
```
### Horizontal
```html
```
### WithLongTextHorizontal
```html
```
## Usage
**Use an Input to:**
- Allow users to enter freeform text (e.g., names, job titles, email addresses).
- Collect structured data such as numbers, dates, or passwords.
- Provide search functionality where users can input keywords.
**Do not use an Input to:**
- Select from predefined options (use radio buttons, checkboxes, or dropdowns instead).
- Display non-editable information (use a text display component instead).
- Input complex formatted data without validation (ensure proper input masks or formatting helpers are used).
## Other Considerations
- Ensure every input field has a descriptive label.
- Use placeholder text sparingly — it should not replace labels as it disappears when users type.
- Include error messages and validation hints for incorrect or missing input.
- Labels should be short, clear, and aligned with the user’s expectations (e.g., "First Name", "Phone Number").
- Provide help text when input expectations may be unclear (e.g., password rules).
- Restrict input types appropriately (e.g., type="email" for email fields, type="number" for numeric input).
## Design Rationale
Alignment with standards ensures all users, including those with disabilities, can interact with input fields effectively.
## Component API
### Properties
- **label** (string): Label text for the input Default: none.
- **name** (string | undefined): Name of the input Default: none.
- **description** (string): Description text below the label Default: none.
- **hint** (string): Hint text shown below the input Default: none.
- **required** (boolean): Whether the input is required Default: false.
- **disabled** (boolean): Whether the input is disabled Default: false.
- **labelHidden** (boolean): Whether to visually hide the label Default: false.
- **error** (string | undefined): Error message to display Default: none.
- **fullWidth** (boolean): Whether the input should take full width Default: false.
- **icon** (string): Icon to display before the input Default: none.
- **horizontal** (boolean): Default: false.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
### Events
- **change**: .
- **input**: Fired as the user types into the input..
# Nav-group-app
## Component API
### Properties
- **name** (string): Name of the application Default: none.
- **id** (string): ID of the application Default: none.
- **description** (string): Description of the application Default: none.
- **href** (string | undefined): URL of the application Default: none.
- **target** (string): Target of the application Default: "_parent".
- **selected** (boolean | undefined): Whether the application is selected Default: none.
- **purchase** (boolean | undefined): Whether the application is not yet purchased for the user Default: none.
- **brandHidden** (boolean | undefined): Indicates whether the brand name should be hidden in the application display. Default: none.
### Events
- **click**: .
# Nav-group
## Examples
### Default
```html
```
### WithoutHeading
```html
```
## Component API
### Properties
- **heading** (string | undefined): The heading text for the navigation group Default: none.
### Slots
- **default**: Default content of the element.
# Nav
## Examples
### Default
```html
```
## Component API
### Properties
- **label** (string): Optional label for the navigation Default: none.
### Slots
- **default**: Default content of the element.
# Password
The Password is a specialized input field component designed for securely entering sensitive credentials. It masks the entered text by default to prevent unauthorized viewing and includes options for visibility toggles.
## Examples
### Default
```html
```
### WithError
```html
```
### WithHint
```html
```
### Required
```html
```
### Disabled
```html
```
### FullWidth
```html
```
### WithLongText
```html
```
### WithLongTextHorizontal
```html
```
## Usage
**Use a Password Input to:**
- Collect secure user credentials for logging in or creating an account.
- Allow users to set or update passwords in profile settings.
- Ensure password confidentiality by masking input characters.
**Do not use a Password Input to:**
- Collect non-sensitive information (use a standard input field instead).
- Display static passwords (use a readonly text field with obfuscation if needed).
- Auto-fill passwords without user consent (browser-managed password storage should be leveraged instead).
## Other Considerations
- Provide a clear label (e.g., "Enter Password") and do not rely solely on placeholders.
- Add password policies as a hint text (e.g., minimum length, special characters, case sensitivity).
- Use error messages for invalid passwords (e.g., "Password must be at least 8 characters").
## Design Rationale
- Enhances security by masking password.
- Balances accessibility and security by giving users control over password visibility.
- Improves usability with visibility toggle.
## Component API
### Properties
- **showPassword** (boolean): Default: false.
- **buttonIcon** (string): Default: "".
- **buttonAriaLabel** (string): Default: "".
- **inputType** (string): Default: "text".
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
- **error** (string | undefined): Error message to display Default: none.
- **required** (boolean): Whether the input is required Default: false.
- **label** (string): Label text for the input Default: none.
- **description** (string): Description text below the label Default: none.
- **hint** (string): Hint text shown below the input Default: none.
- **labelHidden** (boolean): Whether to visually hide the label Default: false.
- **fullWidth** (boolean): Whether the input should take full width Default: false.
- **icon** (string): Icon to display before the input Default: none.
- **horizontal** (boolean): Default: false.
### Events
- **action-click**: .
- **input**: Fired as the user types into the input..
- **change**: .
# Popover
## Examples
```html
Toggle Popover
Popover Content
Placement: ${args.placement}
```
### PlacementDemo
```html
Top Start
Top Start Popover
Top
Top Popover
Top End
Top End Popover
Left
Left Popover
Center
Bottom (default)
Bottom Popover
Right
Right Popover
Bottom Start
Bottom Start Popover
Bottom
Bottom Popover
Bottom End
Bottom End Popover
```
### ViewportEdgeDemo
```html
Top Edge
This popover should flip to bottom when near the top edge.
Right Edge
This popover should flip to left when near the right edge.
Bottom Edge
This popover should flip to top when near the bottom edge.
Left Edge
This popover should flip to right when near the left edge.
```
### LargeContent
```html
Show Large Content
Large Content Popover
This demonstrates how the popover handles large content:
Content is scrollable if it exceeds viewport
Maintains max-width and max-height constraints
Preserves placement when possible
Flips placement when needed
Try resizing the window to see how it adapts!
```
### FocusTrapDemo
```html
Before PopoverOpen Popover
Focus Trap Demo
Tab navigation is trapped within this popover.
Button 1
Div with tabindex
After Popover
```
## Component API
### Properties
- **open** (boolean): Whether the popover is shown Default: false.
- **mode** ('auto' | 'manual'): The popover behavior mode Default: 'auto'.
- **placement** (PopoverPlacement): The preferred placement of the popover Default: none.
### Events
- **open-changed**: Fired when the popover opens or closes.
### Slots
- **default**: Content to be shown in the popover.
- **trigger**: The element that triggers the popover.
# Product-lead-form
## Examples
```html
Are you interested?
Information about why user should contact us. Fill and send the form and
we will tell you more.
```
## Component API
### Properties
- **id** (string): Unique identifier for the form container Default: "".
- **formId** (string): The HubSpot form ID to display Default: "".
- **locale** (string): Form language (en, fi, sv) Default: "en".
- **email** (string): Prepopulated email address Default: "".
- **company** (string): Prepopulated company name Default: "".
- **country** (string): Prepopulated country Default: "".
- **origin** (boolean): The environment the form is loaded in Default: "".
- **target** (string): The target product of the form Default: "".
### Events
- **form-ready**: Fired when the form is loaded and ready.
- **form-submit**: Fired when the form is submitted.
- **form-submitted**: Fired when the form submission is completed.
- **form-error**: Fired if there's an error loading the form.
# Promotion-dialog
## Examples
### Default
```html
Open dialog
Category information
Accessible header for dialog
Visual header
Short description of the promotion.
Key benefits and features (optional)
Simple feature descriptionFeature with **markdown** supportCancelLearn more
```
### WithAppMenu
Example of promotion dialog with app menu integration. The dialog opens when you open the menu and click on the **additional services** in the **more services** section.
```html
Additional service!
Learn about our additional service
Effortless onboarding with Intro
Welcome new employees with ease using Intro’s smart and engaging
onboarding solution. Automate repetitive tasks, ensure a consistent
experience, and help new hires feel at home from day one. Say goodbye to
manual processes—Intro does the heavy lifting for you.
Key features
Tailored onboarding flows – Create personalized
journeys that reflect your company culture.Automated task management – Keep new hires on track
with structured guidance.Seamless integrations – Connect effortlessly with
your existing HR tools.
Ready to elevate your onboarding?
Discover how Intro can transform your onboarding experience. Fill out
the form below, and our team will be in touch!
Cancel
```
## Usage
The Promotion Dialog component is designed to enable seamless promotion of product-led features and services. It helps guide users towards exploring and activating new offerings by leveraging a structured and user-friendly dialog.
### Key Use Cases
- Feature Promotion: Highlight new or underutilized features within the product.
- Service Upgrades: Offer upgraded plans or add-on services directly to users.
- Beta Invitations: Enable admins or users to join beta programs or trials.
### Example Scenarios
- Introducing AI-powered recommendations in a recruitment application.
- Inviting users to activate a free beta for a feature set within their organization.
- Promoting an upgrade to premium services during feature exploration.
### Placement
- Trigger the dialog using action buttons, inline promotions, or notifications.
- Avoid using persistent triggers for promotions to prevent user fatigue.
- Ensure the promotion dialog aligns with the overall application’s visual hierarchy.
## Design Rationale
- Focused Engagement: The modal dialog ensures user attention is directed to the promotion without distractions.
- Guided Actions: Clear CTAs and error handling guide users seamlessly through the process.
- Accessibility: Ensures compliance with accessibility standards (e.g., ARIA roles, focus trapping).
## Component API
### Properties
- **open** (boolean): Whether the dialog is open Default: false.
- **size** (DialogSize): The size of the dialog Default: none.
- **variant** (DialogVariant): The variant of the dialog Default: none.
- **hideTitle** (boolean): Whether to hide the title Default: false.
- **closable** (boolean): Whether the dialog has close button in header Default: true.
- **modal** (boolean): Whether the dialog is modal Default: false.
### Events
- **close**: Event fired when the dialog is closed.
### Slots
- **default**: Default content of the dialog.
- **header**: Slot for the header content.
- **footer**: Slot for the footer content.
# Radio
The Radio component allows users to select a single option from a set of choices. It supports various states including checked, disabled, and readonly, along with customizable labels and hints for better accessibility.
## Examples
### Default
```html
```
### RadioGroup
```html
```
### States
```html
```
### WithHint
```html
```
### WithDescription
```html
```
### WithError
```html
This field is required
```
### WithCustomContent
```html
Custom formatted labelCustom formatted hintCustom formatted error
```
## Usage
**Use a Radio Button to:**
- Allow users to select one option from a list when multiple choices exist.
- Present mutually exclusive options, where selecting one automatically deselects others.
- Indicate a required selection, ensuring that users make a decision before proceeding.
**Do not use a Radio Button to:**
- Allow multiple selections (use checkboxes instead).
- Toggle a single setting on or off (use a checkbox or toggle switch instead).
- Display a long list of options (consider a dropdown for better space management).
## Other Considerations
- Ensure each radio button descriptive labels that clearly communicate the choice (e.g., “Full-time”, “Part-time”).
- Avoid using vague options like “Yes” and “No” unless the context is clear.
- Default to the most common or recommended option when appropriate.
- Visually group related options under a heading or a question to provide context.
- Ensure that all radio buttons in a group are logically ordered for a smooth user experience.
## Design Rationale
- Mutual exclusivity ensures users can only select one option, preventing conflicting choices.
- Immediate feedback provides clarity, as selecting one option automatically deselects the others.
- Ease of use makes radio buttons a familiar and effective choice for form inputs.
- Consistency with accessibility guidelines ensures that all users, including those using assistive technologies, can easily interact with radio buttons.
## Component API
### Properties
- **label** (string | undefined): Default: none.
- **hint** (string | undefined): Default: none.
- **error** (string | undefined): Default: none.
- **checked** (boolean): Default: false.
- **labelHidden** (boolean): Default: false.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **required** (boolean): Default: false.
- **description** (string | undefined): Default: none.
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **placeholder** (string | undefined): Input placeholder text Default: none.
### Events
- **change**: .
- **input**: Fired as the user types into the input..
# Select
The Select provides a dropdown interface for users to choose an option from a predefined list. It is ideal for scenarios where space is limited, and users need to pick from a set of structured choices.
## Examples
### Default
```html
```
### States
```html
```
### DescriptionState
```html
```
### HintState
```html
```
### ErrorState
```html
```
## Usage
The Select component is commonly used in forms and settings where users must make a selection from a limited set of choices. Unlike text inputs, a select component restricts user input to predefined options, ensuring data consistency and reducing errors.
**Use Select when:**
- Users need to choose one option from a fixed set of choices.
- The number of options is manageable (e.g., 5–15 options).
- The choices do not require complex descriptions (if descriptions are necessary, consider a radio buttons).
- A consistent, compact UI is required, and a radio button group would take too much space.
- Users should not enter free text but instead select from a valid list.
- Users should be able to refine results or content (e.g., selecting a category).
**Do not use Select when:**
- The number of options is very small (2–4); use radio buttons instead.
- Users need to make multiple selections; use a checkboxes instead.
- Options require additional descriptions or explanations; use a group of radio buttons with descriptions.
- The selection should be immediately visible without clicking.
## Other Considerations
- Use clear and concise label.
- Use placeholder text like “Select a department” instead of a default selection unless a default is meaningful.
- Keep option labels short and scannable.
- Group related options for better readability (either alphabetically, by importance or by group).
- Provide clear error messages when a selection is required but not made.
- Preselect a default option when appropriate (e.g., "Select a department").
- Do not use vague labels like “Choose One” without context.
- Avoid long option lists that require excessive scrolling.
## Design Rationale
The Select component is designed to improve efficiency and clarity in forms while maintaining accessibility. A dropdown conserves space and simplifies decision-making for users, particularly when dealing with long lists.
## Component API
### Properties
- **label** (string | undefined): Default: none.
- **labelHidden** (boolean): Default: false.
- **required** (boolean): Default: false.
- **hint** (string | undefined): Default: none.
- **error** (string | undefined): Default: none.
- **icon** (string | undefined): Default: none.
- **fullWidth** (boolean): Default: false.
- **description** (string | undefined): Default: none.
- **disabled** (boolean): Whether the input is disabled Default: false.
- **name** (string | undefined): The name of the input Default: none.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
### Events
- **change**: .
- **input**: Fired as the user types into the input..
# Spinner
A loading spinner component that provides visual feedback during loading states.
## Examples
### Default
```html
```
### Sizes
The spinner component comes in four different sizes: s, m, l, and xl.
```html
```
### InButton
The spinner can be used within buttons to indicate loading states.
```html
Loading
```
## Component API
### Properties
- **size** (string): Default: "s".
- **label** (string | undefined): Default: none.
# Stack
## Component API
### Properties
- **direction** (StackDirection): The direction of the stack (row or column) Default: none.
- **spacing** (StackSpacing): The spacing between stack items Default: none.
- **alignment** (StackAlignment): The alignment of stack items Default: none.
### Slots
- **default**: Default content of the stack.
# Tag
The Tag component is a small, versatile label that highlights or categorizes items across the interface. Tags are designed to quickly convey essential information, such as status, category, or type, helping users scan and interact with content effectively.
## Examples
### Default
```html
Category
```
### WithIcon
```html
Featured
```
### Variants
```html
${Object.values(TagVariant).map(
(variant) =>
html`${variant}${variant} `
)}
```
## Usage
Use the Tag component to:
- Indicate status or progress (e.g., "Pending," "Approved")
- Highlight categories or types (e.g., "Admin," "User")
- Draw attention to new or updated content (e.g., "New")
- Help users filter or identify items by type in lists, cards, or other grouped components
## Other Considerations
- **Concise Wording:** Use one or two words for clear communication (e.g., "New," "Alert").
- **Consistent Use:** Apply tags only where necessary and avoid overuse to prevent visual clutter.
- **Positioning:** Place tags in consistent positions, such as at the top-right corner of cards or lists, so users can easily scan for information.
## Component API
### Properties
- **icon** (IconName | undefined): Optional icon to display in the tag Default: none.
- **variant** (TagVariant | undefined): Variant of the tag Default: none.
### Slots
- **default**: Default content of the element.
# Textarea
The Textarea is used to create a text input field that allows users to enter and edit multi-line text
## Examples
### Default
```html
```
### WithLongText
```html
```
### WithLongTextHorizontal
```html
```
## Usage
Use the Textarea for:
- User Input of Multi-line Text: When users need to enter a long-form response, such as messages, comments, or detailed feedback.
- Flexible Text Entry: When the amount of text entered is unpredictable, such as open-ended answers in forms.
- Editing Content: When users need to edit or format existing text, such as in a note-taking or content management system.
Do not use the Textarea for:
- Short Inputs: Use a InputText -component for single-line inputs like names, email addresses, or phone numbers.
- Structured Data Entry: If input needs to be formatted (e.g., dates, times, or passwords), use the appropriate specialized input type.
## Design Rationale
Visual design and state variations follow the look and feel of the rest of the form elements for a consistent experience.
## Component API
### Properties
- **label** (string | undefined): Default: none.
- **name** (string | undefined): The name of the input Default: none.
- **hint** (string | undefined): Default: none.
- **description** (string | undefined): Default: none.
- **required** (boolean): Default: false.
- **disabled** (boolean): Whether the textarea is disabled Default: false.
- **labelHidden** (boolean): Default: false.
- **error** (string | undefined): Default: none.
- **fullWidth** (boolean): Default: false.
- **horizontal** (boolean): Default: false.
- **value** (string | undefined): The value of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
### Events
- **change**: .
- **input**: Fired as the user types into the input..
# Toggle
## Examples
### Default
```html
```
### States
```html
```
### WithError
```html
Error messageError message
```
### WithHint
```html
```
### WithErrorAndHint
```html
```
## Component API
### Properties
- **checked** (boolean): Whether the toggle is checked or not Default: false.
- **disabled** (boolean): Whether the toggle is disabled Default: false.
- **reversed** (boolean): Whether the toggle's label appears before the switch Default: false.
- **labelHidden** (boolean): Whether the label should be visually hidden Default: false.
- **label** (string): The label text for the toggle Default: ''.
- **hint** (string | undefined): Additional hint text for the toggle Default: none.
- **error** (string | undefined): Error message text for the toggle Default: none.
- **value** (string | undefined): The value associated with the toggle Default: ''.
- **name** (string | undefined): The name of the input Default: none.
- **readonly** (boolean | undefined): Whether the input is readonly Default: false.
- **placeholder** (string | undefined): Input placeholder text Default: none.
- **required** (boolean): Default: false.
### Events
- **change**: Fired when the toggle state changes, with `detail.checked` indicating the new state.
- **input**: Fired as the user types into the input..
### Slots
- **default**: Default content of the element (used as the label).
- **error**: Slot for error messages.
- **hint**: Slot for hint messages.
# Appmenu
## Usage
- Application Switching: Enable seamless navigation between different applications within your ecosystem
- Service Discovery: Showcase available services and upgrades to users
- Unified Navigation: Provide consistent access to all services from any application
- `ATS products` should display all connected Add-On products in navigation
- `Add-On products` should display the connected ATS product in navigation
### Placement
- The AppMenu should be the first item in the main navigation.
- Use the default activator when possible.
- If your navigation requires a custom activator, use the `activator` slot.
- Always use a button that clearly and textually indicates the action to be performed.
### Group services
Services can be given to the component by using an array of `AppMenuItems` items or by using the default slot to generate required markup using `nav` `nav-group` and `nav-group-app` components. Either way, organize services into clear, logical groups to help users understand their current services.
#### Active services
- Use clear, descriptive heading for the group (e.g., "Your Applications")
- Place current application first with `selected` status
- Include other active, accessible services for the current client user
- Use client company-level integration status
- Or use client department-level integration status if supported
- Use action-oriented descriptions for the services
- If possible route to the service with preserved authentication
- If not possible, use automatic SSO routing when enabled for organization
- If not possible, provide pre-filled credentials like username or email in the login of the service
- In general, the login should be as simple as possible
#### Complementary services
- Use heading to indicate that the group contains services that can be purchased (e.g., "More services")
- Group complementary services together
- Mark services requiring activation with `purchase` status
- Use action-oriented descriptions
- Route to appropriate promotional page of the service in user's current language
## Design Rationale
The AppMenu uses a two-level structure (groups and services) to:
1. Clearly separate active and available services
2. Reduce cognitive load through logical grouping
3. Enable quick access to frequently used applications
Clear visual indicators help users understand:
- Current application context (`selected`)
- Available upgrade opportunities (`purchase`)
- Service relationships and groupings
# Datepicker
## Usage
**Use a Datepicker to:**
- Allow users to select a specific date (e.g., start date of a contract, employee birthdate).
- Prevent incorrect date formatting by restricting manual input or enforcing validation rules.
**Do not use a Datepicker to:**
- Select non-date values (use an input field or dropdown instead).
- Display static or read-only dates (use a text label instead).
- Allow users to input approximate or fuzzy dates (consider a text input field for flexibility).
## Other Considerations
- Provide a clear and descriptive label that clearly indicate the purpose of the datepicker (e.g., "Start Date", "End Date").
- Format the date according to regional standards (e.g., MM/DD/YYYY or DD/MM/YYYY).
- Provide help text if users need to know valid date ranges or restrictions.
- Ensure date validation prevents invalid selections (e.g., past dates for future events).
- Allow users to only select valid date ranges when applicable (e.g., an end date must be after a start date).
- Disable weekends or holidays if necessary for scheduling use cases.
## Design Rationale
- Prevents input errors by ensuring date values are formatted correctly.
- Enhances usability with a visual calendar rather than requiring manual entry.
- Reduces cognitive load by presenting available dates in an intuitive format.
# Inputtext
## Usage
**Use an Input to:**
- Allow users to enter freeform text (e.g., names, job titles, email addresses).
- Collect structured data such as numbers, dates, or passwords.
- Provide search functionality where users can input keywords.
**Do not use an Input to:**
- Select from predefined options (use radio buttons, checkboxes, or dropdowns instead).
- Display non-editable information (use a text display component instead).
- Input complex formatted data without validation (ensure proper input masks or formatting helpers are used).
## Other Considerations
- Ensure every input field has a descriptive label.
- Use placeholder text sparingly — it should not replace labels as it disappears when users type.
- Include error messages and validation hints for incorrect or missing input.
- Labels should be short, clear, and aligned with the user’s expectations (e.g., "First Name", "Phone Number").
- Provide help text when input expectations may be unclear (e.g., password rules).
- Restrict input types appropriately (e.g., type="email" for email fields, type="number" for numeric input).
## Design Rationale
Alignment with standards ensures all users, including those with disabilities, can interact with input fields effectively.
# Overview
Version {version}
# Components
> Components are the reusable building blocks of our design system. Each component meets a specific interaction or UI need, and has been specifically created to work together to create patterns and intuitive user experiences.
In progress
# Patterns
> Design patterns help create consistent, intuitive experiences across our products. They provide proven solutions to common UX challenges, reduce cognitive load for users, and speed up both design and development by offering ready-to-use combinations of our components.
Version {version}
# Design Tokens
> Design tokens are the foundational elements of our design system. They are used to create consistent and scalable UI components.
{tokenGroups.map((component) => (
))}
# Typography
Under construction
# Typography
> This page is under construction. We are working on a more comprehensive guide for typography.
Below you can see the typography styles that are currently in testing phase.
## Loose style
Veli kulta, veikkoseni, kaunis kasvinkumppalini! Lähe nyt kanssa laulamahan, saa kera sanelemahan yhtehen yhyttyämme, kahta'alta käytyämme! Harvoin yhtehen yhymme, saamme toinen toisihimme näillä raukoilla rajoilla, poloisilla Pohjan mailla.
Heading 2
Veli kulta, veikkoseni, kaunis kasvinkumppalini! Lähe nyt kanssa laulamahan, saa kera sanelemahan yhtehen yhyttyämme, kahta'alta käytyämme! Harvoin yhtehen yhymme, saamme toinen toisihimme näillä raukoilla rajoilla, poloisilla Pohjan mailla.
Veli kulta, veikkoseni, kaunis kasvinkumppalini! Lähe nyt kanssa laulamahan, saa kera sanelemahan yhtehen yhyttyämme, kahta'alta käytyämme! Harvoin yhtehen yhymme, saamme toinen toisihimme näillä raukoilla rajoilla, poloisilla Pohjan mailla.
Heading 3
Veli kulta, veikkoseni, kaunis kasvinkumppalini! Lähe nyt kanssa laulamahan, saa kera sanelemahan yhtehen yhyttyämme, kahta'alta käytyämme! Harvoin yhtehen yhymme, saamme toinen toisihimme näillä raukoilla rajoilla, poloisilla Pohjan mailla.
Lyökämme käsi kätehen, sormet sormien lomahan, lauloaksemme hyviä, parahia pannaksemme, kuulla noien kultaisien, tietä mielitehtoisien, nuorisossa nousevassa, kansassa kasuavassa: noita saamia sanoja, virsiä virittämiä vyöltä vanhan Väinämöisen, alta ahjon Ilmarisen, päästä kalvan Kaukomielen, Joukahaisen jousen tiestä, Pohjan peltojen periltä, Kalevalan kankahilta.
# All-icons
Version {version}
# Icons
> This gallery showcases our complete icon set. Browse our comprehensive collection, quickly search for specific icons, and easily copy the component code for any selected icon. Use this tool to find and implement the perfect icons for your application's user interface.
>
>
> [Installing icons →](?path=/docs/info-get-started--docs)
# About
# About Mark Design System
> Mark is our unified design system, crafted to empower developers and designers to create consistent, accessible, and high-quality user interfaces across all our products and platforms. As a **Modular Accessible Reusable Kit**, Mark sets the standard for precision and simplicity in design.
Mark is more than a set of components — it’s a comprehensive toolkit that ensures quality, consistency, and a streamlined development process.
## Key components
### Unified Component Library
The `@mark/ui` package offers a cohesive library of pre-built, customizable components, each crafted to meet Grade’s standards for accessibility, usability, and visual harmony. These components provide a seamless experience that users will recognize and trust across platforms.
### Design Tokens for Consistency
Through `@mark/tokens`, all core design decisions—from colors to typography to spacing—are centralized and standardized, creating a consistent visual identity across every Grade product. Design tokens simplify updates and ensure our brand’s look and feel is applied universally and reliably.
### Clear, Accessible Icon System
Our `@mark/icons` package includes a curated selection of icons that integrate smoothly into projects, making information more intuitive and visually consistent. Each icon reflects Grade’s visual identity, reinforcing clarity in communication.
### Refined Typography
Typography plays a key role in conveying clarity and professionalism. With `@mark/fonts`, our system includes a selection of font families and styles that enhance readability and align with Grade’s design language, providing a polished, cohesive look across all interfaces.
### Accessibility as a Core Principle
Built with accessibility at its foundation, Mark ensures every component aligns with WCAG standards. By integrating accessible design from the beginning, Mark helps create inclusive experiences for all users, demonstrating our commitment to usability and inclusivity.
## Learn more about the principles
Mark is built on a set of principles that guide our design and development practices.
[Learn more about the principles →](?path=/docs/info-principles--docs)
### Getting Started
To begin using Mark in your project, install the core packages.
[Get started with Mark →](?path=/docs/info-get-started--docs)
### Contribution and Support
We value all input and welcome contributions to the Mark Design System. If you're interested in contributing or need support:
- Check our [contribution guidelines](https://bitbucket.fcg.fi/projects/DSG/repos/mark/browse/CONTRIBUTING.md) for details on how to get involved.
- For questions or support, reach out to the design team via [Teams]().
- Report issues or submit feature requests through our [Jira board](https://gradegroup.atlassian.net/jira/software/projects/MDS/boards/180).
# Cdn
# CDN usage
> Mark Design System components can be used directly via CDN without setting up a build system. Here's how to include the necessary files.
You can also experiment with Mark Design System components directly in CodePen. Look for `Edit in CodePen` button in our component examples to try them out instantly with the correct CDN configuration.
## Required Files
Add these files to your HTML:
## Usage Example
Here's a complete example showing how to use Mark Design System components:
## Version Information
The CDN URLs include version numbers to ensure stability in your applications. We recommend pinning to specific versions to avoid unexpected changes. The examples above use our latest stable versions:
- UI Components v{uiVersion}
- Tokens v{tokensVersion}
- Fonts v{fontsVersion}
## Subresource Integrity
For enhanced security, you can add integrity checks to your CDN imports. The integrity values for each file can be found at: `https://cdn.grade.design/mark/{package}/{version}/integrity.json`
Example with integrity:
```html
```
# Get-started
# Get Started with Mark
> This guide will help you integrate Mark into your project, enabling you to create consistent and accessible user interfaces efficiently.
## Installation
Before installing Mark packages, you'll need to authenticate with the Artifactory registry. Find more information from the [internal documentation →](https://gradegroup.atlassian.net/wiki/x/vQD2MQ)
### Authenticate with Artifactory
```bash
npm login --registry=https://artifactory.grade.fi/artifactory/api/npm/mark/ --auth-type=web --scope=@mark
```
### Install Core Packages
To begin using Mark, install our core packages using your preferred package manager:
```bash
npm install @mark/fonts @mark/icons @mark/tokens @mark/ui
```
### Optional Editor Package
If you need the WYSIWYG editor functionality, install it separately:
```bash
npm install @mark/editor
```
## IDE Setup
To enhance your development experience with autocompletion and documentation links, add the following to your `.vscode/settings.json`:
```json
{
"html.customData": [
"./node_modules/@mark/ui/dist/vscode.html-custom-data.json"
]
}
```
## Usage of Web Components
Mark components are built as web components, which means they can be used in any web application regardless of the framework. Here's how to use them:
### Properties
Properties (or attributes) can be set on the component to configure its behavior. For example:
```html
Click me
```
In this example, we're setting the `variant` property of the `m-button` component.
### Events
Web components emit events that you can listen to. For example:
```html
Click me
```
This listens for the `click` event on the button and calls the `handleClick` function when it occurs.
### Methods
Some components expose methods that you can call. You can access these methods by getting a reference to the element. For example:
```javascript
const dialogElement = document.querySelector("#my-dialog");
dialogElement.showModal();
```
This calls the `showModal` method on a dialog component.
### Slots
Slots allow you to insert content into specific places in a component. For example:
```html
Modal title
Modal content goes here
CancelSave
```
In this example, we're using the `header` and `footer` slots to insert a title and buttons into the dialog.
### Using Icons
Icons can be used either as standalone elements or within components:
```html
Click me
```
## Importing Required Packages
Before using Mark components, make sure to import all necessary packages in your main entry file (e.g., `main.ts`):
```typescript
import "@mark/fonts";
import "@mark/tokens/css";
import "@mark/icons";
import "@mark/ui";
// Import additional packages if needed
import "@mark/editor";
```
## Vue Usage
While Mark components can be used directly as web components in Vue, there are a few steps to ensure optimal integration:
### Configuring Vue for Web Components
Add the following configuration to your main Vue file (usually `main.js` or `main.ts`):
```javascript
import { createApp } from "vue";
import App from "./App.vue";
// Import all Mark components
import "@mark/ui";
const app = createApp(App);
// Configure Vue to ignore Mark custom elements
app.config.compilerOptions.isCustomElement = (tag) => tag.startsWith("m-");
app.mount("#app");
```
This configuration tells Vue to treat any element starting with `m-` as a custom element.
### Using Mark Components in Vue
After configuration, you can use Mark components in your Vue templates:
```typescript
Click meHello
```
# Localization
# Localization
> The component library provides built-in localization support that allows you to translate your components into different languages. The system uses a global translation registry and automatically detects the user's language preferences.
## Adding Translations
To add translations for a new language, use the `TranslationRegistry.registerTranslations()` method. Each translation object must include a `$lang` property specifying the language code.
```typescript
import { TranslationRegistry, Translation } from "@mark/ui";
const translations: Translation = {
$lang: "fi",
navGroupApp: {
selected: "Valittu",
upgrade: "Hanki",
upgradeLabel: "Hanki pääsy tähän ominaisuuteen",
},
};
// Register Finnish translations
TranslationRegistry.registerTranslations(translations);
```
## Language Detection
The system automatically detects the language in the following order:
1. HTML document's `lang` attribute
2. Browser's language setting
3. Fallback to 'en' (English)
# Principles
First draft
# Mark DS Principles
> Our design philosophy is centered around creating inclusive, efficient, and user-friendly products that meet real-world needs with simplicity and clarity.
We believe that effective design is a balance of innovation, accessibility, and a human touch. Each design decision reflects our commitment to providing modern, trusted solutions that enhance the experiences of HR professionals and decision-makers in the public and private sectors.
## Simplicity and Clarity
-> Our design principle of "less is more" guides us to create interfaces that are clean, intuitive, and easy to navigate.
By focusing on essential elements and removing unnecessary complexity, we ensure that users can engage with our products confidently, without distractions. Clarity is at the heart of our design language, making sure information is presented in a way that feels direct, straightforward, and supportive of user goals.
## User-Centered and Inclusive Design
-> We prioritize an inclusive approach to design that speaks in the language of the user, for the user.
Our team actively involves diverse groups throughout the design process to ensure our products serve a wide range of abilities, preferences, and backgrounds. This commitment to inclusivity means our designs are adaptable, accessible, and aim to eliminate barriers that could limit user experience.
## Consistency and Reusability
-> Our design system provides a unified structure and set of components that drive consistency across all Grade products.
This reusability not only speeds up the development process but also ensures that users encounter a familiar experience, regardless of which Grade product they are using. We build with scalability in mind, enabling our system to adapt as our product suite grows and evolves.
## Accessibility for All
-> Accessibility is at the foundation of everything we design.
Following the Web Content Accessibility Guidelines (WCAG), we ensure our products are usable for everyone, including those with disabilities. Our accessibility standards guarantee that our solutions are equitable and support all users in achieving their objectives without unnecessary hurdles.
## Data and Research-Driven Design
-> In-depth research and data guide our design decisions, ensuring that every feature we develop addresses genuine user needs.
We leverage user insights, feedback, and testing to refine our products continually, grounding each iteration in a solid understanding of our users’ behaviors and preferences. This research-driven approach allows us to evolve our products with confidence, backed by real-world evidence and experience.
## Innovation with a Human Touch
-> Our designs are modern and technically sophisticated, yet always centered around the human experience.
We aim to create an environment that is professional yet approachable, innovative yet warm. This philosophy is especially crucial as we serve HR professionals and decision-makers, for whom trust, reliability, and efficiency are paramount. Through thoughtful design, we bring warmth and clarity to our digital solutions, making them feel both cutting-edge and inviting.
# Start-here
# Welcome to Mark Design System
> Mark is [Grade Group's](https://grade.com/en/) unified design system, providing modular, reusable components and tools to streamline UI/UX development across all products.
>
>
> [More information →](?path=/docs/info-about-the-system--docs)
## Explore Mark Design System
# Ai-assisted-job-descriptions
# Universal Pattern for AI-Assisted Job Descriptions
> This guide standardizes the user experience for implementing and using the AI job description generation feature within the ATS, accommodating product-specific components. The pattern is tailored for two main user groups: Admin Users and Recruiters (regular ATS users).
## Flow overview
**Admin Flow**: Guide Admins from the promotion banner to feature settings.

**Recruiter Flow**: Guide Recruiters from generating a job ad for the first time to providing AI consent. Ensure AI consent settings are always accessible in user profile settings.

## 1. Feature Promotion for Admins

### Banner Display
- **Purpose**: Use the AI feature banner to promote the job description generation tool to eligible Admin users.
- **Visibility**: Display only to Admin Users on the **Main Home View** if the AI feature is not yet enabled.
- **Banner Action**: Link the banner to the **AI Feature Section** on the **Settings Page**, where the Admin can enable the AI feature for the entire organization.
### Post-Enablement Behavior
- Remove the promotion banner from the **Main Home View** once the feature is enabled to avoid redundant prompts.
### Additional Considerations
- **User Experience**: Ensure Admin users clearly understand the feature trial and its functions.
- **Placement**: Position the promotion prominently within the application, ideally on the dashboard or settings page.
- **Promotion Design**:
- Use the **AppPromotion** component for consistent styling and behavior.
- Display an appealing message about the feature and the trial.
- Include a clear CTA directing Admin users to the settings page to activate the feature.
## 2. Enabling AI Access for Recruiters

### Admin's Role in Feature Enablement
- Limit AI feature enablement to Admin Users only.
- Place controls for activating the AI tool in the **AI Feature Section** on the **Settings Page**.
### Result of Enabling AI Feature
- Provide Recruiters access to the AI feature in the **Job Post Settings** section within their regular job posting workflow.
### Additional Considerations
- **Settings Messaging**: Provide clear information regarding the feature, trial duration, and limitations.
- **Trial Expiry**: Explain what happens when the trial expires and how users can continue using the feature.
- **Activation Control**:
- Set the activation control (e.g., toggle, checkbox, button) to "off" by default.
- Ensure the control remains "off" when the feature is inactive.
- Hide the promotion banner once the feature is active.
## 3. Access and consent flow for recruiters

### Recruiter Access
- **Feature Location**: Place the AI feature within the **Job Post View** under **Job Post Settings** once enabled.
### Consent Requirement

- **First-Time Consent**:
- Prompt Recruiters to provide AI consent the first time they use the feature.
- **Consent Modal**: Trigger a modal with consent information and options when the Recruiter clicks the AI feature button.
- Require Recruiters to agree to AI use before generating any job description text.
### Persistent Consent Setting

- Make the **AI Consent Setting** accessible in **Profile Settings** once consent is provided.
- Allow each recruiter to review or revoke consent at any time, as this is a **personal setting**.
## Design and Component Guidelines
### Universal Flow and Product-Specific Components
- **Feature Banner Component**: Use the **Grade Product Design System** for consistent styling and behavior.
- **Product-Specific Views**: Ensure that other components and UI views integrate seamlessly with this universal AI feature pattern, even if they vary by product.
### Supported Features
- Adapt the universal flow to various product implementations, allowing teams to integrate the AI feature into existing workflows while ensuring a consistent user experience.
## User Interface Summary
{`
| **User Type** | **Initial Access Location** | **Post-Enablement Access Location** | **Consent Requirement** | **Consent Setting Access** |
|-----------------|------------------------------|--------------------------------------|-------------------------------------------|---------------------------------------|
| **Admin User** | Main Home View (Banner) | Settings Page (AI Feature Section) | None (Admin enables feature for all) | N/A |
| **Recruiter** | N/A | Job Post View (Job Post Settings) | First use only (per user, via modal) | Accessible in User Profile Settings |
`}
# Ai-button
# AI button
> This guide standardizes the creation of the AI button within each ATS, accommodating product-specific look and feel.
## AI button design overview
**Core design**: The AI button component is a simple button that triggers the AI generation process. Each ATS needs to skin their own button with the following core elements:
- **Gradient border**
- **Icon**

### Gradient border
The gradient border is a key visual element. It contians the following two colors:
- **#159EFD** (blue)
- **#A834FF** (purple)
The gradient should be a linear gradient that transitions from the top left to the bottom right.

### Icons
The second key visual element is the AI icon, which can be downloaded here. When the AI is processing, display a loading icon alongside the text "Generating...". Please use your ATS's existing loading icon to maintain consistency. If your ATS doesn't have a loading icon, you can download an alternative here.



### Animation
To provide visual feedback when the AI is processing, consider animating the gradient border when the user clicks the AI button to generate content. This animation helps indicate that the AI is actively working. For inspiration, view an example of how this animation can be implemented:
# Discovery-and-engagement
# Service Discovery & Engagement Guide
> Effective service discovery and promotion are crucial for user engagement and business growth. This pattern combines seamless navigation with strategic feature promotion to create value for both users and organizations.
## Benefits
The combination of seamless navigation and strategic feature promotion creates significant value for both users and organizations. When implemented properly, this pattern delivers clear advantages:
**For Users**
1. **Discovery Through Context**: Find relevant tools exactly when needed
2. **Seamless Experience**: Move between applications while maintaining workflow
3. **Clear Value Proposition**: Understand benefits before commitment
4. **Guided Growth**: See natural progression path for their needs
**For Organizations**
1. **Increased Adoption**: Higher discovery and conversion of complementary services
2. **Reduced Friction**: Seamless transitions reduce abandonment
3. **Strategic Promotion**: Right message at the right time
## Implementation Strategy
### 1. Navigation & Discovery
Navigation and discovery is handled by the `m-app-menu` component. It is used to display the main navigation and the additional services.
[AppMenu Documentation →](?path=/docs/components-appmenu--docs)
### 2. Feature Promotion
Feature promotion is handled by the `m-promotion-dialog` component. It is used to display a promotion dialog with a clear headline, description, benefits and call-to-action.
[PromotionDialog Documentation →](?path=/docs/components-promotion-dialog--docs)
#### Content Structure
1. **Clear Feature Badge**: Mark new or premium features distinctly, e.g. "New", "Premium", "Addon", "Feature"
2. **Compelling Headline**: Benefit-focused, action-oriented titles, "Check references digitally with Refensa"
3. **Concise Description**: Problem-solution explanation, "Save time and money by checking references digitally"
4. **Key Benefits**: 2-3 main features with visual aids, "Save time", "Save money", "Improve quality"
5. **Clear Call-to-Action**: Direct next steps, "Learn more"
#### Writing Guidelines
- Focus on user benefits over technical features
- Use everyday language, avoid jargon
- Keep descriptions brief and scannable
- Include concrete, relatable benefits
### 3. Lead Generation
Include `m-product-lead-form` component in the promotion dialog. This component is used to collect leads for the product. The form is ready to be used by providing the necessary data about the user and the product chosen.
[ProductLeadForm Documentation →](?path=/docs/components-product-lead-form--docs)
## Example Implementation
Open the menu and click on the **additional services** in the **more services** section.
## Implementation Requirements
For technical implementation details, see:
- [m-app-menu](?path=/docs/components-appmenu--docs)
- [m-promotion-dialog](?path=/docs/components-promotion-dialog--docs)
- [m-product-lead-form](?path=/docs/components-product-lead-form--docs)
- [m-nav-group](?path=/docs/components-navgroup--docs)
- [m-nav-group-app](?path=/docs/components-navgroupapp--docs)
This guide helps create an effective service discovery and promotion strategy that benefits both users and organizations while maintaining a seamless, professional experience.
# Forms
# Universal Pattern for Forms
# Form Examples
Here's a basic form handling with javascript.
## Backend Form
This example shows form validation:
# Accessibility
# Accessibility Test Report
> We test all components automatically with [axe-core](https://www.deque.com/axe/axe-core/) to ensure they are accessible. Below you can see the latest accessibility test results.
{" "}
# Changelog
# Changelog
> Track all notable changes to Mark Design System packages.
> You can find the individual changelogs of the packages from the tabs below.
{processedUI}
{processedIcons}
{processedTokens}
{processedFonts}
{processedEditor}
# Testing
# E2E Test Report
> We test every component in the design system using [Cypress](https://docs.cypress.io/guides/overview/why-cypress).
> Below you can see the latest E2E test results.
End-to-End (E2E) testing is a methodology used to test the flow of an component from start to finish inside a real browser. It aims to replicate real user scenarios and validate the components for integration and data integrity.
{" "}
# Tokens-border
# Border Tokens
> This is a list of all the border tokens in the Mark design system.
# Tokens-color
# Color Tokens
> This is a list of all the color tokens in the Mark design system.
# Tokens-font-family
# Font Family Tokens
> This is a list of all the font family tokens in the Mark design system.
# Tokens-font-size
# Font Size Tokens
> This is a list of all the font size tokens in the Mark design system.
# Tokens-font-weight
# Font Weight Tokens
> This is a list of all the font weight tokens in the Mark design system.
# Tokens-line-height
# Line Height Tokens
> This is a list of all the line height tokens in the Mark design system.
# Tokens-size
# Size Tokens
> This is a list of all the size tokens in the Mark design system.
# Tokens-space
# Space Tokens
> This is a list of all the space tokens in the Mark design system.