Adding Semantic UI to Phoenix v1.4 with Webpack

I am a newbie to Phoenix, Elixir, and Semantic.

I’m having an issue finding an example of how to add Semantic UI to Phoenix in the newest version 1.4.3 where it seems the file structure has changed a little and Webpack is now used instead of Brunch for asset generation. Tutorials on how to integrate Semantic with Phoenix date before the new version release and I’m unsure of where to put certain folders/files.

I’ve looked at these sites:

I’ve been testing out installing Semantic into my project and I get a semantic folder, semantic.json file, and my package-lock.json and package.json files get updated.

I moved the semantic folder which contains folders src and tasks into my assets/static folder and have updated my endpoint.ex file to contain the following:

  plug Plug.Static,
    at: "/",
    from: :app,
    gzip: false,
    only: ~w(css fonts images js favicon.ico robots.txt semantic)

Unsure of the next steps.

Hi, there are a lot of ways to integrate a third-party library into Phoenix, but you don’t need to modify endpoint.ex or move the files of Semantic UI from node_modules to assets.

The easiest way is adding Semantic UI to app.js:

import 'semantic-ui';

or just add a reference to Semantic UI inside the entry object of Webpack’s configuration.

entry: {
  semantic: ['semantic-ui'],
  // ...
}

another option is to use Semantic UI’s CDN, you just need to add the CDN to app.html.eex.

<link rel="stylesheet" type="text/css" href="semantic/dist/semantic.min.css">
<script
  src="https://code.jquery.com/jquery-3.1.1.min.js"
  integrity="sha256-hVVnYaiADRTO2PzUGmuLJr8BLUSjGIZsDYGmIJLv2b8="
  crossorigin="anonymous"></script>
<script src="semantic/dist/semantic.min.js"></script>

I’ve never used Semantic UI, but the process is pretty much the same for every dependency you want to include. In case that Webpack can’t find the dependency specified, you may want to use a relative path to the dist folder.

I use semantic-ui-less - if you don’t mind using less as a preprocessor, I can chuck up a simple repo tomorrow morning when I get in the office.

Essentially, you create a theme folder for your site, and tell webpack how to get to that config file when it is resolving the semantic files:

resolve: {
    extensions: [".js", ".vue", ".json", ".less", ".css"],
    alias: {
      "../../theme.config$": path.join(
        __dirname,
        "less/vendor/semantic-ui/theme.config"
      ),
    }
  },

Doing it that way makes it easy to override the default stylings etc and only load the styles for things that I use

Then for the javascript, I import a semantic-ui.js file that looks like:

// Core
import 'semantic-ui-less/definitions/modules/transition';

// Individual
import 'semantic-ui-less/definitions/modules/sidebar';
import 'semantic-ui-less/definitions/modules/checkbox';
import 'semantic-ui-less/definitions/modules/dropdown';
import 'semantic-ui-less/definitions/modules/modal';
import 'semantic-ui-less/definitions/modules/popup';
import 'semantic-ui-less/definitions/modules/tab';

Again so I only load what I use

Here is a repo with semantic-ui working on it. It uses the less version, so you can include what you want and tweak as needed.

Pretty much:

  1. mix phx.new --no-ecto semantic_test
  2. cd semantic_test/assets
  3. npm install --save-dev semantic-ui-less jquery less less-loader file-loader
  4. Apply the changes as per the commit log

CSS

For example, you could add a file in assets/vendor/semantic-ui/theme/globals/site.overrides with the contents:

@text-colors: blue, green, orange, pink, purple, red, teal, yellow, black, grey, white, violet;
.text {
    .-(@i: length(@text-colors)) when (@i > 0) {
        @c: extract(@text-colors, @i);
        &.@{c} { color: @@c !important }
        .-((@i - 1));
    }.-;
}

That will let you use .text.blue as a class to style things.

Or if you wanted to change the font, create a file in assets/vendor/semantic-ui/theme/globals/site.variables with the contents:

/*-------------------
       Fonts
--------------------*/

@importGoogleFonts: false;
@fontName: 'Verdana';

You can pretty much follow https://github.com/Semantic-Org/Semantic-UI-LESS/tree/master/themes/default for which files you can create.

JS
I just update assets/js/vendor/semanmtic-ui.js with the things that I want to activate, then use them in the main app.js

HTH

2 Likes