Web development without ready-to-use UI libraries wouldn't be as fast and efficient. You may argue that you're an HTML/CSS ninja, and I believe you because I am too. Nonetheless, it's still cool to use predefined stylish components, and that's why we are looking for some beautiful UI libraries. My name is Mikhail Isaev, and I'm the author of framework. Today, I'm going to tell you about the framework and how to use it with SwifWeb. Let's begin! SwifWeb MaterializeCSS What is it? MaterializeCSS is a modern responsive front-end framework based on which was created by Google to combine the classic principles of successful design along with innovation and technology. I enjoyed writing a wrapper for this framework because it is very easy to use! open-source Material Design How to install? If you are new to SwifWeb then you have to create new project using the Webber CLI tool. In the project open Package.swift and edit the section to make it look like this: dependencies dependencies: [ // the rest of the other dependencies incuding swifweb/web .package(url: "https://github.com/swifweb/materialize", from: "1.0.0"), ] Next edit to make it look like this: executableTarget .executableTarget(name: "App", dependencies: [ .product(name: "Web", package: "web"), .product(name: "Materialize", package: "materialize") ]), Then open and configure in method like this: App.swift Materialize didFinishLaunching Lifecycle.didFinishLaunching { Materialize.configure() } You will face missing styles if you forget to configure it 🙃 Custom Theme: If you generated a custom Materialize style from SCSS then configure it this way: Lifecycle.didFinishLaunching { app in Materialize.configure(avoidStyles: true) app.addStylesheet("/css/custom-materialize.min.css") } Add your custom style into /Sources/App/css/custom-materialize.min.css open and declare resources in as follows: Package.swift executableTarget .executableTarget(name: "App", dependencies: [ .product(name: "Web", package: "web"), .product(name: "Materialize", package: "materialize") ], resources: [ .copy("css/custom-materialize.min.css"), .copy("css") ]), Now you are ready to start building the UI! Components I have beautifully wrapped all the components into Swift, but the article would be too long if I were to describe all of them. Let me examine a few of them here, and you can refer to the for the rest. readme on GitHub Buttons You can make any element as material button just by calling method. .materialButton(...) element can be used for links, and or other elements can be used with handler. A Div onClick Div("My Button") .materialButton(type: .raised) .onClick {} A("My Link") .href("https://google.com") .materialButton(type: .raised) Both elements will look same, the only difference is that is a link and will act like a link. A Method have few options: .materialButton can be type raised, floating, floatingHalfWay, flat can be size small, large can be or custom, by default waves light, red, yellow, orange, purple, green, teal light is just a flag to mark button disabled, pass @State value here to change it on the fly disabled Also you can add a material icon to it simply by calling .addMaterialIcon(...) .addMaterialIcon("announcement") // or optionally .addMaterialIcon("announcement".size(.tiny).side(.right)) Find more about the material icon below. Floating Action Button It is a fixed floating action button with multiple actions. Read more about it . in the official docs FloatingActionButton(icon: "add", color: .pink) .item(icon: "public", color: .red) .item(icon: "adb", color: .purple) .item(icon: "announcement", color: .blue) { Toast.show("Announcement!") } Optional arguments can be and , it is by default size large small large can be or custom, by default waves light, red, yellow, orange, purple, green, teal light can be , it is by default direction top, right, bottom, left top can be it is by default mode hover, click, toolbar hover Control it programmatically: lazy var fab = FloatingActionButton(...) fab.open() // to show the menu/toolbar fab.close() // to show the menu/toolbar fab.isOpen // the check if it is open Icons You can add an icon anywhere by initializing the object. MaterialIcon This object accepts icon as the initializer argument. List of the icon types is available . type here MaterialIcon("announcement") You can change icon type on the fly later by calling method on it. .type(...) Optional methods accepts .size(...) tiny, small, medium, large accepts .side(...) left, right All the methods can accept reactive @State value, so you can change the icon and its properties on the fly. Colors All colors that are listed are available including their modifiers. in the official documentation Text Color Span("Hello").textColor(.red) // just red color Span("Hello").textColor(.red.lighten3) // red color with lighten-3 modifier Span("Hello").textColor(.red.darken4) // red color with darken-4 modifier Background Color Div().materialBackground(.red) // just red color Div().textColor(.red.lighten3) // red color with lighten-3 modifier Div().textColor(.red.darken4) // red color with darken-4 modifier // or Div().red() Div().red(.lighten3) Div().red(.darken4) Grid The main thing in grid is which has its width and optional modifiers. Column offest, push, pull Container { Row { Column(.small(.one)) { "1" } // <div class="col s1">1</div> Column(.small(.one)) { "2" } // <div class="col s1">2</div> Column(.small(.one)) { "3" } // <div class="col s1">3</div> Column(.small(.one)) { "4" } // <div class="col s1">4</div> Column(.small(.one)) { "5" } // <div class="col s1">5</div> Column(.small(.one)) { "6" } // <div class="col s1">6</div> Column(.small(.one)) { "7" } // <div class="col s1">7</div> Column(.small(.one)) { "8" } // <div class="col s1">8</div> Column(.small(.one)) { "9" } // <div class="col s1">9</div> Column(.small(.one)) { "10" } // <div class="col s1">10</div> Column(.small(.one)) { "11" } // <div class="col s1">11</div> Column(.small(.one)) { "12" } // <div class="col s1">12</div> } Divider() Row { Column(.small(.twelve)) { "screen-wide" } Column(.small(.six)) { "one-half" } Column(.small(.six)) { "one-half" } } Divider() Row { Column(.small(.twelve)) { "12-columns" } Column(.small(.six, offset: .six)) { "6-columns at the right" } } Divider() Row { Column(.small(.seven, push: .five)) { "7-columns pushed to the right" } Column(.small(.five, pull: .seven)) { "5-columns pulled to the left" } } } The examples above are 1:1 like in the official documentation, so you can just compare. You can set more than one size class to a Column: Column(.extraLarge(.twelve), .large(.ten), .medium(.eight), .small(.six)) Alignment Vertical Align VAlignWrapper { H5("This should be vertically aligned") } Text Align H5("This should be left aligned").leftAlign() H5("This should be right aligned").rightAlign() H5("This should be center aligned").centerAlign() Quick Floats Div().floatLeft() // Quickly float things to left Div().floatRight() // Quickly float things to right Div().floatCenter() // Quickly float things to center Hiding/Showing Content Div().hideOnSmallOnly() // Hidden for Mobile Only Div().hideOnMedOnly() // Hidden for Tablet Only Div().hideOnMedAndDown() // Hidden for Tablet and Below Div().hideOnMedAndUp() // Hidden for Tablet and Above Div().hideOnLargeOnly() // Hidden for Desktop Only Div().showOnSmall() // Show for Mobile Only Div().showOnMedium() // Show for Tablet Only Div().showOnLarge() // Show for Desktop Only Div().showOnMediumAndUp() // Show for Tablet and Above Div().showOnMediumAndDown() // Show for Tablet and Below Div().pinned() // Pins element Formatting Truncation H4("This is an extremely long title").truncate() // also with @State Hover This feature adds an animation for box shadow on hover. Card().hoverable() // also with @State Browser Defaults You can revert element styles to the original state. Ul().browserDefault() Images Responsive Images Img().src("cool_pic.jpg").responsive() // resizes responsively to page width Circular images Img().src("images/yuna.jpg").circle() // square image that appears circular Videos Responsive Embeds Div { IFrame(...) }.videoContainer() Responsive Videos Video { Source().src("movie.mp4").type("video/mp4") }.responsive() Navbar Navbar { A("Logo") .floatLeft() // align left .floatRight() // align right .floatCenter() // align center } .deepPurple(.lighten4) // background .left() // left aligned links .right() // right aligned links .item("Sass", href: "/sass") .item("Components", href: "/badges") .item("JavaScript", active: true, href: "/collapsible") // as active // dropdown menu .dropdownItem("More", background: .white, hover: false) { DropdownItem("Dropdown 1", color: .red) { Toast.show("Hi") } DropdownItem("Dropdown 2", href: "") } Cards Card("Card Title") .blueGrey(.darken1) .textColor(.white) .message("""I am a very simple card. I am good at containing small bits of information. I am convenient because I require little markup to use effectively. """) .action("THIS IS A BUTTON") {} .action("THIS IS A LINK", href: "#") Preloader Circular PreloaderCircular(colors: .blue, .red, .green, .yellow).active() Indeterminate PreloaderLinearIndeterminate() Determinate @State var value: Double = 20 // change it to update the progress PreloaderLinearDeterminate($value) Pagination Pagination() .back(disabled: true, icon: "chevron_left") {} .item(1, href: "#1") .item(2, href: "#2") .item(3) { Toast.show("Going to 3!") } .forward() { Toast.show("Going forward!", rounded: true) } That’s It All right, I described about ~20% of the framework. If you are familiar with Materialize CSS you may notice that its representation is much easier to use! Swift Wanna learn more? Stay tuned for the upcoming articles! Don’t hesitate to ask any questions and feel free to contribute! in our Discord