npm package: @jaaahn/hyper-ui
Description: A personal Vue Component Library fitting my needs
Latest version: 4.0.8

<!-- This README is auto-generated. Please do not modify this file. --> 

# Table of Contents 
   - [Intro](#welcome-to-hyperui) 
   - [Breaking Changes](#attention-breaking-changes) 
   - [Install and Import](#install-and-initialize) 
   - [Config](#config) 
   - [Preparing your HTML](#preparing-your-html-file) 
   - [Core Concepts](#core-concepts) 
     - [Brand Themes](#brand-themes) 
     - [Classic Brand Theme](#classic-hyperui-brand-theme) 
     - [Element Variants](#element-variants) 
     - [Size Option](#the-size-option) 
   - [Components](#component-documentation) 
     - [HyButton](#hybutton-component) 
     - [HyCheckbox](#hycheckbox-component) 
     - [HyDropdown](#hydropdown-component) 
     - [HyDropzone](#hydropzone-component) 
     - [HyFilterButton](#hyfilterbutton-component) 
     - [HyFlexContainer](#hyflexcontainer-component) 
     - [HyFloatingBadge](#floating-badge) 
     - [HyHeader](#hyheader-component) 
     - [HyInput](#hyinput-component) 
     - [HyListIcon](#hylisticon-component) 
     - [HyListItem](#hylistitem-component) 
     - [HyLoader](#hyloader-component) 
     - [HyMain](#hymain-component) 
     - [HyModal](#hymodal-component) 
     - [HyNavigationContainer](#hynavigationcontainer-component) 
     - [HyNavigationSidebar](#hynavigationsidebar-component) 
     - [HyNavigationTabbar](#hynavigationtabbar-component) 
     - [HyNotes](#hynotes-component) 
     - [HyPopover](#hypopover-component) 
     - [HyProgressBar](#hyprogressbar-component) 
     - [HyRadioButton](#hyradiobutton-component) 
     - [HySection](#hysection-component) 
     - [HySelect](#hyselect-component) 
     - [HySelectDropdown](#hyselectdropdown-component) 
     - [HySmartMenu](#hysmartmenu-component) 
     - [HySplitView](#hysplitview-component) 
     - [HySubSection](#hysubsection-component) 
     - [HyTabbar](#hytabbar-component) 
     - [HyTable](#hytable-component) 
     - [HyTextArea](#hytextarea-component) 
     - [HyToggle](#hytoggle-component) 
     - [HyTooltip](#hytooltip-component) 
   - [Utility Classes](#utility-classes) 
   - [CSS Variables](#css-variables) 
   - [Tips & Tricks](#tips-and-tricks) 
     - [Z-Index Guide](#z-index-guide) 
     - [Changing the font-size](#changing-the-font-size) 
     - [Desktop and Mobile Mode](#desktop-and-mobile-mode) 
     - [Recommended Navigation Code Structure](#recommended-navigation-code-structure) 
     - [How v-model works](#how-v-model-works) 
     - [Working with Slots](#working-with-slots) 
     - [Re-Style Components](#re-style-components) 
   - [Changelogs](#changelogs) 

# Welcome to HyperUI 

Welcome to HyperUI, a personal Vue 3 component library fitting my needs.

HyperUI aims on being an easy to use, opinionated component library for Vue 3. It provides components and the necessary building blocks to design web apps, but unlike other libraries does not provide excessive customizability. HyperUI supports automatic darkmode based on the users system preferences.

As this library is a personal project, it does not come with a lot of customization options, but in this documentation there are some tips on how to customize the design using CSS. If you think like there is something off with your design, then feel encouraged to use CSS to tweak it the way you like it.

Licensed under [MIT License](LICENSE).
 
# Attention Breaking Changes 

## Upgrading to [Version 4.0.0](#changelogs)

We provide an upgrade script that can migrate your project mostly from v3 to v4. This script can only update attribute, prop and css variable changes. Any syntax upgrades will have to be performed by you.

```
$ npx -p @jaaahn/hyper-ui upgrade-v3-to-v4
```

When running, the script will prompt you for a directory. It will migrate any file within that directory. Use version control to go over changes and inspect your codebase after migration for any damage that the migration script might have caused.

The following paragraphs detail all the changes made in this release.  
Any points marked with `[x]` can be done by the migration script. Any changes marked with `[ ]` have to be manually migrated.

### Renamed props for a more consistent experience

| Auto  | Component        | OLD                   |     | NEW                   | Notes                                  |
| ----- | ---------------- | --------------------- | --- | --------------------- | -------------------------------------- |
| `[x]` | HyButton         | `type`                | --> | `variant`             |                                        |
| `[x]` | HyDropdown       | `border`              | --> | `showBorder`          |                                        |
| `[x]` | HyHeader         | `extendHeadline`      | --> | `doExtendHeadline`    |                                        |
| `[ ]` | HyModal          | `hideScrollbars`      | --> | `showScrollbars`      | !!! inverted behaviour                 |
| `[ ]` | HyModal          | `disableSwipeToClose` | --> | `swipeToCloseEnabled` | !!! inverted behaviour                 |
| `[ ]` | HyModal          | `disableDismiss`      | --> | `dismissible`         | !!! inverted behaviour                 |
| `[ ]` | HySmartMenu      | `hideScrollbars`      | --> | `showScrollbars`      | !!! inverted behaviour                 |
| `[ ]` | HySmartMenu      | `disableSwipeToClose` | --> | `swipeToCloseEnabled` | !!! inverted behaviour                 |
| `[ ]` | HySmartMenu      | `disableDismiss`      | --> | `dismissible`         | !!! inverted behaviour                 |
| `[x]` | HySmartMenu      | `type`                | --> | `variant`             |                                        |
| `[x]` | HyPopover        | `hover`               | --> | `doOpenOnHover`       |                                        |
| `[x]` | HyPopover        | `type`                | --> | `variant`             |                                        |
| `[x]` | HySection        | `border`              | --> | `showBorder`          |                                        |
| `[x]` | HySection        | `dividers`            | --> | `showDividers`        |                                        |
| `[x]` | HySelectDropdown | `enableSearch`        | --> | `showSearch`          |                                        |
| `[x]` | HySelectDropdown | `border`              | --> | `showBorder`          |                                        |
| `[x]` | HyTable          | `border`              | --> | `showBorder`          |                                        |
| `[x]` | HyTabbar         | `type`                | --> | `variant`             | !!! Renamed option "blue" to "primary" |

### Renamed element variants

| Auto  | OLD               |     | NEW               | Notes                            |
| ----- | ----------------- | --- | ----------------- | -------------------------------- |
| `[x]` | `transparent`     | --> | `ghost`           |                                  |
| `[x]` | `transparent-bg`  | --> | `ghost-bg`        |                                  |
| `[x]` | `light-blue`      | --> | `ghost-blue`      |                                  |
| `[x]` | `light-bg-blue`   | --> | `ghost-bg-blue`   |                                  |
| `[x]` | `light-red`       | --> | `ghost-red`       |                                  |
| `[x]` | `light-bg-red`    | --> | `ghost-bg-red`    |                                  |
| `[x]` | `light-orange`    | --> | `ghost-yellow`    | !!! renamed "orange" to "yellow" |
| `[x]` | `light-bg-orange` | --> | `ghost-bg-yellow` | !!! renamed "orange" to "yellow" |
| `[x]` | `light-green`     | --> | `ghost-green`     |                                  |
| `[x]` | `light-bg-green`  | --> | `ghost-bg-green`  |                                  |

### Renamed size options

| Auto  | OLD      |     | NEW  | Notes             |
| ----- | -------- | --- | ---- | ----------------- |
| `[x]` | `normal` | --> | `lg` | Still the default |
| `[x]` | `light`  | --> | `md` |                   |
| `[x]` | `thin`   | --> | `sm` |                   |

### Prefixed CSS Variables

`[x]` We prefixed all CSS variables with `--hy-`. The migration script can upgrade all of these.

### Changed some CSS variable names regarding naming element variants naming scheme

`[x]` Some css variable names have changed to align more with the updated element variants.

### Changes in HyPopovers and HySmartMenus including their "Free" variants

`[ ]`

We rewrote the HyPopover component leading to a breaking interface change regarding it and HySmartMenu.

Going forward, all HyPopovers work like the old HyPopoverFree (apart from prop name changes).
This means, the reference element is now passed via a prop instead of inlining it with the use of a slot.

Consider this code:

```html
<hy-popover v-model="isOpen">
    <template #element>
        <hy-button @click="..."> ... </hy-button>
    </template>

    <template #content>
        Popover content
    </template>
</hy-popover
```

This code would now be:

```html
<hy-button id="targetButton" @click="..."> ... </hy-button>

<hy-popover reference="#targetButton" v-model="isOpen"> Popover content </hy-popover>
```

Please notice the changes we did to the code:

-   Added an `id` attribute to the target element
-   Moved the target element out of the popover (allowing us to get rid of the `<template>`s)
-   Added the `reference` attribute with a query selector string for selecting the target element

HyPopovers inherits from its predecessor HyPopoverFree the ability to directly accept `HTMLElements`.

These changes also mean, we updated how SmartMenus work and removed the HyPopoversFree and HySmartMenuFree components.  
For more information, please read the docs for [HyPopovers](#hypopover-component) and [HySmartMenus](#hysmartmenu-component).

## Upgrading to [Version 3.0.0](#changelogs):

We refined the naming scheme of this library. Please search your codebase for these classes and replace them with:

| OLD                    |     | NEW                                                                              |
| ---------------------- | --- | -------------------------------------------------------------------------------- |
| `reset`                | --> | `hy-reset`                                                                       |
| `--font-color-similar` | --> | `--hy-font-color-match`                                                          |
| `same`                 | --> | `match` (only affects HyPopover, HyPopoverFree, HySmartMenu and HySmartMenuFree) |

We also changed targeting classes and utility classes to fit this new naming scheme. We strongly incourage you to use the new syntax. With this syntax, every class now matches its corresponding component name:

| OLD                         |     | NEW                       |
| --------------------------- | --- | ------------------------- |
| `hyper-button`              | --> | `hy-button`               |
| `hyper-checkbox`            | --> | `hy-checkbox`             |
| `hyper-dropzone`            | --> | `hy-dropzone`             |
| `hyper-flexcontainer`       | --> | `hy-flex-container`       |
| `hyper-header`              | --> | `hy-header`               |
| `hyper-input`               | --> | `hy-input`                |
| `hyper-listicon`            | --> | `hy-list-icon`            |
| `hyper-loader`              | --> | `hy-loader`               |
| `hyper-main`                | --> | `hy-main`                 |
| `hyper-modal`               | --> | `hy-modal`                |
| `hyper-navigationcontainer` | --> | `hy-navigation-container` |
| `hyper-navigationsidebar`   | --> | `hy-navigation-sidebar`   |
| `hyper-navigationtabbar`    | --> | `hy-navigation-tabbar`    |
| `hyper-popover`             | --> | `hy-popover`              |
| `hyper-popoverfree`         | --> | `hy-popover-free`         |
| `hyper-progressbar`         | --> | `hy-progress-bar`         |
| `hyper-radiobutton`         | --> | `hy-radio-button`         |
| `hyper-section`             | --> | `hy-section`              |
| `hyper-select`              | --> | `hy-select`               |
| `hyper-smartmenu`           | --> | `hy-smart-menu`           |
| `hyper-smartmenufree`       | --> | `hy-smart-menu-free`      |
| `hyper-subsection`          | --> | `hy-sub-section`          |
| `hyper-tabbar`              | --> | `hy-tabbar`               |
| `hyper-table`               | --> | `hy-table`                |
| `hyper-textarea`            | --> | `hy-text-area`            |
| `hyper-toggle`              | --> | `hy-toggle`               |

## Upgrading to [Version 2.0.0](#changelogs):

-   New component naming scheme -> Please refer to the component documentation
-   Styles now need to be imported manually -> Please refer to the [Import Section](#install-and-initialize)
 
# Install and Initialize 

## Installing

### From a CND

```html
<script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.js"></script>

<script src="https://cdn.jsdelivr.net/npm/@jaaahn/hyper-ui/dist/hyper-ui.iife.js"></script>
```

This will expose the global variable `HyperUI` which can be used to install the library: `app.use(HyperUI, config)`.  
Importing styles is not required if importing from a CDN.

### Via NPM

`npm install @jaaahn/hyper-ui`

## Initializing the library

```js
// Standard Vue Code
import { createApp } from "vue";
import App from "./App.vue";

const app = createApp(App);
// Standard Vue Code above
// #######################

// See below for config options; these can be omitted
let config = {
    theme: "system",
    // size: "lg",
    // variant: "ghost-bg-blue",
};

import HyperUI from "@jaaahn/hyper-ui";
app.use(HyperUI, config); // config is optional and can be omitted

import "@jaaahn/hyper-ui/styles"; // Import styles !IMPORTANT!

// #######################
// Standard Vue Code below
app.mount("#app");
```

This is all you need. Now you can use these components within your template. You don't need to import them in each file and you also don't need to put them within you `components` object in your Vue instance as you would do it with your own custom components.
 
# Config 

HyperUI allows you to change its behaviour by providing a config.  
This config is a `JS object` passed to the `app.use(...)` function as the second argument (see [import](#install-and-initialize)). But, passing this is completely optional and the config can just be omitted if one does not want to change the libraries behaviour.

### Config options

| Name         |  Type  | Default                      | Available options                                         | Extra info                                                                        |
| ------------ | ------ | ---------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------- |
| `theme`      | String | "system"                     | system, light, dark                                       | "system" will choose light- or darkmode depending on the users system preferences |
| `size`       | String | "lg"                         | [Size option](#the-size-option)               | Only on supported elements                                                        |
| `variant`    | String | component specific           | [See element variants](#element-variants) | Only on supported elements                                                        |
| `brandTheme` | Object | Classic HyperUI color scheme | [View guide](#brand-themes)               |                                                                                   |
 
# Preparing your HTML file 

If you are planning on using the included [HyHeader](#hyheader-component) component, please add these theme-color meta tags to your html head:

```html
<meta name="theme-color" content="#fff" media="(prefers-color-scheme: light)" />

<meta name="theme-color" content="#191c1f" media="(prefers-color-scheme: dark)" />
```

If you are NOT planning on using the Header, then add the following to your html head:

```html
<meta name="theme-color" content="#eeeef2" media="(prefers-color-scheme: light)" />

<meta name="theme-color" content="#0c0c0e" media="(prefers-color-scheme: dark)" />
```
 
# Core concepts 

The following pages will explain some of the core concepts of this library.
 
# Brand themes 

Brand themes are HyperUI's way of managing a color palette. If your app requires specific brand colors, brand themes allow you to fully customize available colors and element variants.

Components will use the colors specified in your brand theme to compute their color/variant options.

The `brandTheme` object can be passed when initializing the library. If you omit this, HyperUI will use it's own colors.

The `brandTheme` object has two entries:

```js
brandTheme: {
    colors: {
        ...
    },
    accentColor: "...",
},
```

In the colors object, list all colors you want the application to have. You may use any color format supported by CSS.

Then, please select an `accentColor` by using the name of the color.

If you need an example, please look at [Classic HyperUI Brand Theme](#classic-hyperui-brand-theme)
On documentation about CSS variables computed from brand colors, refer to [CSS Variables](#css-variables)
 
# Classic HyperUI brand theme 

```js
brandTheme: {
    colors: {
        blue: "hsl(222, 100%, 61%)",
        pink: "hsl(340, 82%, 49%)",
        yellow: "hsl(44, 97%, 50%)",
        green: "hsl(116, 45%, 54%)",
        red: "hsl(0, 76%, 58%)",
        "light-blue": "hsl(205, 100%, 62%)",
        purple: "hsl(321, 62%, 46%)",
    },
    accentColor: "blue", // Choose a color from the colors object
},
```

This means, the following colors are available: "blue", "pink", "yellow", "green", "red", "light-blue", "purple".
The accent (primary) color is "blue".

You can import the classic brand theme from HyperUI to extend it:

```js
import HyperUI, { CLASSIC_COLORS, CLASSIC_BRAND_THEME } from "@jaaahn/hyper-ui";
```

Where CLASSIC_COLORS is the `colors` object and CLASSIC_BRAND_THEME is the entire `brandTheme` object described above.
 
# Element variants 

On supported elements, these variants are available.

| Option name | Result                                                                                | Notes                      |
| ----------- | ------------------------------------------------------------------------------------- | -------------------------- |
| `primary`   | Primary action button style featuring the blue accent color                           | Only available on HyButton |
| `secondary` | Secondary action button, matches the background color                                 |                            |
| `ghost`     | Button with only text. Has hover and click effect.                                    |                            |
| `ghost-bg`  | Button with text and a slightly visible gray background. Has hover and click effect.  |                            |

Additionally, all colors of your selected brand theme become available as "solid", "ghost" and "ghost-bg" element variants.

An example: If you have a color called "green", then these variants will be made available: `green`, `ghost-green` and `ghost-bg-green`.
 
# The size option 

Currently, the size option supports `lg`, `md` and `sm`. This option can be set individually for each element or via HyperUI config globally.

The `lg` option is the default for HyperUI.
 
# Component Documentation 

On the following pages we want to list all included components as well as provide examples and demos.

Component names can be written in Camel Case with the first letter also capitalized, like `HyFlexContainer` or `HyButton`. Alternatively you can also write the components in lowercase syntax like `hy-flex-container` or `hy-button`.

Mind you: If passing a non string to a prop, you need to use `v-bind:PROPNAME`. Otherwise you will get a warning in your console.
 
# HyButton Component 

Basic `<button>` element. It comes in two colors, can be disabled and put into a loading state.

### Targeting class

`hy-button`

### Slot

Pass a slot which will be displayed as the normal `<button>` text.

### Options

| Name            | Type    | Default                                                   | Available options              | Required | Extra info                                                                                                                                 |
| --------------- | ------- | --------------------------------------------------------- | ------------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| `variant`       | String  | "secondary"                                               | primary, secondary, ghost, ... |          | [See available variants](#element-variants)                                                                               |
| `size`          | String  | "lg"                                                      | lg, md, sm                     |          | [Size Option Docs](#the-size-option)                                                                                          |
| `loading`       | Boolean | false                                                     |                                |          | For spinner: leave progress = null. For progress bar: set loading = true and provide a progress value between 0-1                          |
| `progress`      | Number  | null                                                      |                                |          | Range between 0-1. Values not in this range will be caped                                                                                  |
| `progressWidth` | String  | "min(calc(100% - 2 \* var(--hy-element-padding)), 200px)" |                                |          | Specify a width (in css syntax)                                                                                                            |
| `disabled`      | Boolean | false                                                     |                                |          |
| `extend`        | Boolean | true                                                      |                                |          | Controls whether the element extends to 100% or stays at `max-content`. Deprecated, use [`.hy-extend-full`](#utility-classes) instead. |

### Example

```html
<!-- Loading with spinner -->
<hy-button @click="method('hello')" :disabled="false" :loading="isLoading" variant="primary"> Click me </hy-button>

<!-- Loading with progress -->
<hy-button @click="method('hello')" :disabled="false" :loading="isLoading" :progress="loadingProgress" variant="primary">
    Click me
</hy-button>
```

### Note: Target a specific style of button

Every `HyButton` component is a `<button>` nested inside a `<div>` element (see [Re-Styling Components](#re-style-components)).
The specific styles (controlled by the `variant` option) are applied to the `<button>` element by a class, which matches the variants's name.
So, if you want to change the background-color of every ghost button, you could use something like:

```css
.hy-button :deep(button.ghost) {
    background-color: yellow !important;
}

/* :deep() is explained in the "Re-Style Components" section */
```
 
# HyCheckbox Component 

Standard checkbox. It can be disabled.
Use `v-model` to create a two-way binding.

### Targeting class

`hy-checkbox`

### v-model

Syncs whether the box is ticked or not with your parent vue instance. View the [Info about v-model](#how-v-model-works) section for more details.

### Slot

Use the slot to pass text which will be displayed as a label.

### Options

| Name         | Type    | Default | Available options | Required | Extra info                                                                                                                                     |
| ------------ | ------- | ------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `modelValue` | Boolean |         |                   | Required | Two-way binding for the checkbox's value                                                                                                       |
| `disabled`   | Boolean | false   |                   |          |
| `extend`     | Boolean | true    |                   |          | Controls wether the element extends to 100% or stays at `max-content`. Not recommended, use [`.hy-extend-full`](#utility-classes) instead. |
| `type`       | String  | "left"  | left, right       |          | Aligns either label and box left, or label on the left and box on the right                                                                    |

### Example

```html
<hy-checkbox v-model="someBooleanVariable" :disabled="disabledVariable" type="right"> Click me </hy-checkbox>
```
 
# HyDropdown Component 

An expanding menu. The menu floats above other content (and thus is not an inline element) but remains visually attached. It therefore is the mid-ground between a popover and an expandable section.

### Targeting class

`hy-dropdown`

### Slot

| Name      | Is also the default slot | Required | Extra info                                                                                                                    |
| --------- | ------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `content` | Yes                      | Required | The content to display in the menu                                                                                            |
| `title`   | No                       |          | If you don't want to use the `title` prop, you may use this slot. Note: additional styling of the element might be necessary. |
| `icon`    | No                       |          |                                                                                                                               |

### Options

| Name                 | Type    | Default                                                   | Available options     | Required | Extra info                                                                                                        |
| -------------------- | ------- | --------------------------------------------------------- | --------------------- | -------- | ----------------------------------------------------------------------------------------------------------------- |
| `modelValue`         | Boolean |                                                           |                       | Required | Controls whether or not the dropdown is open                                                                      |
| `title`              | String  |                                                           |                       | Required |                                                                                                                   |
| `showBorder`         | Boolean | false                                                     |                       |          |                                                                                                                   |
| `loading`            | Boolean | false                                                     |                       |          | For spinner: leave progress = null. For progress bar: set loading = true and provide a progress value between 0-1 |
| `progress`           | Number  | null                                                      |                       |          | Range between 0-1. Values not in this range will be caped                                                         |
| `progressWidth`      | String  | "min(calc(100% - 2 \* var(--hy-element-padding)), 200px)" |                       |          | Specify a width (valid css)                                                                                       |
| `disabled`           | Boolean | false                                                     |                       |          |                                                                                                                   |
| `size`               | String  | "lg"                                                      | lg, md, sm            |          | [Size Option Docs](#the-size-option)                                                                 |
| `variant`            | String  | "secondary"                                               | secondary, ghost, ... |          | [See available variants](#element-variants)                                                      |
| `maxHeight`          | String  | null                                                      |                       |          | Specify a height (valid css) or `null` to leave it unconstrained                                                  |
| `zIndex`             | Number  | 10                                                        |                       |          | Z-Index of the expanding menu                                                                                     |
| `hideOnClickOutside` | Boolean | true                                                      |                       |          | If the user clicks outside, the menu will hide                                                                    |
| `dropdownDirection`  | String  | "bottom"                                                  | bottom, top           |          | The direction the dropdown expands to                                                                             |
| `invalid`            | Boolean | false                                                     |                       |          | Highlights input with red color if true                                                                           |
| `invalidText`        | String  | null                                                      |                       |          | Displays a message (if invalid = true)                                                                            |

### Examples

```html
<hy-dropdown v-model="dropdownIsOpenVariable" title="Click to expand">
    <p>Hello World</p>
</hy-dropdown>
```

Or with an icon (syntax equal to hy-select or hy-input)

```html
<hy-dropdown v-model="dropdownIsOpenVariable" title="Click to expand">
    <template #content>
        <p>Hello World</p>
    </template>

    <template #icon>
        <i class="icon-settings"></i>
    </template>
</hy-dropdown>
```
 
# HyDropzone Component 

A dropzone component. Drop a file or click on it to open a native file selector window.

### Targeting class

`hy-dropzone`

### Options

| Name          | Type   | Default                                    | Available options                        | Required | Extra info                                                                                                                                          |
| ------------- | ------ | ------------------------------------------ | ---------------------------------------- | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `placeholder` | String | "Drop file here or click to select a file" |                                          |          |                                                                                                                                                     |
| `readMode`    | String | "text"                                     | text, binaryString, dataURL, arrayBuffer |          | How the file will be read. [More info about what they do](https://developer.mozilla.org/en-US/docs/Web/API/FileReader#methods)                      |
| `accept`      | String | "\*"                                       |                                          |          | Which files to accept. [About this attribute and how its syntax works](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input/file#accept) |

### Reading the selected file

Once the user selects a file, the `newValue` event will be fired with an event object containing the following information:

```
{
    content: String,
    name: String,
    size: Number,
    lastModified: Number,
    type: String // MIME-Type of the selected file
}
```

### Clearing the selected file

If one wants to clear the selected file, please call the `clear` method on the component instance. If this method is called, the `newValue` event will fire with `$event = null`.  
Guide on how to do this using Vue refs:

```html
<hy-dropzone readMode="dataURL" accept="image/*" @newValue="my_method_for_handling_the_event($event)" ref="myDropzone" />

<hy-button @click="$refs.myDropzone.clear()"> Clear </hy-button>
```

### Directly accessing the underlying `<input>` element

The underlying `<input type="file">` html element is the second child node of the dropzone component. Thus is can be direcly referenced:

```html
<hy-dropzone ref="myDropzone" />
```

```js
let inputElement = this.$refs.myDropzone.$el.childNodes[1];
```

### Example

Hint: In Vue, the `$event` is the variable that contains the event object of the triggered event.

```html
<hy-dropzone readMode="text" accept="text/*,application/*,.md" @newValue="myVariable = $event" />
```

Or:

```html
<hy-dropzone readMode="dataURL" accept="image/*" @newValue="my_method_for_handling_the_event" />
```

Or:

```html
<hy-dropzone readMode="dataURL" accept="image/*" @newValue="my_method_for_handling_the_event($event)" />
```
 
# HyFilterButton Component 

This component brings a filter "pill-shaped" [HyButton](#hybutton-component) with an "is active" indicator and a [HySmartMenu](#hysmartmenu-component). The button opens and closes the menu, no need for `v-model`.

### Targeting class

`hy-filter-button`

### Slot

| Name      | Is also the default slot | Required | Extra info                                                        |
| --------- | ------------------------ | -------- | ----------------------------------------------------------------- |
| `button`  | No                       | Required | Slot for button content                                           |
| `content` | No                       | Required | SmartMenu/Popover: content slot. Receives the `menuType` variable |
| `header`  | No                       |          | SmartMenu/Popover: header slot. Receives the `menuType` variable  |
| `footer`  | No                       |          | SmartMenu/Popover: footer slot. Receives the `menuType` variable  |

### Options

| Name             | Type    | Default   | Available options             | Required | Extra info                                                                                                   |
| ---------------- | ------- | --------- | ----------------------------- | -------- | ------------------------------------------------------------------------------------------------------------ |
| `active`         | Boolean | false     |                               |          | Shows that the filter is active by adding a [Floating Badge](#floating-badge) to the button |
| `mode`           | String  | "popover" | popover, smartMenu            |          | Type of menu to use                                                                                          |
| `variantButton`  | String  | null      | primary, secondary, ghost ... |          | `variant` option of [HyButton](#hybutton-component). If not overwritten, will use the selected default |
| `variantPopover` | String  | "match"   | match, contrast               |          | `variant` option of [HyPopover](#hypopover-component) and [HySmartMenu](#hysmartmenu-component)  |

The component inherits all options of [HyButton](#hybutton-component), except for: `variant`  
The component inherits all options of [HySmartMenu](#hysmartmenu-component), except for: `variant`, `modelValue`, `reference`
The component inherits all options of [HyPopover](#hypopover-component), except for: `variant`, `modelValue`, `reference`, `doOpenOnHover`, `hoverDelay`

### Example

```html
<hy-filter-button headline="Filter example" minWidth="300px" :active="search != ''">
    <template #button>
        <i class="icon-search"></i>
        Search
    </template>

    <template #content>
        <hy-input v-model="search"></hy-input>
    </template>
</hy-filter-button>
```

Tip: wrap multiple filter buttons inside a [HyFlexContainer](#hyflexcontainer-component) with `:allowBreak="false" justify="flex-start"` set to create a filter row.
 
# HyFlexContainer Component 

This is basically a `div` with `display: flex` applied to it. If the screen is smaller than 800px, the `flex-direction` will be set to `column`

### Targeting class

`hy-flex-container`

### Slot

Pass the elements you want to position within the FlexContainer via the slot.

### Options

| Name            | Type    | Default         | Available options                  | Required | Extra info                                                                                              |
| --------------- | ------- | --------------- | ---------------------------------- | -------- | ------------------------------------------------------------------------------------------------------- |
| `wrap`          | Boolean | true            | see `css flex-wrap` property       |          |                                                                                                         |
| `justify`       | String  | "space-between" | see `css justify-content` property |          |                                                                                                         |
| `verticalAlign` | String  | "center"        | see `css align-items` property     |          |                                                                                                         |
| `direction`     | String  | "row"           | see `css flex-direction` property  |          |                                                                                                         |
| `allowBreak`    | Boolean | true            |                                    |          | Wether the flex-container should switch to `flex-direction: column` if the screen is smaller than 800px |

Your items will shrink to the minimum width without shrinking your content (e.g. text). If you would like to change this behaviour, please do this manually in your css.

### Example

```html
<hy-flex-container>
    <input />
    <button>Hello</button>
    <hy-checkbox />
</hy-flex-container>
```
 
# Floating Badge 

This is not a component but rather a utility class.

To activate, apply to any element the class `hy-floating-badge`.  
Now you may specify the text to display via an `data-badge-text` attribute.
You may use `v-bind:data-badge-text` to bind the attribute to a reactive vue variable (see example 2). This attribute can be ommited (or fed an empty string) to just show a small dot above the target element (see example 3).

### Examples

Example 1:

```html
<hy-button class="hy-floating-badge" data-badge-text="10k">Show the News</hy-button>
```

Example 2:

```html
<hy-button class="hy-floating-badge" v-bind:data-badge-text="myBadgeText">Show the News</hy-button>

<hy-input v-model="myBadgeText" placeholder="Badge text"></hy-input>
```

Example 3:

```html
<hy-button class="hy-floating-badge">Show the News</hy-button>
```
 
# HyHeader Component 

A page header component. Sticks to the top of the screen on mobile and floats on desktop devices.

### Attention

The following steps need be performed if using this component:

-   We recommend using the same values for the properties `maxHeight` and `resizeTo` as used on [HyMain](#hymain-component)
-   We recommend using the same value for the property `switchToMobileAt` as used on [HyNavigationContainer](#hynavigationcontainer-component)
-   Always place the header ABOVE the [HyMain](#hymain-component) component
-   Put this in your HTML head:

    ```html
    <meta name="theme-color" content="#fff" media="(prefers-color-scheme: light)" />

    <meta name="theme-color" content="hsl(220, 5%, 13%)" media="(prefers-color-scheme: dark)" />
    ```

**If you need any guidance on how to structure your code, take a look at this guide: [Recommended navigation code structure](#recommended-navigation-code-structure)**

### Targeting class

`hy-header`

### Slot

| Name    | Is also the default slot | Required | Extra info                       |
| ------- | ------------------------ | -------- | -------------------------------- |
| `left`  | Yes                      |          | Position: left, next to headline |
| `right` | No                       |          | Position: far right              |

### Options

| Name               | Type    | Default  | Available options | Required  | Extra info                                                                                                      |
| ------------------ | ------- | -------- | ----------------- | --------- | --------------------------------------------------------------------------------------------------------------- |
| `headline`         | String  | null     |                   |           |                                                                                                                 |
| `icon`             | String  | null     |                   |           | Name of an icon to display left of headline. Uses an `<i class="..." />`                                        |
| `doCoverShadow`    | Boolean | true     |                   |           | Adds a shadow underneath. Lets elements scrolling underneath fade into the void                                 |
| `floating`         | Boolean | true     |                   |           | Do floating look on desktop devices                                                                             |
| `doExtendHeadline` | Boolean | true     |                   |           | Controls `.hy-extend-full` class on headline element                                                            |
| `maxWidth`         | String  | "1400px" |                   |           | Must be same value as corresponding property on [HyMain](#hymain-component)                               |
| `resizeTo`         | Number  | 95       |                   |           | Must be same value as corresponding property on [HyMain](#hymain-component)                               |
| `switchToMobileAt` | Number  | 850      |                   |           | Must be same value as corresponding property on [HyNavigationContainer](#hynavigationcontainer-component) |
| `zIndex`           | Number  | 50       |                   |           |                                                                                                                 |

### Example

```html
<hy-header maxWidth="800px" :resizeTo="90" headline="HyperUI" icon="icon-home">
    <!-- Any additional elements go here -->
</hy-header>
```

More complex example with two slots

```html
<hy-header maxWidth="800px" :resizeTo="90" headline="HyperUI" icon="icon-home">
    <!-- Left slot must be named explicitly -->
    <template #left>
        <hy-button variant="ghost-bg" size="sm"> <i class="icon-chevron-left"></i> Back </hy-button>
    </template>

    <!-- Right slot can be treated as the default slot, but can named explicitly -->
    <hy-button variant="primary" size="sm"> Hello </hy-button>
</hy-header>
```
 
# HyInput Component 

Basic `<input>` element. It can be disabled and put into an loading state.  
Use `v-model` to create a two-way binding.

### Targeting class

`hy-input`

### v-model

Syncs the current input value with your parent vue instance. View the [Info about v-model](#how-v-model-works) section for more details.

### Slot

| Name    | Is also the default slot | Required | Extra info          |
| ------- | ------------------------ | -------- | ------------------- |
| `left`  | Yes                      |          | Position: left      |
| `right` | No                       |          | Position: far right |

### Options

| Name            | Type    | Default                                                   | Available options     | Required | Extra info                                                                                                                                     |
| --------------- | ------- | --------------------------------------------------------- | --------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `modelValue`    | any     |                                                           |                       | Required | Two-way binding for the input's value                                                                                                          |
| `type`          | String  | "text"                                                    |                       |          | Equal to HTML's `type` attribute. E.g. `type="password"`                                                                                       |
| `variant`       | String  | "secondary"                                               | secondary, ghost, ... |          | [See available variants](#element-variants)                                                                                   |
| `size`          | String  | "lg"                                                      | lg, md, sm            |          | [Size Option Docs](#the-size-option)                                                                                              |
| `placeholder`   | String  | ""                                                        |                       |          |                                                                                                                                                |
| `loading`       | Boolean | false                                                     |                       |          | For spinner: leave progress = null. For progress bar: set loading = true and provide a progress value between 0-1                              |
| `disabled`      | Boolean | false                                                     |                       |          |
| `extend`        | Boolean | true                                                      |                       |          | Controls wether the element extends to 100% or stays at `max-content`. Not recommended, use [`.hy-extend-full`](#utility-classes) instead. |
| `required`      | Boolean | false                                                     |                       |          | Equal to HTML's `required` attribute.                                                                                                          |
| `progress`      | Number  | null                                                      |                       |          | Range between 0-1. Values not in this range will be caped                                                                                      |
| `progressWidth` | String  | "min(calc(100% - 2 \* var(--hy-element-padding)), 200px)" |                       |          | Specify a width (valid css)                                                                                                                    |
| `invalid`       | Boolean | false                                                     |                       |          | Highlights input with red color if true                                                                                                        |
| `invalidText`   | String  | null                                                      |                       |          | Displays a message (if invalid = true)                                                                                                         |
| `doAutofocus`   | Boolean | false                                                     |                       |          | Will focus input on mounted and blur before being unmounted                                                                                    |

### NOTE: Inheriting Props

All HTML attributes except `id`, `class` and vue props listed above, will be inherited to the underlying `<input>` element.

### Example

```html
<hy-input v-model="username" :disabled="false" :loading="isLoading" type="text" placeholder="Your username"></hy-input>
```

With an Icon on the left side

```html
<hy-input v-model="username" :disabled="false" :loading="isLoading" type="text" placeholder="Your username">
    <i class="icon-search"></i>
</hy-input>
```

With an Icon on the right side

```html
<hy-input v-model="username" :disabled="false" :loading="isLoading" type="text" placeholder="Your username">
    <template #right>
        <i class="icon-megaphone"></i>
    </template>
</hy-input>
```

With an Icon on the left and on the right side

```html
<hy-input v-model="username" :disabled="false" :loading="isLoading" type="text" placeholder="Your username">
    <template #left>
        <i class="icon-search"></i>
    </template>
    <template #right>
        <i class="icon-megaphone"></i>
    </template>
</hy-input>
```

With progress bar

```html
<hy-input
    v-model="username"
    :disabled="false"
    :loading="isLoading"
    :progress="loadingProgress"
    type="text"
    placeholder="Your username"
></hy-input>
```
 
# HyListIcon Component 

An iOS style list icon. Best used within sections with automatic dividers turned on to create an elegant e.g. settings page.

### Targeting class

`hy-list-icon`

### Slot

Pass your icon into the default slot.

### Options

| Name    | Type   | Default       | Available options | Required | Extra info                                                                                                                               |
| ------- | ------ | ------------- | ----------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `color` | String | "transparent" | blue, red, ...    |          | Background color. [Use colors of your brand theme](#brand-themes).                                                      |
| `icon`  | String | undefined     |                   |          | If you have an icon font, use this prop instead of the icon slot. It's value will be applied to the class attribute of an `<i>` element. |

### Example

```html
<hy-list-icon color="light-blue">
    <i class="icon-printer"></i>
    <!-- Your icon -->
</hy-list-icon>
```

Best used in sections:

```html
<hy-section :showDividers="true">
    <hy-flex-container :allowBreak="false">
        <hy-list-icon color="pink"> <i class="icon-printer"></i> </hy-list-icon>

        <hy-toggle type="right"> Toggle this </hy-toggle>
    </hy-flex-container>

    <hy-flex-container :allowBreak="false">
        <hy-list-icon color="orange"> <i class="icon-plus-circle"></i> </hy-list-icon>

        <p>Look at this</p>
    </hy-flex-container>
</hy-section>
```
 
# HyListItem Component 

This list item was designed to build elegant settings pages. Best used within sections with automatic dividers turned on.

### Targeting class

`hy-list-item`

### Slot

| Name      | Is also the default slot | Required | Extra info               |
| --------- | ------------------------ | -------- | ------------------------ |
| `content` | Yes                      | Required | Content of the list item |
| `icon`    | No                       |          | A SVG icon               |

### Options

| Name            | Type    | Default         | Available options | Required   | Extra info                                                                                                        |
| --------------- | ------- | --------------- | ----------------- | ---------- | ----------------------------------------------------------------------------------------------------------------- |
| `color`         | String  | "transparent"   | blue, red, ...    |            | [See HyListIcon options](#hylisticon-component)                                                             |
| `icon`          | String  | undefined       |                   |            | [See HyListIcon options](#hylisticon-component)                                                             |
| `clickable`     | Boolean | false           |                   |            | Adds a chevron on the right and sets `cursor: pointer`                                                            |
| `loading`       | Boolean | false           |                   |            | For spinner: leave progress = null. For progress bar: set loading = true and provide a progress value between 0-1 |
| `progress`      | Number  | null            |                   |            | Range between 0-1. Values not in this range will be caped                                                         |
| `progressWidth` | String  | "min(50%, 70px) |                   |            | Specify a width (valid css)                                                                                       |
| `disabled`      | Boolean | false           |                   |            |                                                                                                                   |

### Example

```html
<hy-section :showDividers="true">
    <hy-list-item color="pink" icon="icon-printer">
        <p>Hello World</p>
    </hy-list-item>

    <hy-list-item color="red" :clickable="true">
        <p>Hello World</p>
    </hy-list-item>

    <hy-list-item color="red">
        <template #content>
            <p>Hello World</p>
        </template>

        <template #icon> <svg>...</svg> or <i class="icon-..."></i> </template>
    </hy-list-item>
</hy-section>
```
 
# HyLoader Component 

# HyLoader

This is a custom loading indicator.  
Use `v-if="booleanVariable"` to show the indicator or not.  
This is just a spinning wheel, you must position the indicator by yourself.

### Targeting class

`hy-loader`

### Options

| Name     | Type   | Default | Available options | Required | Extra info                                        |
| -------- | ------ | ------- | ----------------- | -------- | ------------------------------------------------- |
| `width`  | Number | 50      |                   |          | In css px                                         |
| `height` | Number | 50      |                   |          | In css px                                         |
| `line`   | Number | 4       |                   |          | In css px. This is how thick the line is rendered |

### Example

```html
<hy-loader v-if="isLoading" :width="25" :height="25" :line="3" />
```
 
# HyMain Component 

A container that resizes based on your screen size. At a certain screen size it locks to a width of 1400px (or whatever you specify it to).

### Targeting class

`hy-main`

### Slot

Pass the elements you want to position within the Main view via the slot.

### Options

| Name       | Type   | Default  | Available options | Required | Extra info                                                                                                           |
| ---------- | ------ | -------- | ----------------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `maxWidth` | String | "1400px" |                   |          | Desired css max-width value                                                                                          |
| `resizeTo` | Number | 95       |                   |          | Will be a max-width in **percent** that the container will resize to if it must be smaller than the given `maxWidth` |

### Example

```html
<hy-main maxWidth="800px" :resizeTo="90">
    <hy-flex-container>
        <input />
        <button>Hello</button>
        <hy-checkbox />
    </hy-flex-container>
</hy-main>
```
 
# HyModal Component 

A modal element. Adapts to mobile and desktop devices. Respects the bottom safe-area.

### Targeting class

`hy-modal`

### v-model

Syncs the current visibility state with your parent vue instance. View the [Info about v-model](#how-v-model-works) section for more details.
If `modelValue` is set to `true`, the modal will show. So you can open the modal programmatically while letting the user close the modal with the build in close button.

### Slot

| Name      | Is also the default slot | Required | Extra info                                                                         |
| --------- | ------------------------ | -------- | ---------------------------------------------------------------------------------- |
| `content` | Yes                      | Required | The main content of the modal                                                      |
| `header`  | No                       |          | Place elements next to the close button. Use `size="md"` to match the close button |
| `footer`  | No                       |          | Place elements in the sticky footer                                                |

### Options

| Name                      | Type    | Default | Available options | Required   | Extra info                                                                                                                                            |
| ------------------------- | ------- | ------- | ----------------- | ---------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |
| `modelValue`              | Boolean |         |                   | Required   | Two-way binding about whether the modal is open or not                                                                                                |
| `headline`                | String  | null    |                   |            |                                                                                                                                                       |
| `description`             | String  | null    |                   |            |                                                                                                                                                       |
| `zIndex`                  | Number  | 200     |                   |            | Z-Index of modal element                                                                                                                              |
| `background`              | String  | null    |                   |            | Background of modal. Defaults to white / black depending on the color scheme                                                                          |
| `showScrollbars`          | Boolean | false   |                   |            |                                                                                                                                                       |
| `doBSL`                   | Boolean | true    |                   |            | Whether body scrolling should be disabled or not. If `doBSL = true`, then the user will only be able to scroll within the modal, not the entire body. |
| `dismissible`             | Boolean | true    |                   |            | If set to `false`, the user cannot dismiss the modal. This option hides the close button and disabling the 'click-outside-way' of closing the modal.  |
| `swipeToCloseEnabled`     | Boolean | true    |                   |            | If set to `false`, swipe to close on touch devices will be disabled and the close button will be shown on every device.                               |
| `forceFullHeightOnMobile` | Boolean | false   |                   |            | Forces full height if the modal is displayed on mobile devices. If `false`, the modal will only be as high as necessary                               |
| `doBlurBg`                | Boolean | false   |                   |            | Be advised: we noticed the modal getting stuck on iOS when setting this option to true.                                                               |

### Example

In your vue template:

```html
<hy-modal v-model="modal.isOpen" headline="My test modal">
    <p>{{ myText }}</p>

    <hy-button v-on:click="modal.isOpen = false"> Close modal </hy-button>
</hy-modal>
```

Or with a header and footer:

```html
<hy-modal v-model="modal.isOpen" headline="My test modal">
    <template #header>
        <hy-button variant="ghost-bg-red" size="md">Hello World Header</hy-button>
    </template>

    <template #content>
        <p>Lorem Ipsum</p>
    </template>

    <template #footer>
        <hy-button variant="ghost-bg-red" size="md">Hello World Footer</hy-button>
    </template>
</hy-modal>
```
 
# HyNavigationContainer Component 

HyperUI comes with a basic navigation system consisting of a sidebar and a tabbar UI component.

If you just provide a Sidebar and Tabbar component, then the container will display the sidebar on desktop devices and the tabbar on mobile devices. It uses the `switchToMobileAt` prop to decide which to use when.

Optionally, you may use the `sidebarVisibleDesktop` v-model (which defaults to true) to hide/show the sidebar on desktop devices.

If you use the `sidebarVisibleMobile` v-model (which defaults to false), you can also hide/show the sidebar on mobile devices. The sidebar will then render over the main content and clicking outside of it will close it.
Using this does not void your option to use the tabbar component on mobile. You could, if you wish so, use the tabbar and the sidebar in conjunction on mobile.

### Targeting class

`hy-navigation-container`

### Slot

| Name      | Is also the default slot | Required | Extra info                                                                |
| --------- | ------------------------ | -------- | ------------------------------------------------------------------------- |
| `tabbar`  | No                       |          | Tabbar is for mobile phones                                               |
| `sidebar` | No                       |          | Displayed on larger screens or if `sidebarVisibleMobile` is set to `true` |
| `content` | No                       | Required | Here, you may place something like the `<router-view />`                  |

### Options

| Name                    | Type    | Default | Available options | Required | Extra info                                                                                                                    |
| ----------------------- | ------- | ------- | ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------- |
| `sidebarVisibleDesktop` | Boolean | true    |                   |          | Toggles whether the sidebar is visible or retracted on desktop                                                                |
| `sidebarVisibleMobile`  | Boolean | true    |                   |          | Toggles whether the sidebar is visible or retracted on mobile devices                                                         |
| `switchToMobileAt`      | Number  | 850     |                   |          | In CSS `px`. If the screen is smaller than this number, then this component will hide the sidebar and show the tabbar.        |
| `gap`                   | String  | "0px"   |                   |          | Gap between sidebar and content when in desktop mode                                                                          |
| `doBSL`                 | Boolean | true    |                   |          | If enabled, body scrolling will be locked when opening the sidebar on mobile                                                  |
| `sidebarPosition`       | String  | "left"  | left, right       |          |                                                                                                                               |
| `sidebarDimensions`     | Object  | null    |                   |          | This is just a backup for if the automatic sidebar-width-detection does not work, provide a `{width: 'any css value'}` value. |

### Example

```html
<hy-navigation-container v-model:sidebarVisibleDesktop="sidebarVisibleDesktop" v-model:sidebarVisibleMobile="sidebarVisibleMobile">
    <template #sidebar>
        <hy-navigation-sidebar>
            <!-- Of course, one can put in this slot whatever they want: -->
            <h3>Hello World</h3>

            <!-- It's recommended to use the pre-styled navigation buttons for presenting the different routing destinations -->
            <button @click="$router.push('/home')" class="hy-navigation-option" :class="{ selected: