Hypen Language
Hypen is a UI language developed specifically for cross-platform application development. It enables developers to write one codebase that will run everywhere, instead of writing a codebase for each platform.
The language itself is simple, intuitive and focused mostly on UI development. This allows us to be a “plug and play” framework that you can integrate with your existing solutions, instead of having to change stacks.
The framework renders the language into native components on each platform, thus retaining the speed of native apps and allowing the developer to plug-in custom components or override existing ones.
Syntax
The syntax is quite simple - components are declared in a tree-like structure, defining the look of your UI. To style a component, one can apply applicators, small functions that modify the component's look.
Components are by definition stateless, and they can only receive arguments. These arguments can be static values or reactive references to the app's state. By default, components are reactive, meaning that when their arguments or state change, they will re-render automatically. Since we sometimes need managed state, we can use Modules - modules are components that have their own state and can be reused across the app. While hypen is a UI language, it supports invoking code from the app's logic layer, by using Actions. Actions are functions that can be change the app's state, perform network request, access the device's hardware, etc. This keeps the UI layer clean and focused on UI, while the logic layer is focused on the app's logic, making it easier to maintain and test.
Let's take a peek at a simple Hypen application with a component and two routes - don't worry, it's going to be quite simple:
Syntax example
Our app will have a component called UserDetails and two routes - one for the home page and one for the user details page.
component UserDetails {
Column {
Card {
Text("Username: ${@state.username}")
Text("Email: ${@state.email}")
}
Button {
Text("Logout")
}.click(@logout)
}
}This defines a component called UserDetails that doesn't accept any arguments and displays a Card containing two Text components and a Button. The text components depend on the app's state, and the button invokes the logout action when clicked.
Let's define the app and the routes now:
// We import the UserDetails component
require(what: UserDetails, from:“./UserDetails”) // Importing a module
//Root of the application
application App {
//Initial route to be displayed
Route(“/”) {
Column {
Image(“https://random.image/nft.jpg")
Text(“Welcome!”)
Center {
Button {
Text(“Change text”)
.textColor(white)
}
.backgroundColor(blue)
.click {
push(“/userDetails”)
}
}
}
}
// User details route
Route(id: “/userDetails”) {
UserDetails()
}
}Components
Basic components
All Hypen apps have access to a set of basic components from which they can arrange custom components. Consider these basic components the building blocks of your UI.
You can combine these basic components to build bigger components which you can later on reuse in the rest of your app by using requires to declare dependencies and ChildSlots to define stand-ins in generic components.
To start you off, here are some of the basic components
Text
A static text component used to display text from the arguments.
Usage
Text("My text value")
Text(@state.textValue)
Arguments
Text - Value
Specific modifiers
Text("myText")
.color(color: red | #FF0000 | @state.color)
.fontSize(size: 24sp)
.fontStyle(style: normal | italic)
.fontWeight(weight: 800 | bold | medium | normal)
.lineHeight(height: 24sp)
.textAlign(align: left | right | center | justify | start | end)Image
Displays an image from either assets or the network.
Usage
Image("https://picsum.photos/200/200")Image(@assets.image)
Arguments
Image - Value
Specific modifiers
Image("https://picsum.photos/200/200")Container
Child components within a Container are laid out in the order they are declared on the z-axis, allowing for an overlaying arrangement of components within a bounded context. The Container acts as a parent, providing a scope and structure for its children, which can be any number of UI elements such as Text, Image, or even other Containers.
Container {
ChildComponents()
}Column
A Column arranges its child components vertically. Each child component is placed below the previous, creating a single vertical flow. This is useful for creating layouts that require a vertical arrangement of elements, such as forms or lists.
Column {
ChildComponents()
}Row
A Row arranges its child components horizontally. Each child component is placed next to the previous, creating a single horizontal flow. This is ideal for creating layouts that require elements to be aligned side-by-side, such as a set of buttons or icons.
Row {
ChildComponents()
}Center
The Center component centers its child components within its bounds. This is useful for placing a single component or a group of components in the middle of the screen or within another container, ensuring that they are visually centered.
Center {
ChildComponents()
}Spacer
A Spacer creates an empty space between components, useful for adding padding or separating elements visually without the need for additional styling or containers.
Spacer
//usage
Column {
Component()
Spacer()
Component()
}Divider
A Divider is a thin line used to separate content visually. It can be used within lists, between paragraphs, or anywhere you need a clear visual separation.
Cards
Cards are containers with a shadow, rounded corners, and padding. They are used to display information in a more visually appealing way, often containing a combination of Text, Image, and Button components.
List
A List displays a collection of items in a vertical arrangement. It can be static or dynamically generated from a data source. Each item in the list can be a combination of various components.
Navigation
Tabbed Navigation allows you to organize content across different tabs. Each tab can contain different components or screens, enabling users to easily switch between them.
Tabbed navigation
TabbedNavigation {
Tab(id: "home") {
// Home tab content
}
Tab(id: "settings") {
// Settings tab content
}
}Drawer
Drawer { MenuItem(id: "/home", title: "Home") MenuItem(id: "/settings", title: "Settings") }
Inputs
Button
A Button is a clickable element used to perform an action. It can contain text, an icon, or both.
Button {
Text("Click me")
}
.action(@event)Checkbox
A Checkbox allows users to select one or more options from a set.
Checkbox(id: "option1", label: "Option 1", checked: true).onChecked(actionName)
Checkbox(id: "option2", label: "Option 2", checked: false).onChecked(actionName)Radio
A Radio button allows users to select one option from a set, ensuring that no more than one option can be selected at a time.
RadioGroup {
RadioButton(id: "option1", label: "Option 1")
RadioButton(id: "option2", label: "Option 2")
}Toggle
A Toggle switch allows users to switch between two states or options. It is often used for settings that can be turned on or off.
Toggle(id: "toggleOption", label: "Enable Feature")Input
An Input field allows users to enter text. It can be used for various types of data input, such as names, email addresses, and passwords.
Input(id: "email", placeholder: "Enter your email")Dropdown
A Select dropdown allows users to choose one option from a list. It's useful for saving space on the screen while offering multiple selection options.
Dropdown(id: "countrySelect") {
Option("us", "United States")
Option("ca", "Canada")
Option("uk", "United Kingdom")
}Datepicker
A Datepicker allows users to select a date from a calendar view. It simplifies the process of entering dates and ensures the format is consistent.
Datepicker(id: "startDate", label: "Start Date")Modals
Modal
A Modal is a dialog box/popup window that is displayed on top of the current page. It can be used to capture user input, display information, or require user interaction before continuing.
Modal(id: "signupModal") {
// Modal content here
}Popover
A Popover is a small, contextual overlay that can display additional information or provide interaction options. It's similar to a tooltip but can contain richer content, including buttons, links, and custom HTML.
Popover(anchor: "@buttonId") {
Text("More info here")
}Extra
Spinner
A Spinner is an animated indeterminate loading indicator that shows that a process is ongoing. It's commonly used to inform users that the application is loading or processing data.
Spinner()ProgressBar
A ProgressBar is a horizontal loading indicator that shows the current progress in a process. It's commonly used to inform users that the application is loading or processing data.
Spinner()