@jaaahn/hyper-ui v3.2.6
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.
Content
- Attention Breaking Changes
- Install and import
- Component Documentation
- CSS Documentation
- Tips & Tricks
- Changelogs
Attention Breaking Changes
Upgrading to Version 3.0.0:
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 | --> | --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:
- 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 import
1. Installing the library
From a CND
<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
2. Importing the library
// 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: "normal",
};
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.
3. 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 above). 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 | Possible values | Extra info |
---|---|---|---|---|
theme | String | "system" | "system" , "light" or "dark" | system will choose light- or darkmode depending on the users system preferences |
size | String | "normal" | "normal" , "light" or "thin" | Only on supported elements |
4. Preparing your HTML file
If you are planning on using the included HyHeader component, please add these theme-color meta tags to your html head:
<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 are NOT planning on using the Header, then add the following to your html head:
<meta name="theme-color" content="#eeeef2" media="(prefers-color-scheme: light)" />
<meta name="theme-color" content="#000" media="(prefers-color-scheme: dark)" />
Component Documentation
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
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 | Extra info |
---|---|---|---|
type | String | "secondary" | See down below |
size | String | normal | Size Option Docs |
loading | Boolean | false | For spinner: leave progress = null. For progress bar: 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 instead. |
progress | Number | null | Range between 0-1. Values not in this range will be caped |
progressWidth | String | min(70%, 150px) | Specify a width (valid css) |
Different styles or types
Option name | Result |
---|---|
primary | Primary action button style featuring the blue accent color |
secondary | Secondary action button, matches the background color |
transparent | Button with only text. Has hover and click effect. |
transparent-bg | Button with text and a slightly visible gray background. Has hover and click effect. |
light-blue | Compare to above |
light-bg-blue | Compare to above |
light-red | Compare to above |
light-bg-red | Compare to above |
light-orange | Compare to above |
light-bg-orange | Compare to above |
light-green | Compare to above |
light-bg-green | Compare to above |
Example
<!-- Loading with spinner -->
<hy-button @click="method('hello')" :disabled="false" :loading="isLoading" type="primary">
Click me
</hy-button>
<!-- Loading with progress -->
<hy-button @click="method('hello')" :disabled="false" :loading="isLoading" :progress="loadingProgress" type="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).
The specific styles (controlled by the type
option) are applied to the <button>
element by a class, which matches the type's name.
So, if you want to change the background-color of every transparent button, you could use something like:
.hy-button :deep(button.transparent) {
background-color: yellow !important;
}
/* :deep() is explained in the "Re-Style Components" section */
HyInput
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 section for more details.
Slot
This component can hold up to 2 icons. One on the left and one on the right.
By default, passing an icon into the slot will position it left to the text. If you want the icon to appear at the right of the input component, then use a named slot with the name right
. If you want to display two icons simultaneously, then use two named slots using the names left
and right
.
This feature was build to work with icon-fonts using the <i>
tag. Other systems may also work, but may require more tweaking. Your icons should have a width of around 20px
.
These icons cannot be clicked on.
Options
Name | Type | Default | 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" |
size | String | normal | Size Option Docs |
placeholder | String | "" | |
loading | Boolean | false | For spinner: leave progress = null. For progress bar: 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 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(70%, 150px) | Specify a width (valid css) |
invalid | Boolean | false | Highlights input if true |
invalidText | String | null | Displays a message (if invalid = true) |
NOTE: Inheriting Props
The option autocomplete
got removed in favor of vue's $attrs
.
All HTML props except id
, class
and vue props listed above, will be inherited to the underlying <input>
element.
Vue will also automatically inherit all props, including id
and class
, to the <div>
wrapper that this component uses.
Example
<hy-input v-model="username" :disabled="false" :loading="isLoading" type="text" placeholder="Your username"></hy-input>
With an Icon on the left side
<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
<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
<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
<hy-input v-model="username" :disabled="false" :loading="isLoading" :progress="loadingProgress" type="text" placeholder="Your username"></hy-input>
HyTextArea
Basic <textarea>
element with the option of being disabled.
Use v-model
to create a two-way binding.
This Component was not build for being used within a FlexContainer
.
Targeting class
hy-text-area
v-model
Syncs the current input value with your parent vue instance. View the Info about v-model section for more details.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | String | - | Required. Two-way binding for the input's value |
placeholder | String | "" | |
disabled | Boolean | false | |
required | Boolean | false | Equal to HTML's required attribute. |
resize | String | vertical | Equal to CSS resize rule. Correct values are none , both , vertical & horizontal |
size | String | normal | Size Option Docs |
NOTE: Inheriting Props
All HTML props except id
, class
and vue props listed above, will be inherited to the underlying <textarea>
element.
Vue will also automatically inherit all props, including id
and class
, to the <div>
wrapper that this component uses.
Example
<hy-text-area v-model="essay" :disabled="false" placeholder="Your essay goes here" />
HySelect
A HTML select
element with custom styling and an icon.
Use v-model
to create a two-way binding.
Targeting class
hy-select
v-model
Syncs the selected option with your parent vue instance. View the Info about v-model section for more details. This allows you to programmatically set the value while still allowing the user to select the option he wants.
Slot
Pass the <option>
elements as you would with regular HTML.
If you want to display an icon on the left side of the component, then you need to use named slots:
One named slot for the options
and one for the icon
.
Ref example for more detail.
This feature was build to work with icon-fonts using the <i>
tag. Other systems may also work, but may require more tweaking. Your icons should have a width of around 20px
.
These icons cannot be clicked on.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | String | - | Required. Two-way binding about the selected option |
loading | Boolean | false | For spinner: leave progress = null. For progress bar: 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 instead. |
size | String | normal | Size Option Docs |
progress | Number | null | Range between 0-1. Values not in this range will be caped |
progressWidth | String | min(70%, 150px) | Specify a width (valid css) |
Example
<hy-select v-model="variable" :disabled="false" :loading="isLoading">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</hy-select>
With an icon:
<hy-select v-model="variable" :disabled="false" :loading="isLoading">
<template #options>
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</template>
<template #icon>
<i class="icon-sort-descending"></i>
</template>
</hy-select>
With progress bar
<hy-select v-model="variable" :disabled="false" :loading="isLoading" :progress="loadingProgress">
<option value="option1">Option 1</option>
<option value="option2">Option 2</option>
</hy-select>
HySelectDropdown
Similar to a hy-select
but comes with its own menu UI and search functionality. Utilises hy-dropdown
under the hood.
Slot
Specify options as follows inside the default slot
or options
named slot:<p data-value="internalValue"> Display Value </p>
In addition, you may use the icon
named slot for displaying an icon, just like how the hy-select
component accepts icons.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | String | - | Required. Two-way binding about the selected option |
enableSearch | Boolean | true | Disable the search bar |
searchPlaceholder | String | "Search..." | |
searchNoResults | String | "No search results found..." |
Additionally, this menu supports these properties from HyDropdown:
border
, loading
, progress
, progressWidth
, disabled
, size
, maxHeight
, zIndex
, hideOnClickOutside
, dropdownDirection
Examples
<hy-select-dropdown v-model="variable">
<p data-value="option1">Option 1</p>
<p data-value="option2">Option 2</p>
<p data-value="option3">Option 3</p>
<p data-value="option4">Option 4</p>
</hy-select-dropdown>
Or with an icon (syntax equal to hy-select)
<hy-select-dropdown v-model="variable">
<template #options>
<p data-value="option1">Option 1</p>
<p data-value="option2">Option 2</p>
<p data-value="option3">Option 3</p>
<p data-value="option4">Option 4</p>
</template>
<template #icon>
<i class="icon-sort-descending"></i>
</template>
</hy-select-dropdown>
HyCheckbox
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 section for more details.
Slot
Use the slot to pass text which will be displayed as a label.
Options
Name | Type | Default | 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 instead. |
type | String | left | left or right . Aligns either label and box left, or label on the left and box on the right |
Example
<hy-checkbox v-model="someBooleanVariable" :disabled="disabledVariable" type="right">
Click me
</hy-checkbox>
HyToggle
An iOS style toggle "checkbox". Sometimes this is also called a "switch".
This component is functionally identical to the <hy-checkbox>
component. Please refer to its documentation.
Example
<hy-toggle v-model="someBooleanVariable" :disabled="disabledVariable" type="right">
Toggle me
</hy-toggle>
HyRadioButton
Standard radio button. It can be disabled.
Use v-model
to create a two-way binding.
Targeting class
hy-radio-button
v-model
Syncs which radio button is selected with your parent vue instance. View the Info about v-model section for more details. This allows you to programmatically set the value while still allowing the user to select the option he wants.
Slot
Use the slot to pass text which will be displayed as a label.
Options
Name | Type | Default | Required | Extra info |
---|---|---|---|---|
modelValue | String | - | Required | Two-way binding about wether the radio is selected or not. |
value | String | - | Required | Value of your radio button. If the radio button is clicked, this will be written to your modelValue variable. Works similar to html's <option value="..."> -tag one uses within selects. |
name | String | - | - | Set the name attribute of the <input type="radio"> -tag used within the component. |
disabled | Boolean | false | - | |
type | String | left | - | Set to left or right . Aligns either label and box left, or label on the left and box on the right. |
extend | Boolean | true | - | Controls wether the element extends to 100% or stays at max-content . Not recommended, use .hy-extend-full instead. |
Example
<!-- These three components will form a radio group, where only one option can be selected at a time. -->
<hy-radio-button v-model="someVariable" value="option1" :disabled="disabledVariable"> Option 1 </hy-radio-button>
<hy-radio-button v-model="someVariable" value="option2" :disabled="disabledVariable"> Option 2 </hy-radio-button>
<hy-radio-button v-model="someVariable" value="option3" :disabled="disabledVariable" type="right"> Option 3 </hy-radio-button>
HyDropzone
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 | Required | Extra info |
---|---|---|---|---|
placeholder | String | "Drop file here or click to select a file" | - | |
readMode | String | "text" | - | How the file will be read. Choose between text , binaryString , dataURL or arrayBuffer . More info about what they do |
accept | String | * | - | Which files to accept. About this attribute and how its syntax works |
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:
<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:
<hy-dropzone ref="myDropzone" />
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.
<hy-dropzone readMode="text" accept="text/*,application/*,.md" @newValue="myVariable = $event" />
Or:
<hy-dropzone readMode="dataURL" accept="image/*" @newValue="my_method_for_handling_the_event" />
Or:
<hy-dropzone readMode="dataURL" accept="image/*" @newValue="my_method_for_handling_the_event($event)" />
HyTabbar
A tabbar with multiple tabs the user can switch between. Sometimes this is known as a segmented picker or a switch.
Use v-model
to create a two-way binding, much like the <Select>
works.
This component supports dynamically created options (e.g. if using a v-for
loop for generating options).
If there are too many options to fit them, the component will automatically allow the user to scroll through the options. For this to work, the component may not be wrapped in a display: flex
container or a hy-flex-container
!
Targeting class
hy-tabbar
v-model
Syncs the selected tab with your parent vue instance. View the Info about v-model section for more details.
Slot
Syntax: <p data-value="valueOfTab"> Bla bla bla </p>
.
See the example below for more info on how to use this element.
Why? Due to technical restrictions, you can't just simply use a <option value="">
element in the slot
. Instead, please use a <p>
with a custom data-attribute called data-value
, like data-value="tab1"
or data-value="optionA"
. You are going to run into issues if this attribute is not given on an option element.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | String | Required. Two-way binding about which tab is selected | |
disabled | Boolean | false | |
type | String | gray | Available options are gray and blue |
Example
<hy-tabbar v-model="variable" :disabled="disabledVariable">
<p data-value="tab1">Tab 1</p>
<p data-value="tab2">Tab 2</p>
<p data-value="tab3">Tab 3</p>
</hy-tabbar>
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 | Extra info |
---|---|---|---|
width | Number | 25 | In css px |
height | Number | 25 | In css px |
line | Number | 5 | In css px. This is how thick the line is rendered |
Example
<hy-loader v-if="isLoading" :width="25" :height="25" :line="3" />
HyProgressBar
This is a custom progress bar.
Targeting class
hy-progress-bar
Options
Name | Type | Default | Extra info |
---|---|---|---|
progress | Number | - | Required. Range between 0-1. Values not in this range will be caped |
width | String | "100%" | Specify a width (valid css) |
Example
<hy-progress-bar v-if="isLoading" :progress="loadingProgress" width="50%" />
HyFlexContainer
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 | Extra info |
---|---|---|---|
wrap | Boolean | true | Controls the css flex-wrap property, switches between wrap and no-wrap |
justify | String | space-between | Controls the css justify-content property |
verticalAlign | String | center | Controls the css align-items property |
direction | String | row | Controls the 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
<hy-flex-container>
<input />
<button>Hello</button>
<hy-checkbox />
</hy-flex-container>
HySection
This is a section, with (unlike the body) a white background. It should be used most of the time when working with content. A section includes a title and two description fields.
Targeting class
hy-section
Slot
Pass the elements you want to position within the Section via the slot.
v-model: Make it collapsable
If provided alongside a value for title
, the section becomes collapsable.
Omit this, if you don't want the section to be collapsable (default behaviour).
View the Info about v-model section for more details.
Options
Any title
, pre
or post
field left as null won't be rendered.
Name | Type | Default | Extra info |
---|---|---|---|
border | Boolean | false | |
divider | Boolean | false | A divider between each element will be added automatically if set to true |
title | String | null | |
pre | String | null | Description field over slot |
post | String | null | Description field under slot |
modelValue | Boolean | null | Collapse the section (only active, if a value for title is provided) |
Example
<hy-section :border="true" :divider="false">
<hy-flex-container>
<input />
<hy-button>Hello</hy-button>
<hy-checkbox />
</hy-flex-container>
</hy-section>
<hy-section title="My Section" pre="Description" v-model="testSectionCollapsed">
<hy-button>Hello</hy-button>
</hy-section>
HySubSection
Has a slightly darker background-color than a section. Intended for use with only one input / button (etc.) element but one can pass any element via the slot. A sub-section includes a title and two description fields.
Targeting class
hy-sub-section
Slot
Pass the element(s) you want to position within the Sub-Section via the slot.
v-model: Make it collapsable
If provided alongside a value for title
, the sub-section becomes collapsable.
Omit this, if you don't want the section to be collapsable (default behaviour).
View the Info about v-model section for more details.
Options
Any title
, pre
or post
field left as null won't be rendered.
Name | Type | Default | Extra info |
---|---|---|---|
title | String | null | |
pre | String | null | Description field over slot |
post | String | null | Description field under slot |
modelValue | Boolean | null | Collapse the sub-section (only active, if a value for title is provided) |
Example
<hy-sub-section title="Title" pre="First description" post="Second description">
<hy-input v-model="testInput" placeholder="Input field" />
</hy-sub-section>
<hy-sub-section title="Title" v-model="testSubSectionCollapsed">
<hy-input v-model="testInput" placeholder="Input field" />
</hy-sub-section>
Info about background color and padding
This component was designed to be used within a regular Section. That's why it has a slightly different color than normal sections. If you want them to appear with the same color as Sections, for example to use them without a wrapper section, then please add the following lines of css to your code:
.hy-sub-section {
background-color: var(--section-bg-color);
/* If you want them to have the same padding as regular sections */
padding: var(--section-padding);
}
HyTable
A table.
Targeting class
hy-table
Slot
Pass HTML table elements.
Options
Name | Type | Default | Extra info |
---|---|---|---|
border | Boolean | true |
Example
<hy-table :border="true">
<tr>
<th>Col 1</th>
<th>Col 2</th>
</tr>
<tr>
<td>Hello</td>
<td>World</td>
</tr>
</hy-table>
HyMain
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 | 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 |
usingHyHeader | Boolean | false | Must be set to true if using HyHeader |
Example
<hy-main maxWidth="800px" :resizeTo="90">
<hy-flex-container>
<input />
<button>Hello</button>
<hy-checkbox />
</hy-flex-container>
</hy-main>
HyNavigationContainer
HyperUI comes with a basic navigation system consisting of a sidebar and a tabbar UI component. This container can house both of them and automatically switch between them depending on screen size. It also helps aligning the main content next to the sidebar.
Targeting class
hy-navigation-container
Slot
This component has three slots, which is why we need to use named slots.
First, the tabbar for mobile phones and other rather small screens.
The name of the slot istabbar
.Second, the sidebar for desktop devices that can fit a sidebar next to the main content.
The name of the slot issidebar
.Third, the main content.
Here, one may place its<router-view>
.
The name of the slot iscontent
.
As these are named slots, they don't have to be in this order. Just make shure you don't forget one of them.
Options
Name | Type | Default | Required | Extra info |
---|---|---|---|---|
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. |
maxWidth | String | "1400px" | - | Similar to the maxWidth option on the HyMain component. This does apply to the container holding the sidebar and the content, not just the content. It's recommended to wrap your <router-view> in a HyMain component. |
Example
<hy-navigation-container>
<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: $route.name == 'Home' }">
<i class="icon-home"></i> <!-- Icon (currently only icon-fonts like fontawesome are officially supported) -->
<span>Home</span> <!-- Label -->
</button>
<button @click="$router.push('/settings')" class="hy-navigation-option" :class="{ selected: $route.name == 'Settings' }">
<i class="icon-settings"></i>
<span>Settings</span>
</button>
</hy-navigation-sidebar>
</template>
<template #tabbar>
<hy-navigation-tabbar>
<!-- These pre-styled navigation buttons are also in the tabbar available, but they change their style to better fit in the tabbar -->
<button @click="$router.push('/home')" class="hy-navigation-option" :class="{ selected: $route.name == 'Home' }">
<i class="icon-home"></i>
<span>Home</span>
</button>
<button @click="$router.push('/settings')" class="hy-navigation-option" :class="{ selected: $route.name == 'Settings' }">
<i class="icon-settings"></i>
<span>Settings</span>
</button>
</hy-navigation-tabbar>
</template>
<template #content>
<hy-main maxWidth="800px">
<!-- This example uses Vue Router, but essentially you can put anything in here -->
<router-view></router-view>
</hy-main>
</template>
</hy-navigation-container>
The <hy-navigation-sidebar>
and <hy-navigation-tabbar>
components are explained below.
HyNavigationSidebar
As part of the navigation system HyperUI offers, there is a Sidebar UI component. It should be placed within a HyNavigationContainer.
Targeting class
hy-navigation-sidebar
Slot
Place any content (e.g. a logo, company name and the available pages) that should be displayed within the sidebar here.
Within this slot, one may use the "hy-navigation-option"
class on a <button>
element to create a specially designed button that may represent a page that the user can visit. Apply the "selected"
class to it and it will be highlighted. Within, you can place a label next to an icon.
The following example will use vue router to create a navigation option, that represents the 'home' page of your app:
<button @click="$router.push('/home')" class="hy-navigation-option" :class="{ selected: $route.name == 'Home' }">
<!-- Icon (currently only icon-fonts like fontawesome are officially supported) -->
<i class="icon-home"></i>
<!-- Label -->
<span>Home</span>
</button>
Note that this syntax is the same within a <hy-navigation-tabbar>
component.
Enable scrolling in sidebar
Scrolling must be enabled if there is too much content within the sidebar and the content does overflow if a screen is too small. Be aware that this is only one possible solution and there might be better looking, but more complicated ways to enable scrolling.
.hy-navigation-sidebar :deep(#visual) {
overflow-y: scroll;
}
Options
Name | Type | Default | Required | Extra info |
---|---|---|---|---|
width | String | "300px" | - | |
height | String | "100vh" | - | |
inset | String | "15px" | - | Inset to the parent container. |
Typically, one does not need to change these properties.
Example
For example look at the HyNavigationContainer
's example section
HyNavigationTabbar
As part of the navigation system HyperUI offers, there is a Tabbar UI component. It should be placed within a HyNavigationContainer.
This component looks similar to the tabbar that iOS apps typically have.
Targeting class
hy-navigation-tabbar
Slot
Place the available navigation options that should be displayed within the tabbar here.
Within this slot, one may use the "hy-navigation-option"
class on a <button>
element to create a specially designed button that may represent a page that the user can visit. Apply the "selected"
class to it and it will be highlighted. Within, you can place a label below an icon.
The following example will use vue router to create a navigation option, that represents the 'home' page of your app:
<button @click="$router.push('/home')" class="hy-navigation-option" :class="{ selected: $route.name == 'Home' }">
<!-- Icon (currently only icon-fonts like fontawesome are officially supported) -->
<i class="icon-home"></i>
<!-- Label -->
<span>Home</span>
</button>
Note that this syntax is the same within a <hy-navigation-sidebar>
component.
Options
None.
Example
For example look at the HyNavigationContainer
's example section
HyDropdown
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.
Slot
Use the default slot
or content
named slot to provide the menu's content.
In addition, you may use the icon
named slot for displaying an icon, just like how the hy-select
component accepts icons.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | Boolean | - | Required. Controls whether or not the dropdown is open |
title | String | - | Required |
border | Boolean | false | |
loading | Boolean | false | For spinner: leave progress = null. For progress bar: 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(70%, 150px) | Specify a width (valid css) |
disabled | Boolean | false | |
size | String | normal | Size Option Docs |
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" or "top" |
Examples
<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)
<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>
HyModal
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 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
Pass the elements you want to appear within the modal in the slot. Inside, you can directly interact with your Vue instance as it would be normal template code.
Options
Name | Type | Default | 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 (-color) of modal. Defaults to white (or black) |
hideScrollbars | Boolean | true | |
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. |
disableDismiss | Boolean | false | If set to true , the user cannot dismiss the modal. This option hides the close button and disabling the 'click-outside-way' of closing the modal. |
disableSwipeToClose | Boolean | false | If set to true , 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. |
IMPORTANT
The modal component uses teleports to get the modal out of the regular component tree, as it would otherwise cause problems with position: fixed
.
BUT, in order for this to work, one must specify a target element, preferably outside of the vue instance (for example in index.html). This element should be a div with an #hy-modals-container
id. Do not style this element with css! You only need one element for all your modals in your Vue project!
See below for an example.
Example
In your vue template:
<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>
In index.html
:
(...)
<body>
<div id="app"></div>
<script type="module" src="/src/main.js"></script>
<div id="hy-modals-container"></div>
</body>
(...)
HyPopover
A popover container. Floats above the main content and stays attached to the target element with the help of Popper. Will disappear if the user clicks outside of it.
If you set hover
to true
, then you can use this component as a tooltip.
Attention
Popovers may require a lot of computing resources. We recommend not using too many of them, certainly not in dynamic scenarios (e.g. using v-for). For such applications, please use HyPopoverFree.
Targeting class
hy-popover
v-model
Syncs the current open state with your parent vue instance. View the Info about v-model section for more details.
If modelValue
is set to true
, the popover will show. So you can open the popover programmatically while giving the user the option to close the popover by clicking outside of it.
Even if you use the popover as a tooltip that simply shows when the user hovers over an element, you still need to use v-model!
Slot
This component has two slots, which is why we need to use named slots.
First, the target element This can be any element, such as a
<p>
tag or aHyButton
component.
The name of the slot iselement
Second, the popover content
popover
This is what will appear inside the popover.
The name of the slot ispopover
So, within the components slot, you should pass two <template #nameOfSlot>
tags. See the example below for more detail.
Options
Name | Type | Default | Extra info |
---|---|---|---|
modelValue | Boolean | Required. Controls whether the popover is shown or not | |
type | String | match | Color type of popover. Either match or contrast (= dark bg-color if lightmode is active) |
zIndex | Number | 10 | Z-Index of popover element |
hover | Boolean | false | If true , the popover will show if the user hovers over the target element |
hoverDelay | Number | 700 | In MS. Delay to wait before popover will show (only for hover). Aborts if user stops hovering over target element |
hideOnClickOutside | Boolean | true | If the user clicks outside, the popover will hide |
minWidth | String | 0 | Desired css min-width value, e.g. "400px" |
maxWidth | String | unset | Desired css max-width value, e.g. "600px" |
maxHeight | String | unset | Desired css max-height value, e.g. "100px" |
placement | String | bottom | See Popper options |
offsetY | Number | 15 | Y-Offset of popover |
offsetX | Number | 0 | X-Offset of popover |
Example
<hy-popover v-model="popover.isOpen" minWidth="400px">
<template #element>
<hy-button v-on:click="popover.isOpen = !popover.isOpen">Toggle popover</hy-button>
</template>
<template #popover>
<h4>Hello World</h4>
<hy-input v-model="testInput"/>
</template>
</hy-popover>
HyPopoverFree
A popover container. Floats above the main content and stays attached to the target element with the help of Popper. Will disappear if the user clicks outside of it.
Does NOT support hover
.
Difference to HyPopover
HyPopover was designed to be used "inline" with one element.
If you want to have one popover component and be able to attach it to different elements, then please use this component.
A popover may require a lot of computing resources. Use HyPopoverFree in dynamic situations (e.g. when using v-for): one HyPopoverFree that may attach to different elements depending on the situation.
Targeting class
hy-popover-free
v-model
Syncs the current open state with your parent vue instance. View the Info about v-model section for more details.
If modelValue
is set to true
,
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
2 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
3 months ago
2 months ago
3 months ago
3 months ago
3 months ago
3 months ago
4 months ago
4 months ago
4 months ago
3 months ago
3 months ago
3 months ago
8 months ago
7 months ago
7 months ago
7 months ago
7 months ago
5 months ago
5 months ago
5 months ago
5 months ago
6 months ago
6 months ago
6 months ago
6 months ago
6 months ago
5 months ago
9 months ago
9 months ago
10 months ago
10 months ago
10 months ago
11 months ago
11 months ago
11 months ago
11 months ago
12 months ago
12 months ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
1 year ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
2 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
3 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago