defmodule MoonWeb.Components.Started.ForDeveloper do @moduledoc false use MoonWeb, :stateless_component alias MoonWeb.Components.IndentedCodeSnippet alias MoonWeb.Components.CodeSnippet alias MoonWeb.Components.PageSection def render(assigns) do ~F"""

Moon Design System is a collection of reusable components set up and grouped according to simple and clear standards. Moon DS component collection is the single source of truth that can be used to build any number of applications.

Moon Design System can be used for new and existing Phoenix project that uses LiveView

Moon Surface components can be used from SLIM and EEX templates , but recommended format is Surface v0.9.x + Tailwind + Moon Surface Components

NB! You need to be using the latest version of Tailwind CSS for the system to work.

We do use adsf here. Add .tool-versions file to the root of your projects:

{tool_versions_code()}

And run asdf install

Create new Phoenix project (if needed) with LiveView enabled. Do not fetch dependencies.

mix archive install hex phx_new mix phx.new my_super_app --live cd my_super_app

Add Moon Library to mix.exs deps section:

{github_code()}

and fetch dependencies.

mix deps.get

Make sure your phoenix* dependenciesversions do not conflict with the same in moon library.

Add surface & esbuild configurations to the project's confix.exs:

{config_exs_code()}

Compile project and dependencies

mix compile

Initialize Surface as described here. Please make sure that surface compiler is configured.

mix surface.init

Add two Plug.Static plugs to your endpoint.ex

{plug_static_code()}

Import Moon Surface css and themes to project's assets/app.css:

{themes_import_code()}

Copy assets/package.json from deps/moon folder, or take two sections from there:

scripts:

{scripts_code()}

dependencies:

{dependencies_code()}

Create file assets/postcss.config.js

{postcss_config_code()}

Create file assets/tailwind.config.js

{tailwind_config_code()}

Edit your assets/js/app.js

{javascript_import_code()}

Add/modify assets-related aliases in your mix.exs file

{mix_exs_aliases()}

Setup assets

mix assets.setup

Add theme-related class (find it in imported theme CSS file) and direction related attribute to your root HTML component, e.g. body in lib/my_super_app_web/components/layouts/root.html.heex

{layout_modifications()}
mix phx.server """ end defp github_code() do """ # mix.exs ... {:moon, git: "git@github.com:coingaming/moon.git"} # or {:moon, git: "https://github.com/coingaming/moon.git"} """ end defp tool_versions_code() do """ # .tool-versions erlang 25.2 elixir 1.14.1 nodejs 14.17.6 """ end defp config_exs_code() do """ # config/config.exs ... import_config "../deps/moon/config/surface.exs" config :surface, :components, [ # put here your app configs for surface ] config :esbuild, version: "0.16.4", default: [ args: ~w(js/app.js --bundle --target=es2016 --outdir=../priv/static/assets), cd: Path.expand("../assets", __DIR__), env: %{"NODE_PATH" => "#{Path.expand("../deps", __DIR__)}:./node_modules"} ] """ end defp plug_static_code() do """ # lib/my_super_app/web/endpoint.ex ... plug(Plug.Static, at: "/moon/assets", from: :moon, gzip: true, only: ~w(assets themes images fonts svgs favicon.ico robots.txt), cache_control_for_etags: "public, max-age=86400" ) plug(Plug.Static, at: "/moon_icons/", from: :moon_icons, gzip: true, cache_control_for_etags: "public, max-age=86400" ) ... """ end defp themes_import_code() do """ /* assets/css/app.css */ /* this is a default theme - used on surface.moon.io feel free to copy and modify it */ @import '../../deps/moon/priv/static/themes/moon.css'; /* Not really required. Only few classes for components are from there. All tailwind imports are already there, so you can remove them from your own app.css also can import _components.css instead @import '../../deps/moon/assets/css/_components.css'; */ @import '../../deps/moon/assets/css/app.css'; """ end defp scripts_code() do """ # assets.package.json "scripts": { "deploy": "NODE_ENV=production tailwindcss -i css/app.css -o ../priv/static/assets/app.css --postcss --minify", "build": "tailwindcss -i css/app.css -o ../priv/static/assets/app.css --postcss", "watch": "tailwindcss -i css/app.css -o ../priv/static/assets/app.css --postcss --watch" }, """ end defp dependencies_code() do """ # assets.package.json "dependencies": { "@tailwindcss/forms": "^0.4.0", "autoprefixer": "^10.4.2", "postcss": "^8.4.5", "postcss-import": "^14.0.2", "tailwindcss": "^3.1.7", "@popperjs/core": "^2.11.6" }, """ end defp postcss_config_code() do """ // assets/postcss.config.js module.exports = { plugins: { 'postcss-import': {}, tailwindcss: {}, autoprefixer: {} } } """ end defp tailwind_config_code() do """ // assets/tailwind.config.js const tailwind_config = require("../deps/moon/assets/tailwind.config.js"); tailwind_config.content = [ "../lib/**/*.ex", "../lib/**/*.heex", "../lib/**/*.eex", "./js/**/*.js", "../deps/moon/lib/**/*.ex", "../deps/moon/lib/**/*.heex", "../deps/moon/lib/**/*.eex", "../deps/moon/assets/js/**/*.js", ]; module.exports = tailwind_config; """ end defp javascript_import_code() do """ // assets/js/app.js ... import Hooks from "./_hooks" // the next line should be added import MoonHooks from "../../deps/moon/assets/js/hooks" let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content") let liveSocket = new LiveSocket("/live", Socket, {params: {_csrf_token: csrfToken}, hooks: { ...MoonHooks, // here we do use imported hooks ...Hooks }}) """ end defp mix_exs_aliases() do """ # mix.exs ... defp aliases do [ setup: ["deps.get", "assets.setup", "assets.build"], "assets.setup": ["cmd --cd assets npm i", "esbuild.install --if-missing"], "assets.build": ["cmd --cd assets npm run build", "esbuild default"], "assets.deploy": [ "cmd --cd assets npm run deploy", "NODE_ENV=production esbuild default --minify", "phx.digest" ] ] end """ end defp layout_modifications() do """ ... ... """ end end