Using fontawesome JS SVG core API instead of simple API.

This commit is contained in:
Daan Vanden Bosch 2021-09-17 16:05:55 +02:00
parent 19d3030d20
commit fab0c5a77a
8 changed files with 112 additions and 31 deletions

View File

@ -12,3 +12,14 @@ expect class UnsafeMap<K, V>() {
fun set(key: K, value: V)
fun delete(key: K): Boolean
}
fun <K, V : Any> UnsafeMap<K, V>.getOrPut(key: K, default: () -> V): V {
var value = get(key)
if (value == null) {
value = default()
set(key, value)
}
return value
}

View File

@ -5,7 +5,10 @@ plugins {
dependencies {
api(project(":core"))
api(project(":observable"))
implementation(npm("@fortawesome/fontawesome-free", "^5.13.1"))
implementation(npm("@fortawesome/fontawesome-svg-core", "^1.2.36"))
implementation(npm("@fortawesome/free-regular-svg-icons", "^5.15.4"))
implementation(npm("@fortawesome/free-solid-svg-icons", "^5.15.4"))
implementation(npm("@fortawesome/free-brands-svg-icons", "^5.15.4"))
testImplementation(project(":test-utils"))
}

View File

@ -10,10 +10,18 @@ import org.w3c.dom.pointerevents.PointerEvent
import world.phantasmal.core.disposable.Disposable
import world.phantasmal.core.disposable.Disposer
import world.phantasmal.core.disposable.disposable
import world.phantasmal.core.unsafe.UnsafeMap
import world.phantasmal.core.unsafe.getOrPut
import world.phantasmal.observable.cell.Cell
import world.phantasmal.observable.cell.list.ListCell
import world.phantasmal.observable.cell.list.ListChange
import world.phantasmal.observable.cell.list.ListChangeEvent
import world.phantasmal.webui.externals.fontawesome.IconDefinition
import world.phantasmal.webui.externals.fontawesome.freeBrandsSvgIcons.faGithub
import world.phantasmal.webui.externals.fontawesome.freeRegularSvgIcons.faCaretSquareRight
import world.phantasmal.webui.externals.fontawesome.freeRegularSvgIcons.faEye
import world.phantasmal.webui.externals.fontawesome.freeSolidSvgIcons.*
import world.phantasmal.webui.externals.fontawesome.icon as faIcon
fun <E : Event> EventTarget.disposableListener(
type: String,
@ -120,32 +128,36 @@ enum class Icon {
Undo,
}
/** Fontawesome icons. */
private val faElementCache = UnsafeMap<IconDefinition, Element>()
fun Node.icon(icon: Icon): HTMLElement {
val iconStr = when (icon) {
Icon.ArrowDown -> "fas fa-arrow-down"
Icon.ArrowRight -> "fas fa-arrow-right"
Icon.Eye -> "far fa-eye"
Icon.File -> "fas fa-file"
Icon.GitHub -> "fab fa-github"
Icon.LevelDown -> "fas fa-level-down-alt"
Icon.LevelUp -> "fas fa-level-up-alt"
Icon.LongArrowRight -> "fas fa-long-arrow-alt-right"
Icon.NewFile -> "fas fa-file-medical"
Icon.Play -> "fas fa-play"
Icon.Plus -> "fas fa-plus"
Icon.Redo -> "fas fa-redo"
Icon.Remove -> "fas fa-trash-alt"
Icon.Save -> "fas fa-save"
Icon.Stop -> "fas fa-stop"
Icon.SquareArrowRight -> "far fa-caret-square-right"
Icon.TriangleDown -> "fas fa-caret-down"
Icon.TriangleUp -> "fas fa-caret-up"
Icon.Undo -> "fas fa-undo"
val iconDef = when (icon) {
Icon.ArrowDown -> faArrowDown
Icon.ArrowRight -> faArrowRight
Icon.Eye -> faEye
Icon.File -> faFile
Icon.GitHub -> faGithub
Icon.LevelDown -> faLevelDownAlt
Icon.LevelUp -> faLevelUpAlt
Icon.LongArrowRight -> faLongArrowAltRight
Icon.NewFile -> faFileMedical
Icon.Play -> faPlay
Icon.Plus -> faPlus
Icon.Redo -> faRedo
Icon.Remove -> faTrashAlt
Icon.Save -> faSave
Icon.Stop -> faStop
Icon.SquareArrowRight -> faCaretSquareRight
Icon.TriangleDown -> faCaretDown
Icon.TriangleUp -> faCaretUp
Icon.Undo -> faUndo
}
// Wrap the span in another span, because Font Awesome will replace the inner element. This way
// the returned element will stay valid.
return span { span { className = iconStr } }
return span {
val iconEl = faElementCache.getOrPut(iconDef) { faIcon(iconDef).node[0]!! }
append(iconEl.cloneNode(deep = true))
}
}
fun <T> bindChildrenTo(

View File

@ -0,0 +1,22 @@
@file:JsModule("@fortawesome/fontawesome-svg-core")
@file:JsNonModule
package world.phantasmal.webui.externals.fontawesome
import org.w3c.dom.HTMLCollection
external class IconDefinition
external class Icon {
val html: Array<String>
val node: HTMLCollection
}
external fun icon(icon: IconDefinition): Icon
external class Config {
/** async or sync */
var mutateApproach: String
}
external val config: Config

View File

@ -0,0 +1,8 @@
@file:JsModule("@fortawesome/free-brands-svg-icons")
@file:JsNonModule
package world.phantasmal.webui.externals.fontawesome.freeBrandsSvgIcons
import world.phantasmal.webui.externals.fontawesome.IconDefinition
external val faGithub: IconDefinition

View File

@ -0,0 +1,9 @@
@file:JsModule("@fortawesome/free-regular-svg-icons")
@file:JsNonModule
package world.phantasmal.webui.externals.fontawesome.freeRegularSvgIcons
import world.phantasmal.webui.externals.fontawesome.IconDefinition
external val faCaretSquareRight: IconDefinition
external val faEye: IconDefinition

View File

@ -0,0 +1,23 @@
@file:JsModule("@fortawesome/free-solid-svg-icons")
@file:JsNonModule
package world.phantasmal.webui.externals.fontawesome.freeSolidSvgIcons
import world.phantasmal.webui.externals.fontawesome.IconDefinition
external val faArrowDown: IconDefinition
external val faArrowRight: IconDefinition
external val faCaretDown: IconDefinition
external val faCaretUp: IconDefinition
external val faFile: IconDefinition
external val faFileMedical: IconDefinition
external val faLevelDownAlt: IconDefinition
external val faLevelUpAlt: IconDefinition
external val faLongArrowAltRight: IconDefinition
external val faPlay: IconDefinition
external val faPlus: IconDefinition
external val faRedo: IconDefinition
external val faSave: IconDefinition
external val faStop: IconDefinition
external val faTrashAlt: IconDefinition
external val faUndo: IconDefinition

View File

@ -217,13 +217,6 @@ abstract class Widget(
el
}
init {
js("require('@fortawesome/fontawesome-free/js/fontawesome');")
js("require('@fortawesome/fontawesome-free/js/solid');")
js("require('@fortawesome/fontawesome-free/js/regular');")
js("require('@fortawesome/fontawesome-free/js/brands');")
}
protected fun style(style: String) {
STYLE_EL.append(style)
}