From ce7377bcb1bfd1bf01df4b615e861c8709e9fbea Mon Sep 17 00:00:00 2001 From: nguyenyou Date: Wed, 27 Nov 2024 21:19:08 +0700 Subject: [PATCH] add sapui5 example --- examples/sapui5-mill/.gitignore | 36 +++ examples/sapui5-mill/.mill-version | 1 + examples/sapui5-mill/.scalafmt.conf | 3 + examples/sapui5-mill/README.md | 43 ++++ examples/sapui5-mill/build.mill | 15 ++ examples/sapui5-mill/index.html | 13 + examples/sapui5-mill/main.js | 2 + examples/sapui5-mill/millw | 241 ++++++++++++++++++ .../sapui5-mill/myapp/src/myapp/helper.scala | 43 ++++ .../sapui5-mill/myapp/src/myapp/index.scala | 19 ++ examples/sapui5-mill/package.json | 25 ++ examples/sapui5-mill/postcss.config.js | 6 + examples/sapui5-mill/public/vite.svg | 1 + examples/sapui5-mill/style.css | 3 + examples/sapui5-mill/tailwind.config.cjs | 10 + examples/sapui5-mill/vite.config.js | 14 + 16 files changed, 475 insertions(+) create mode 100644 examples/sapui5-mill/.gitignore create mode 100644 examples/sapui5-mill/.mill-version create mode 100644 examples/sapui5-mill/.scalafmt.conf create mode 100644 examples/sapui5-mill/README.md create mode 100644 examples/sapui5-mill/build.mill create mode 100644 examples/sapui5-mill/index.html create mode 100644 examples/sapui5-mill/main.js create mode 100755 examples/sapui5-mill/millw create mode 100644 examples/sapui5-mill/myapp/src/myapp/helper.scala create mode 100644 examples/sapui5-mill/myapp/src/myapp/index.scala create mode 100644 examples/sapui5-mill/package.json create mode 100644 examples/sapui5-mill/postcss.config.js create mode 100644 examples/sapui5-mill/public/vite.svg create mode 100644 examples/sapui5-mill/style.css create mode 100644 examples/sapui5-mill/tailwind.config.cjs create mode 100644 examples/sapui5-mill/vite.config.js diff --git a/examples/sapui5-mill/.gitignore b/examples/sapui5-mill/.gitignore new file mode 100644 index 0000000..1881b1f --- /dev/null +++ b/examples/sapui5-mill/.gitignore @@ -0,0 +1,36 @@ +# Logs +logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +node_modules +dist +dist-ssr +*.local + +# Editor directories and files +.vscode/* +!.vscode/extensions.json +.idea +.DS_Store +*.suo +*.ntvs* +*.njsproj +*.sln +*.sw? +.bsp +.metals +.scala-build +scalajs-modules +scalawind.scala +bun.lockb +yarn.lock +package-lock.json +pnpm-lock.yaml +target +.bloop +.idea \ No newline at end of file diff --git a/examples/sapui5-mill/.mill-version b/examples/sapui5-mill/.mill-version new file mode 100644 index 0000000..d61567c --- /dev/null +++ b/examples/sapui5-mill/.mill-version @@ -0,0 +1 @@ +0.12.3 \ No newline at end of file diff --git a/examples/sapui5-mill/.scalafmt.conf b/examples/sapui5-mill/.scalafmt.conf new file mode 100644 index 0000000..3ea0470 --- /dev/null +++ b/examples/sapui5-mill/.scalafmt.conf @@ -0,0 +1,3 @@ +version = "3.7.15" +runner.dialect = scala3 +maxColumn=120 \ No newline at end of file diff --git a/examples/sapui5-mill/README.md b/examples/sapui5-mill/README.md new file mode 100644 index 0000000..6fead2b --- /dev/null +++ b/examples/sapui5-mill/README.md @@ -0,0 +1,43 @@ +# Scalawind Vite + +## Install NodeJS + +In case you don't have NodeJS yet, this is my recommendation: https://github.com/Schniz/fnm + +## Install dependencies + +```bash +$ npm install +# or +$ bun install +# or +$ pnpm install +# or +$ yarn install +``` + +## Start dev server + +```bash +$ npm run dev:scala +# or +$ bun dev:scala +# or +$ pnpm dev:scala +# or +$ yarn dev:scala +``` + +In another terminal: + +```bash +$ npm run dev +# or +$ bun dev +# or +$ pnpm dev +# or +$ yarn dev +``` + +Open: http://localhost:5173 \ No newline at end of file diff --git a/examples/sapui5-mill/build.mill b/examples/sapui5-mill/build.mill new file mode 100644 index 0000000..712828e --- /dev/null +++ b/examples/sapui5-mill/build.mill @@ -0,0 +1,15 @@ +import mill._, scalalib._, scalajslib._, scalajslib.api._ + +object myapp extends ScalaJSModule { + def scalaVersion = "3.3.3" + def scalaJSVersion = "1.17.0" + + def moduleKind = ModuleKind.ESModule + def moduleSplitStyle = ModuleSplitStyle.SmallModulesFor(List("myapp")) + + def ivyDeps = Agg( + ivy"org.scala-js::scalajs-dom::2.8.0", + ivy"com.raquo::laminar::17.1.0", + ivy"be.doeraene::web-components-ui5::2.0.0", + ) +} diff --git a/examples/sapui5-mill/index.html b/examples/sapui5-mill/index.html new file mode 100644 index 0000000..e4d32f6 --- /dev/null +++ b/examples/sapui5-mill/index.html @@ -0,0 +1,13 @@ + + + + + + + Scala ❤️ Tailwind + + +
+ + + diff --git a/examples/sapui5-mill/main.js b/examples/sapui5-mill/main.js new file mode 100644 index 0000000..d5b7fff --- /dev/null +++ b/examples/sapui5-mill/main.js @@ -0,0 +1,2 @@ +import './style.css' +import 'scalajs:main.js' \ No newline at end of file diff --git a/examples/sapui5-mill/millw b/examples/sapui5-mill/millw new file mode 100755 index 0000000..9d343ff --- /dev/null +++ b/examples/sapui5-mill/millw @@ -0,0 +1,241 @@ +#!/usr/bin/env sh + +# This is a wrapper script, that automatically download mill from GitHub release pages +# You can give the required mill version with --mill-version parameter +# If no version is given, it falls back to the value of DEFAULT_MILL_VERSION +# +# Project page: https://github.com/lefou/millw +# Script Version: 0.4.11 +# +# If you want to improve this script, please also contribute your changes back! +# +# Licensed under the Apache License, Version 2.0 + +set -e + +if [ -z "${DEFAULT_MILL_VERSION}" ] ; then + DEFAULT_MILL_VERSION="0.11.4" +fi + + +if [ -z "${GITHUB_RELEASE_CDN}" ] ; then + GITHUB_RELEASE_CDN="" +fi + + +MILL_REPO_URL="https://github.com/com-lihaoyi/mill" + +if [ -z "${CURL_CMD}" ] ; then + CURL_CMD=curl +fi + +# Explicit commandline argument takes precedence over all other methods +if [ "$1" = "--mill-version" ] ; then + shift + if [ "x$1" != "x" ] ; then + MILL_VERSION="$1" + shift + else + echo "You specified --mill-version without a version." 1>&2 + echo "Please provide a version that matches one provided on" 1>&2 + echo "${MILL_REPO_URL}/releases" 1>&2 + false + fi +fi + +# Please note, that if a MILL_VERSION is already set in the environment, +# We reuse it's value and skip searching for a value. + +# If not already set, read .mill-version file +if [ -z "${MILL_VERSION}" ] ; then + if [ -f ".mill-version" ] ; then + MILL_VERSION="$(head -n 1 .mill-version 2> /dev/null)" + elif [ -f ".config/mill-version" ] ; then + MILL_VERSION="$(head -n 1 .config/mill-version 2> /dev/null)" + fi +fi + +MILL_USER_CACHE_DIR="${XDG_CACHE_HOME:-${HOME}/.cache}/mill" + +if [ -z "${MILL_DOWNLOAD_PATH}" ] ; then + MILL_DOWNLOAD_PATH="${MILL_USER_CACHE_DIR}/download" +fi + +# If not already set, try to fetch newest from Github +if [ -z "${MILL_VERSION}" ] ; then + # TODO: try to load latest version from release page + echo "No mill version specified." 1>&2 + echo "You should provide a version via '.mill-version' file or --mill-version option." 1>&2 + + mkdir -p "${MILL_DOWNLOAD_PATH}" + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" 2>/dev/null || ( + # we might be on OSX or BSD which don't have -d option for touch + # but probably a -A [-][[hh]mm]SS + touch "${MILL_DOWNLOAD_PATH}/.expire_latest"; touch -A -010000 "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) || ( + # in case we still failed, we retry the first touch command with the intention + # to show the (previously suppressed) error message + LANG=C touch -d '1 hour ago' "${MILL_DOWNLOAD_PATH}/.expire_latest" + ) + + # POSIX shell variant of bash's -nt operator, see https://unix.stackexchange.com/a/449744/6993 + # if [ "${MILL_DOWNLOAD_PATH}/.latest" -nt "${MILL_DOWNLOAD_PATH}/.expire_latest" ] ; then + if [ -n "$(find -L "${MILL_DOWNLOAD_PATH}/.latest" -prune -newer "${MILL_DOWNLOAD_PATH}/.expire_latest")" ]; then + # we know a current latest version + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # we don't know a current latest version + echo "Retrieving latest mill version ..." 1>&2 + LANG=C ${CURL_CMD} -s -i -f -I ${MILL_REPO_URL}/releases/latest 2> /dev/null | grep --ignore-case Location: | sed s'/^.*tag\///' | tr -d '\r\n' > "${MILL_DOWNLOAD_PATH}/.latest" + MILL_VERSION=$(head -n 1 "${MILL_DOWNLOAD_PATH}"/.latest 2> /dev/null) + fi + + if [ -z "${MILL_VERSION}" ] ; then + # Last resort + MILL_VERSION="${DEFAULT_MILL_VERSION}" + echo "Falling back to hardcoded mill version ${MILL_VERSION}" 1>&2 + else + echo "Using mill version ${MILL_VERSION}" 1>&2 + fi +fi + +MILL="${MILL_DOWNLOAD_PATH}/${MILL_VERSION}" + +try_to_use_system_mill() { + if [ "$(uname)" != "Linux" ]; then + return 0 + fi + + MILL_IN_PATH="$(command -v mill || true)" + + if [ -z "${MILL_IN_PATH}" ]; then + return 0 + fi + + SYSTEM_MILL_FIRST_TWO_BYTES=$(head --bytes=2 "${MILL_IN_PATH}") + if [ "${SYSTEM_MILL_FIRST_TWO_BYTES}" = "#!" ]; then + # MILL_IN_PATH is (very likely) a shell script and not the mill + # executable, ignore it. + return 0 + fi + + SYSTEM_MILL_PATH=$(readlink -e "${MILL_IN_PATH}") + SYSTEM_MILL_SIZE=$(stat --format=%s "${SYSTEM_MILL_PATH}") + SYSTEM_MILL_MTIME=$(stat --format=%y "${SYSTEM_MILL_PATH}") + + if [ ! -d "${MILL_USER_CACHE_DIR}" ]; then + mkdir -p "${MILL_USER_CACHE_DIR}" + fi + + SYSTEM_MILL_INFO_FILE="${MILL_USER_CACHE_DIR}/system-mill-info" + if [ -f "${SYSTEM_MILL_INFO_FILE}" ]; then + parseSystemMillInfo() { + LINE_NUMBER="${1}" + # Select the line number of the SYSTEM_MILL_INFO_FILE, cut the + # variable definition in that line in two halves and return + # the value, and finally remove the quotes. + sed -n "${LINE_NUMBER}p" "${SYSTEM_MILL_INFO_FILE}" |\ + cut -d= -f2 |\ + sed 's/"\(.*\)"/\1/' + } + + CACHED_SYSTEM_MILL_PATH=$(parseSystemMillInfo 1) + CACHED_SYSTEM_MILL_VERSION=$(parseSystemMillInfo 2) + CACHED_SYSTEM_MILL_SIZE=$(parseSystemMillInfo 3) + CACHED_SYSTEM_MILL_MTIME=$(parseSystemMillInfo 4) + + if [ "${SYSTEM_MILL_PATH}" = "${CACHED_SYSTEM_MILL_PATH}" ] \ + && [ "${SYSTEM_MILL_SIZE}" = "${CACHED_SYSTEM_MILL_SIZE}" ] \ + && [ "${SYSTEM_MILL_MTIME}" = "${CACHED_SYSTEM_MILL_MTIME}" ]; then + if [ "${CACHED_SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + return 0 + else + return 0 + fi + fi + fi + + SYSTEM_MILL_VERSION=$(${SYSTEM_MILL_PATH} --version | head -n1 | sed -n 's/^Mill.*version \(.*\)/\1/p') + + cat < "${SYSTEM_MILL_INFO_FILE}" +CACHED_SYSTEM_MILL_PATH="${SYSTEM_MILL_PATH}" +CACHED_SYSTEM_MILL_VERSION="${SYSTEM_MILL_VERSION}" +CACHED_SYSTEM_MILL_SIZE="${SYSTEM_MILL_SIZE}" +CACHED_SYSTEM_MILL_MTIME="${SYSTEM_MILL_MTIME}" +EOF + + if [ "${SYSTEM_MILL_VERSION}" = "${MILL_VERSION}" ]; then + MILL="${SYSTEM_MILL_PATH}" + fi +} +try_to_use_system_mill + +# If not already downloaded, download it +if [ ! -s "${MILL}" ] ; then + + # support old non-XDG download dir + MILL_OLD_DOWNLOAD_PATH="${HOME}/.mill/download" + OLD_MILL="${MILL_OLD_DOWNLOAD_PATH}/${MILL_VERSION}" + if [ -x "${OLD_MILL}" ] ; then + MILL="${OLD_MILL}" + else + case $MILL_VERSION in + 0.0.* | 0.1.* | 0.2.* | 0.3.* | 0.4.* ) + DOWNLOAD_SUFFIX="" + DOWNLOAD_FROM_MAVEN=0 + ;; + 0.5.* | 0.6.* | 0.7.* | 0.8.* | 0.9.* | 0.10.* | 0.11.0-M* ) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=0 + ;; + *) + DOWNLOAD_SUFFIX="-assembly" + DOWNLOAD_FROM_MAVEN=1 + ;; + esac + + DOWNLOAD_FILE=$(mktemp mill.XXXXXX) + + if [ "$DOWNLOAD_FROM_MAVEN" = "1" ] ; then + DOWNLOAD_URL="https://repo1.maven.org/maven2/com/lihaoyi/mill-dist/${MILL_VERSION}/mill-dist-${MILL_VERSION}.jar" + else + MILL_VERSION_TAG=$(echo "$MILL_VERSION" | sed -E 's/([^-]+)(-M[0-9]+)?(-.*)?/\1\2/') + DOWNLOAD_URL="${GITHUB_RELEASE_CDN}${MILL_REPO_URL}/releases/download/${MILL_VERSION_TAG}/${MILL_VERSION}${DOWNLOAD_SUFFIX}" + unset MILL_VERSION_TAG + fi + + # TODO: handle command not found + echo "Downloading mill ${MILL_VERSION} from ${DOWNLOAD_URL} ..." 1>&2 + ${CURL_CMD} -f -L -o "${DOWNLOAD_FILE}" "${DOWNLOAD_URL}" + chmod +x "${DOWNLOAD_FILE}" + mkdir -p "${MILL_DOWNLOAD_PATH}" + mv "${DOWNLOAD_FILE}" "${MILL}" + + unset DOWNLOAD_FILE + unset DOWNLOAD_SUFFIX + fi +fi + +if [ -z "$MILL_MAIN_CLI" ] ; then + MILL_MAIN_CLI="${0}" +fi + +MILL_FIRST_ARG="" +if [ "$1" = "--bsp" ] || [ "$1" = "-i" ] || [ "$1" = "--interactive" ] || [ "$1" = "--no-server" ] || [ "$1" = "--repl" ] || [ "$1" = "--help" ] ; then + # Need to preserve the first position of those listed options + MILL_FIRST_ARG=$1 + shift +fi + +unset MILL_DOWNLOAD_PATH +unset MILL_OLD_DOWNLOAD_PATH +unset OLD_MILL +unset MILL_VERSION +unset MILL_REPO_URL + +# We don't quote MILL_FIRST_ARG on purpose, so we can expand the empty value without quotes +# shellcheck disable=SC2086 +exec "${MILL}" $MILL_FIRST_ARG -D "mill.main.cli=${MILL_MAIN_CLI}" "$@" diff --git a/examples/sapui5-mill/myapp/src/myapp/helper.scala b/examples/sapui5-mill/myapp/src/myapp/helper.scala new file mode 100644 index 0000000..16b2e1b --- /dev/null +++ b/examples/sapui5-mill/myapp/src/myapp/helper.scala @@ -0,0 +1,43 @@ +package myapp + +import com.raquo.laminar.api.L.* +import be.doeraene.webcomponents.ui5.* +import be.doeraene.webcomponents.ui5.theming.Theming + +object ThemeSelector { + + /** Allows to select the theme for the web-components. + * + * That does not take care of the "rest" of the ui (for example, the general background colour, or text colours...) + * + * You would need to use the `selectedChoiceVar` current value and adjust remaining css when relevant. + */ + def apply(): HtmlElement = { + + val themeChoices = Vector( + "sap_fiori_3", + "sap_fiori_3_dark" + ) + + val selectedChoiceVar = Var(themeChoices(0)) + + Select( + themeChoices.map { theme => + Select.option( + theme, + _.value := theme, + _.selected <-- selectedChoiceVar.signal.map(_ == theme) + ) + }, + _.events.onChange.map(_.detail.selectedOption.maybeValue.getOrElse(themeChoices(0))) --> selectedChoiceVar.writer, + selectedChoiceVar.signal.changes --> Observer(Theming.setTheme) + ) + + } + + // registering the themes + Theming.WebComponentsAssets + Theming.WebComponentsFioriAssets + Theming.WebComponentsCompatAssets + +} diff --git a/examples/sapui5-mill/myapp/src/myapp/index.scala b/examples/sapui5-mill/myapp/src/myapp/index.scala new file mode 100644 index 0000000..6d20505 --- /dev/null +++ b/examples/sapui5-mill/myapp/src/myapp/index.scala @@ -0,0 +1,19 @@ +package myapp + +import org.scalajs.dom + +import com.raquo.laminar.api.L.* +import be.doeraene.webcomponents.ui5.* +import be.doeraene.webcomponents.ui5.configkeys.* + +@main +def main(): Unit = { + val container = dom.document.getElementById("app") + render( + container, + div( + ThemeSelector(), + Button(_.design := ButtonDesign.Default, "Default") + ) + ) +} diff --git a/examples/sapui5-mill/package.json b/examples/sapui5-mill/package.json new file mode 100644 index 0000000..da906b0 --- /dev/null +++ b/examples/sapui5-mill/package.json @@ -0,0 +1,25 @@ +{ + "name": "scalawind-vite-mill", + "private": true, + "version": "0.0.0", + "type": "module", + "scripts": { + "dev": "vite", + "build": "vite build", + "preview": "vite preview", + "dev:scala": "./millw -w myapp.fastLinkJS", + "build:scala": "./millw myapp.fullLinkJS" + }, + "devDependencies": { + "autoprefixer": "10.4.19", + "postcss": "8.4.38", + "tailwindcss": "3.4.3", + "vite": "6.0.1" + }, + "dependencies": { + "@ui5/webcomponents": "2.4.0", + "@ui5/webcomponents-compat": "2.4.0", + "@ui5/webcomponents-fiori": "2.4.0", + "@ui5/webcomponents-icons": "2.4.0" + } +} diff --git a/examples/sapui5-mill/postcss.config.js b/examples/sapui5-mill/postcss.config.js new file mode 100644 index 0000000..2e7af2b --- /dev/null +++ b/examples/sapui5-mill/postcss.config.js @@ -0,0 +1,6 @@ +export default { + plugins: { + tailwindcss: {}, + autoprefixer: {}, + }, +} diff --git a/examples/sapui5-mill/public/vite.svg b/examples/sapui5-mill/public/vite.svg new file mode 100644 index 0000000..e7b8dfb --- /dev/null +++ b/examples/sapui5-mill/public/vite.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/examples/sapui5-mill/style.css b/examples/sapui5-mill/style.css new file mode 100644 index 0000000..7ce3e99 --- /dev/null +++ b/examples/sapui5-mill/style.css @@ -0,0 +1,3 @@ +/* @tailwind base; +@tailwind components; +@tailwind utilities; */ \ No newline at end of file diff --git a/examples/sapui5-mill/tailwind.config.cjs b/examples/sapui5-mill/tailwind.config.cjs new file mode 100644 index 0000000..edfb2da --- /dev/null +++ b/examples/sapui5-mill/tailwind.config.cjs @@ -0,0 +1,10 @@ +/** @type {import('tailwindcss').Config} */ +module.exports = { + content: { + files: [ + './index.html', + './out/myapp/fastLinkJS.dest/**/*.js', + './out/myapp/fullLinkJS.dest/**/*.js' + ], + }, +}; \ No newline at end of file diff --git a/examples/sapui5-mill/vite.config.js b/examples/sapui5-mill/vite.config.js new file mode 100644 index 0000000..d042e6d --- /dev/null +++ b/examples/sapui5-mill/vite.config.js @@ -0,0 +1,14 @@ +import { defineConfig } from 'vite'; + +const isProd = process.env.NODE_ENV == "production"; + +export default defineConfig({ + resolve: { + alias: [ + { + find: /^scalajs:(.*)$/, + replacement: `/out/myapp/${isProd ? 'full' : 'fast'}LinkJS.dest/$1` + } + ] + } +}); \ No newline at end of file