@tamer4lynx/tamer-icons 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +44 -0
- package/android/build.gradle.kts +28 -0
- package/android/src/main/assets/fonts/MaterialIcons-Regular.ttf +0 -0
- package/android/src/main/assets/fonts/MaterialSymbolsOutlined.ttf +0 -0
- package/android/src/main/assets/fonts/fa-solid-900.ttf +0 -0
- package/android/src/main/assets/fonts/material-codepoints.txt +4206 -0
- package/android/src/main/kotlin/com/nanofuxion/tamericons/IconCodepoints.kt +60 -0
- package/android/src/main/kotlin/com/nanofuxion/tamericons/IconDrawable.kt +92 -0
- package/android/src/main/kotlin/com/nanofuxion/tamericons/IconElement.kt +162 -0
- package/dist/fontawesome-codepoints.d.ts +2 -0
- package/dist/fontawesome-codepoints.d.ts.map +1 -0
- package/dist/fontawesome-codepoints.js +20 -0
- package/dist/fonts.css +13 -0
- package/dist/fonts.d.ts +7 -0
- package/dist/fonts.d.ts.map +1 -0
- package/dist/fonts.js +6 -0
- package/dist/index.d.ts +19 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +16 -0
- package/dist/material-codepoints.d.ts +2 -0
- package/dist/material-codepoints.d.ts.map +1 -0
- package/dist/material-codepoints.js +56 -0
- package/dist/plugin.d.ts +3 -0
- package/dist/plugin.d.ts.map +1 -0
- package/dist/plugin.js +43 -0
- package/dist/tamer.config.d.ts +5 -0
- package/dist/tamer.config.d.ts.map +1 -0
- package/dist/tamer.config.js +4 -0
- package/fonts/MaterialIcons-Regular.ttf +0 -0
- package/fonts/MaterialSymbolsOutlined.ttf +0 -0
- package/fonts/fa-solid-900.ttf +0 -0
- package/ios/tamericons/tamericons/Classes/TamerIconElement.h +10 -0
- package/ios/tamericons/tamericons/Classes/TamerIconElement.m +307 -0
- package/ios/tamericons/tamericons/Resources/MaterialSymbolsOutlined.ttf +0 -0
- package/ios/tamericons/tamericons/Resources/fa-solid-900.ttf +0 -0
- package/ios/tamericons/tamericons/Resources/material-codepoints.txt +4206 -0
- package/ios/tamericons/tamericons.podspec +26 -0
- package/lynx.ext.json +17 -0
- package/package.json +48 -0
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
package com.nanofuxion.tamericons
|
|
2
|
+
|
|
3
|
+
import java.io.BufferedReader
|
|
4
|
+
import java.io.InputStreamReader
|
|
5
|
+
|
|
6
|
+
object IconCodepoints {
|
|
7
|
+
|
|
8
|
+
val FONTAWESOME: Map<String, Char> = mapOf(
|
|
9
|
+
"search" to '\uf002',
|
|
10
|
+
"home" to '\uf015',
|
|
11
|
+
"bars" to '\uf0c9',
|
|
12
|
+
"arrow-left" to '\uf060',
|
|
13
|
+
"xmark" to '\uf00d',
|
|
14
|
+
"close" to '\uf00d',
|
|
15
|
+
"plus" to '\uf067',
|
|
16
|
+
"minus" to '\uf068',
|
|
17
|
+
"cog" to '\uf013',
|
|
18
|
+
"user" to '\uf007',
|
|
19
|
+
"heart" to '\uf004',
|
|
20
|
+
"share" to '\uf064',
|
|
21
|
+
"trash" to '\uf1f8',
|
|
22
|
+
"pen" to '\uf304',
|
|
23
|
+
"check" to '\uf00c',
|
|
24
|
+
"info" to '\uf129',
|
|
25
|
+
"exclamation-triangle" to '\uf071',
|
|
26
|
+
"circle-xmark" to '\uf057',
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
@Volatile
|
|
30
|
+
private var materialCache: Map<String, Int>? = null
|
|
31
|
+
|
|
32
|
+
fun getMaterial(assets: android.content.res.AssetManager): Map<String, Int> {
|
|
33
|
+
return materialCache ?: synchronized(this) {
|
|
34
|
+
materialCache ?: loadMaterialFromAssets(assets).also { materialCache = it }
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
private fun loadMaterialFromAssets(assets: android.content.res.AssetManager): Map<String, Int> {
|
|
39
|
+
return try {
|
|
40
|
+
assets.open("fonts/material-codepoints.txt").use { stream ->
|
|
41
|
+
BufferedReader(InputStreamReader(stream)).use { reader ->
|
|
42
|
+
buildMap {
|
|
43
|
+
reader.lineSequence().forEach { line ->
|
|
44
|
+
val space = line.indexOf(' ')
|
|
45
|
+
if (space > 0) {
|
|
46
|
+
val name = line.substring(0, space)
|
|
47
|
+
val hex = line.substring(space + 1).trim()
|
|
48
|
+
if (hex.all { it in '0'..'9' || it in 'a'..'f' || it in 'A'..'F' }) {
|
|
49
|
+
put(name, hex.toInt(16))
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
} catch (e: Exception) {
|
|
57
|
+
emptyMap()
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
package com.nanofuxion.tamericons
|
|
2
|
+
|
|
3
|
+
import android.content.res.ColorStateList
|
|
4
|
+
import android.graphics.Canvas
|
|
5
|
+
import android.graphics.Paint
|
|
6
|
+
import android.graphics.Path
|
|
7
|
+
import android.graphics.RectF
|
|
8
|
+
import android.graphics.drawable.Drawable
|
|
9
|
+
import android.graphics.Typeface
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Drawable that renders a single icon font character, scaled and centered in bounds.
|
|
13
|
+
* Color handling follows Android-Iconics: color is stored in a ColorStateList and
|
|
14
|
+
* applied to the paint in draw() so the icon color is not overridden by framework tint.
|
|
15
|
+
*/
|
|
16
|
+
class IconDrawable(
|
|
17
|
+
private val typeface: Typeface,
|
|
18
|
+
private val codepoint: Int,
|
|
19
|
+
color: Int,
|
|
20
|
+
private val sizePx: Int
|
|
21
|
+
) : Drawable() {
|
|
22
|
+
|
|
23
|
+
private var colorList: ColorStateList = ColorStateList.valueOf(color)
|
|
24
|
+
|
|
25
|
+
private val paint = Paint(Paint.ANTI_ALIAS_FLAG).apply {
|
|
26
|
+
style = Paint.Style.FILL
|
|
27
|
+
textAlign = Paint.Align.LEFT
|
|
28
|
+
this.typeface = this@IconDrawable.typeface
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
private val path = Path()
|
|
32
|
+
private val pathBounds = RectF()
|
|
33
|
+
|
|
34
|
+
private val charSequence: CharSequence
|
|
35
|
+
get() = if (codepoint <= 0xFFFF) Character.toString(codepoint.toChar())
|
|
36
|
+
else String(Character.toChars(codepoint))
|
|
37
|
+
|
|
38
|
+
init {
|
|
39
|
+
setBounds(0, 0, sizePx, sizePx)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
fun setColor(value: Int) {
|
|
43
|
+
if (colorList.defaultColor != value) {
|
|
44
|
+
colorList = ColorStateList.valueOf(value)
|
|
45
|
+
invalidateSelf()
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
override fun draw(canvas: Canvas) {
|
|
50
|
+
if (codepoint == 0) return
|
|
51
|
+
paint.color = colorList.getColorForState(state, colorList.defaultColor)
|
|
52
|
+
paint.colorFilter = null
|
|
53
|
+
val b = bounds
|
|
54
|
+
if (b.width() <= 0 || b.height() <= 0) return
|
|
55
|
+
|
|
56
|
+
val seq = charSequence
|
|
57
|
+
path.reset()
|
|
58
|
+
var textSize = b.height().toFloat()
|
|
59
|
+
paint.textSize = textSize
|
|
60
|
+
paint.getTextPath(seq.toString(), 0, seq.length, 0f, 0f, path)
|
|
61
|
+
path.computeBounds(pathBounds, true)
|
|
62
|
+
|
|
63
|
+
val pathW = pathBounds.width().coerceAtLeast(1f)
|
|
64
|
+
val pathH = pathBounds.height().coerceAtLeast(1f)
|
|
65
|
+
val scaleW = b.width() / pathW
|
|
66
|
+
val scaleH = b.height() / pathH
|
|
67
|
+
val scale = minOf(scaleW, scaleH).coerceAtMost(1f)
|
|
68
|
+
textSize *= scale
|
|
69
|
+
paint.textSize = textSize
|
|
70
|
+
path.reset()
|
|
71
|
+
paint.getTextPath(seq.toString(), 0, seq.length, 0f, 0f, path)
|
|
72
|
+
path.computeBounds(pathBounds, true)
|
|
73
|
+
|
|
74
|
+
val offsetX = b.left + (b.width() - pathBounds.width()) / 2 - pathBounds.left
|
|
75
|
+
val offsetY = b.top + (b.height() - pathBounds.height()) / 2 - pathBounds.top
|
|
76
|
+
path.offset(offsetX, offsetY)
|
|
77
|
+
canvas.drawPath(path, paint)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
override fun setAlpha(alpha: Int) {
|
|
81
|
+
paint.alpha = alpha
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
override fun setColorFilter(colorFilter: android.graphics.ColorFilter?) {
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
@Deprecated("Deprecated in Java")
|
|
88
|
+
override fun getOpacity(): Int = android.graphics.PixelFormat.TRANSLUCENT
|
|
89
|
+
|
|
90
|
+
override fun getIntrinsicWidth(): Int = sizePx
|
|
91
|
+
override fun getIntrinsicHeight(): Int = sizePx
|
|
92
|
+
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
package com.nanofuxion.tamericons
|
|
2
|
+
|
|
3
|
+
import android.content.Context
|
|
4
|
+
import android.graphics.Color
|
|
5
|
+
import android.graphics.Typeface
|
|
6
|
+
import android.util.Log
|
|
7
|
+
import android.util.TypedValue
|
|
8
|
+
import android.view.ViewGroup
|
|
9
|
+
import android.widget.FrameLayout
|
|
10
|
+
import android.widget.ImageView
|
|
11
|
+
import com.lynx.react.bridge.Dynamic
|
|
12
|
+
import com.lynx.react.bridge.ReadableType
|
|
13
|
+
import com.lynx.tasm.behavior.LynxContext
|
|
14
|
+
import com.lynx.tasm.behavior.LynxProp
|
|
15
|
+
import com.lynx.tasm.behavior.ui.LynxUI
|
|
16
|
+
|
|
17
|
+
class IconElement(context: LynxContext) : LynxUI<FrameLayout>(context) {
|
|
18
|
+
|
|
19
|
+
private var iconSet = "material"
|
|
20
|
+
private var iconName = ""
|
|
21
|
+
private var iconColor = Color.BLACK
|
|
22
|
+
private var iconSizeSp = 24f
|
|
23
|
+
|
|
24
|
+
private lateinit var imageView: ImageView
|
|
25
|
+
|
|
26
|
+
override fun createView(context: Context): FrameLayout {
|
|
27
|
+
Log.d("TamerIcon", "createView called")
|
|
28
|
+
val container = FrameLayout(context).apply {
|
|
29
|
+
clipChildren = false
|
|
30
|
+
clipToPadding = false
|
|
31
|
+
}
|
|
32
|
+
imageView = ImageView(context).apply {
|
|
33
|
+
scaleType = ImageView.ScaleType.CENTER_INSIDE
|
|
34
|
+
setColorFilter(null)
|
|
35
|
+
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.LOLLIPOP) {
|
|
36
|
+
imageTintList = null
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
container.addView(imageView, FrameLayout.LayoutParams(
|
|
40
|
+
ViewGroup.LayoutParams.MATCH_PARENT,
|
|
41
|
+
ViewGroup.LayoutParams.MATCH_PARENT
|
|
42
|
+
))
|
|
43
|
+
return container
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
private fun getTypeface(): Typeface? {
|
|
47
|
+
return try {
|
|
48
|
+
val assetPath = when (iconSet) {
|
|
49
|
+
"fontawesome", "fa" -> "fonts/fa-solid-900.ttf"
|
|
50
|
+
else -> "fonts/MaterialSymbolsOutlined.ttf"
|
|
51
|
+
}
|
|
52
|
+
Typeface.createFromAsset(lynxContext.context.assets, assetPath)
|
|
53
|
+
} catch (e: Exception) {
|
|
54
|
+
null
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
private fun resolveCodepoint(): Int {
|
|
59
|
+
return when (iconSet) {
|
|
60
|
+
"fontawesome", "fa" -> {
|
|
61
|
+
val key = iconName.removePrefix("fa-").replace("_", "-")
|
|
62
|
+
(IconCodepoints.FONTAWESOME[key] ?: IconCodepoints.FONTAWESOME[iconName])?.code ?: 0
|
|
63
|
+
}
|
|
64
|
+
else -> {
|
|
65
|
+
val map = IconCodepoints.getMaterial(lynxContext.context.assets)
|
|
66
|
+
map[iconName]
|
|
67
|
+
?: map[iconName.replace("_", "-")]
|
|
68
|
+
?: map[iconName.replace("-", "_")]
|
|
69
|
+
?: 0
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
private fun applyIcon() {
|
|
75
|
+
if (!::imageView.isInitialized) return
|
|
76
|
+
val typeface = getTypeface()
|
|
77
|
+
if (typeface == null) {
|
|
78
|
+
Log.w("TamerIcon", "typeface null for set=$iconSet icon=$iconName")
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
val codepoint = resolveCodepoint()
|
|
82
|
+
if (codepoint == 0) {
|
|
83
|
+
Log.w("TamerIcon", "codepoint=0 for icon=$iconName set=$iconSet")
|
|
84
|
+
}
|
|
85
|
+
val sizePx = TypedValue.applyDimension(
|
|
86
|
+
TypedValue.COMPLEX_UNIT_SP,
|
|
87
|
+
iconSizeSp,
|
|
88
|
+
imageView.context.resources.displayMetrics
|
|
89
|
+
).toInt().coerceAtLeast(1)
|
|
90
|
+
val drawable = IconDrawable(typeface, codepoint, iconColor, sizePx)
|
|
91
|
+
imageView.setImageDrawable(drawable)
|
|
92
|
+
imageView.clearColorFilter()
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
@LynxProp(name = "icon")
|
|
96
|
+
fun setIcon(value: String) {
|
|
97
|
+
iconName = value
|
|
98
|
+
applyIcon()
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
@LynxProp(name = "set")
|
|
102
|
+
fun setIconSet(value: String) {
|
|
103
|
+
iconSet = value.lowercase()
|
|
104
|
+
applyIcon()
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@LynxProp(name = "iconColor")
|
|
108
|
+
fun setIconColor(value: Dynamic) {
|
|
109
|
+
applyColorFromDynamic(value)
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
private fun applyColorFromDynamic(value: Dynamic) {
|
|
113
|
+
if (value.type == ReadableType.Null) return
|
|
114
|
+
iconColor = when (value.type) {
|
|
115
|
+
ReadableType.Number -> (value.asDouble().toLong() and 0xFFFFFFFFL).toInt()
|
|
116
|
+
ReadableType.String -> parseColorString(value.asString())
|
|
117
|
+
else -> return
|
|
118
|
+
}
|
|
119
|
+
if (::imageView.isInitialized) {
|
|
120
|
+
(imageView.drawable as? IconDrawable)?.setColor(iconColor)
|
|
121
|
+
?: applyIcon()
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
private fun expandHex(hex: String): String =
|
|
126
|
+
if (hex.length == 3) hex.map { "$it$it" }.joinToString("") else hex
|
|
127
|
+
|
|
128
|
+
private fun parseColorString(value: String): Int = try {
|
|
129
|
+
when {
|
|
130
|
+
value.startsWith("#") -> Color.parseColor("#${expandHex(value.removePrefix("#"))}")
|
|
131
|
+
value.startsWith("rgb") -> parseRgb(value)
|
|
132
|
+
else -> Color.parseColor(value)
|
|
133
|
+
}
|
|
134
|
+
} catch (_: Exception) {
|
|
135
|
+
Color.BLACK
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
@LynxProp(name = "size")
|
|
139
|
+
fun setSize(value: Double) {
|
|
140
|
+
iconSizeSp = value.toFloat()
|
|
141
|
+
applyIcon()
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
private fun parseRgb(value: String): Int {
|
|
145
|
+
val parts = value.replace(Regex("[^0-9,.]"), "").split(",")
|
|
146
|
+
val nums = parts.map { it.toFloatOrNull() ?: 0f }
|
|
147
|
+
return when (nums.size) {
|
|
148
|
+
3 -> Color.rgb(nums[0].toInt(), nums[1].toInt(), nums[2].toInt())
|
|
149
|
+
4 -> Color.argb((nums[3] * 255).toInt(), nums[0].toInt(), nums[1].toInt(), nums[2].toInt())
|
|
150
|
+
else -> Color.BLACK
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
override fun onLayoutUpdated() {
|
|
155
|
+
super.onLayoutUpdated()
|
|
156
|
+
val paddingTop = mPaddingTop + mBorderTopWidth
|
|
157
|
+
val paddingBottom = mPaddingBottom + mBorderBottomWidth
|
|
158
|
+
val paddingLeft = mPaddingLeft + mBorderLeftWidth
|
|
159
|
+
val paddingRight = mPaddingRight + mBorderRightWidth
|
|
160
|
+
mView.setPadding(paddingLeft, paddingTop, paddingRight, paddingBottom)
|
|
161
|
+
}
|
|
162
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fontawesome-codepoints.d.ts","sourceRoot":"","sources":["../src/fontawesome-codepoints.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAmBzD,CAAA"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
export const FONTAWESOME_CODEPOINTS = {
|
|
2
|
+
search: '\uf002',
|
|
3
|
+
home: '\uf015',
|
|
4
|
+
bars: '\uf0c9',
|
|
5
|
+
'arrow-left': '\uf060',
|
|
6
|
+
xmark: '\uf00d',
|
|
7
|
+
close: '\uf00d',
|
|
8
|
+
plus: '\uf067',
|
|
9
|
+
minus: '\uf068',
|
|
10
|
+
cog: '\uf013',
|
|
11
|
+
user: '\uf007',
|
|
12
|
+
heart: '\uf004',
|
|
13
|
+
share: '\uf064',
|
|
14
|
+
trash: '\uf1f8',
|
|
15
|
+
pen: '\uf304',
|
|
16
|
+
check: '\uf00c',
|
|
17
|
+
info: '\uf129',
|
|
18
|
+
'exclamation-triangle': '\uf071',
|
|
19
|
+
'circle-xmark': '\uf057',
|
|
20
|
+
};
|
package/dist/fonts.css
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
@font-face {
|
|
2
|
+
font-family: 'Material Symbols Outlined';
|
|
3
|
+
src: url('../fonts/MaterialSymbolsOutlined.ttf') format('truetype');
|
|
4
|
+
font-weight: 100 700;
|
|
5
|
+
font-style: normal;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
@font-face {
|
|
9
|
+
font-family: 'Font Awesome 6 Free';
|
|
10
|
+
src: url('../fonts/fa-solid-900.ttf') format('truetype');
|
|
11
|
+
font-weight: 900;
|
|
12
|
+
font-style: normal;
|
|
13
|
+
}
|
package/dist/fonts.d.ts
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export declare const MATERIAL_SYMBOLS_URL = "https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/MaterialSymbolsOutlined%5BFILL%2CGRAD%2Copsz%2Cwght%5D.ttf";
|
|
2
|
+
export declare const MATERIAL_SYMBOLS_FAMILY = "Material Symbols Outlined";
|
|
3
|
+
export declare const MATERIAL_ICONS_URL = "https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/MaterialSymbolsOutlined%5BFILL%2CGRAD%2Copsz%2Cwght%5D.ttf";
|
|
4
|
+
export declare const MATERIAL_ICONS_FAMILY = "Material Symbols Outlined";
|
|
5
|
+
export declare const FONTAWESOME_SOLID_URL = "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/webfonts/fa-solid-900.ttf";
|
|
6
|
+
export declare const FONTAWESOME_SOLID_FAMILY = "Font Awesome 6 Free";
|
|
7
|
+
//# sourceMappingURL=fonts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fonts.d.ts","sourceRoot":"","sources":["../src/fonts.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,kJACgH,CAAA;AACjJ,eAAO,MAAM,uBAAuB,8BAA8B,CAAA;AAElE,eAAO,MAAM,kBAAkB,kJAAuB,CAAA;AACtD,eAAO,MAAM,qBAAqB,8BAA0B,CAAA;AAE5D,eAAO,MAAM,qBAAqB,wFACqD,CAAA;AACvF,eAAO,MAAM,wBAAwB,wBAAwB,CAAA"}
|
package/dist/fonts.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export const MATERIAL_SYMBOLS_URL = 'https://github.com/google/material-design-icons/raw/refs/heads/master/variablefont/MaterialSymbolsOutlined%5BFILL%2CGRAD%2Copsz%2Cwght%5D.ttf';
|
|
2
|
+
export const MATERIAL_SYMBOLS_FAMILY = 'Material Symbols Outlined';
|
|
3
|
+
export const MATERIAL_ICONS_URL = MATERIAL_SYMBOLS_URL;
|
|
4
|
+
export const MATERIAL_ICONS_FAMILY = MATERIAL_SYMBOLS_FAMILY;
|
|
5
|
+
export const FONTAWESOME_SOLID_URL = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.1/webfonts/fa-solid-900.ttf';
|
|
6
|
+
export const FONTAWESOME_SOLID_FAMILY = 'Font Awesome 6 Free';
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import type { ViewProps } from '@lynx-js/types';
|
|
2
|
+
export { MATERIAL_ICONS_URL, FONTAWESOME_SOLID_URL } from './fonts';
|
|
3
|
+
export { MATERIAL_CODEPOINTS } from './material-codepoints';
|
|
4
|
+
export interface TfontProps {
|
|
5
|
+
src: string;
|
|
6
|
+
family: string;
|
|
7
|
+
weight?: number;
|
|
8
|
+
style?: ViewProps['style'];
|
|
9
|
+
}
|
|
10
|
+
export type IconSet = 'material' | 'fontawesome' | 'fa';
|
|
11
|
+
export interface IconProps extends ViewProps {
|
|
12
|
+
name: string;
|
|
13
|
+
set?: IconSet;
|
|
14
|
+
size?: number;
|
|
15
|
+
color?: string;
|
|
16
|
+
}
|
|
17
|
+
export declare function Tfont(props: TfontProps): null;
|
|
18
|
+
export declare function Icon(props: IconProps): any;
|
|
19
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAA;AAE/C,OAAO,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,SAAS,CAAA;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAA;AAE3D,MAAM,WAAW,UAAU;IACzB,GAAG,EAAE,MAAM,CAAA;IACX,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,KAAK,CAAC,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;CAC3B;AAED,MAAM,MAAM,OAAO,GAAG,UAAU,GAAG,aAAa,GAAG,IAAI,CAAA;AAEvD,MAAM,WAAW,SAAU,SAAQ,SAAS;IAC1C,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAID,wBAAgB,KAAK,CAAC,KAAK,EAAE,UAAU,QAGtC;AAED,wBAAgB,IAAI,CAAC,KAAK,EAAE,SAAS,OAgBpC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { jsx as _jsx } from "@lynx-js/react/jsx-runtime";
|
|
2
|
+
export { MATERIAL_ICONS_URL, FONTAWESOME_SOLID_URL } from './fonts';
|
|
3
|
+
export { MATERIAL_CODEPOINTS } from './material-codepoints';
|
|
4
|
+
const px = (value) => `${Math.round(value)}px`;
|
|
5
|
+
export function Tfont(props) {
|
|
6
|
+
void props;
|
|
7
|
+
return null;
|
|
8
|
+
}
|
|
9
|
+
export function Icon(props) {
|
|
10
|
+
const { name, set = 'material', size = 24, color, style, ...rest } = props;
|
|
11
|
+
return (_jsx("icon", { icon: name, set: set, size: size, iconColor: color, style: {
|
|
12
|
+
width: px(size),
|
|
13
|
+
height: px(size),
|
|
14
|
+
...style,
|
|
15
|
+
}, ...rest }));
|
|
16
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"material-codepoints.d.ts","sourceRoot":"","sources":["../src/material-codepoints.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,mBAAmB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAuDtD,CAAA"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
export const MATERIAL_CODEPOINTS = {
|
|
2
|
+
// Navigation
|
|
3
|
+
home: '\ue9b2',
|
|
4
|
+
menu: '\ue5d2',
|
|
5
|
+
arrow_back: '\ue5c4',
|
|
6
|
+
arrow_back_ios: '\ue5e0',
|
|
7
|
+
arrow_forward: '\ue5c8',
|
|
8
|
+
chevron_left: '\ue5cb',
|
|
9
|
+
chevron_right: '\ue5cc',
|
|
10
|
+
expand_less: '\ue5ce',
|
|
11
|
+
expand_more: '\ue5cf',
|
|
12
|
+
close: '\ue5cd',
|
|
13
|
+
more_vert: '\ue5d4',
|
|
14
|
+
more_horiz: '\ue5d3',
|
|
15
|
+
// Actions
|
|
16
|
+
add: '\ue145',
|
|
17
|
+
check: '\ue5ca',
|
|
18
|
+
delete: '\ue92e',
|
|
19
|
+
edit: '\uf097',
|
|
20
|
+
search: '\ue8b6',
|
|
21
|
+
share: '\ue80d',
|
|
22
|
+
send: '\ue163',
|
|
23
|
+
download: '\uf090',
|
|
24
|
+
upload: '\uf09b',
|
|
25
|
+
refresh: '\ue5d5',
|
|
26
|
+
// Status / Info
|
|
27
|
+
info: '\ue88e',
|
|
28
|
+
warning: '\uf083',
|
|
29
|
+
error: '\uf8b6',
|
|
30
|
+
help: '\ue887',
|
|
31
|
+
// Social / Profile
|
|
32
|
+
person: '\uf0d3',
|
|
33
|
+
people: '\uea21',
|
|
34
|
+
favorite: '\ue87e',
|
|
35
|
+
star: '\uf8d7',
|
|
36
|
+
// Content
|
|
37
|
+
settings: '\ue8b8',
|
|
38
|
+
notifications: '\ue7f4',
|
|
39
|
+
link: '\ue250',
|
|
40
|
+
history: '\ue8b3',
|
|
41
|
+
// Network / Connectivity
|
|
42
|
+
wifi: '\ue63e',
|
|
43
|
+
wifi_find: '\ueb31',
|
|
44
|
+
bluetooth: '\ue1a7',
|
|
45
|
+
// Misc
|
|
46
|
+
lock: '\ue897',
|
|
47
|
+
lock_open: '\ue898',
|
|
48
|
+
visibility: '\ue8f4',
|
|
49
|
+
visibility_off: '\ue8f5',
|
|
50
|
+
calendar_today: '\ue935',
|
|
51
|
+
schedule: '\ue8b5',
|
|
52
|
+
location_on: '\ue0c8',
|
|
53
|
+
phone: '\ue0cd',
|
|
54
|
+
email: '\ue0be',
|
|
55
|
+
camera: '\ue3af',
|
|
56
|
+
};
|
package/dist/plugin.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../src/plugin.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AAqClD,wBAAgB,gBAAgB,IAAI,aAAa,CAUhD"}
|
package/dist/plugin.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import fs from 'fs';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { fileURLToPath } from 'url';
|
|
4
|
+
import { MATERIAL_ICONS_URL, FONTAWESOME_SOLID_URL } from './fonts';
|
|
5
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
6
|
+
async function fetchToBuffer(url) {
|
|
7
|
+
const res = await fetch(url);
|
|
8
|
+
if (!res.ok)
|
|
9
|
+
throw new Error(`Failed to fetch ${url}: ${res.status}`);
|
|
10
|
+
const arr = await res.arrayBuffer();
|
|
11
|
+
return Buffer.from(arr);
|
|
12
|
+
}
|
|
13
|
+
async function ensureFonts(pkgDir) {
|
|
14
|
+
const fontsDir = path.join(pkgDir, 'fonts');
|
|
15
|
+
fs.mkdirSync(fontsDir, { recursive: true });
|
|
16
|
+
const materialPath = path.join(fontsDir, 'MaterialSymbolsOutlined.ttf');
|
|
17
|
+
const faPath = path.join(fontsDir, 'fa-solid-900.ttf');
|
|
18
|
+
const cacheDir = path.join(pkgDir, '.cache', 'tamer-icons');
|
|
19
|
+
fs.mkdirSync(cacheDir, { recursive: true });
|
|
20
|
+
const materialCache = path.join(cacheDir, 'MaterialSymbolsOutlined.ttf');
|
|
21
|
+
const faCache = path.join(cacheDir, 'fa-solid-900.ttf');
|
|
22
|
+
if (!fs.existsSync(materialCache)) {
|
|
23
|
+
const buf = await fetchToBuffer(MATERIAL_ICONS_URL);
|
|
24
|
+
fs.writeFileSync(materialCache, buf);
|
|
25
|
+
}
|
|
26
|
+
fs.copyFileSync(materialCache, materialPath);
|
|
27
|
+
if (!fs.existsSync(faCache)) {
|
|
28
|
+
const buf = await fetchToBuffer(FONTAWESOME_SOLID_URL);
|
|
29
|
+
fs.writeFileSync(faCache, buf);
|
|
30
|
+
}
|
|
31
|
+
fs.copyFileSync(faCache, faPath);
|
|
32
|
+
}
|
|
33
|
+
export function pluginTamerIcons() {
|
|
34
|
+
return {
|
|
35
|
+
name: 'tamer-icons',
|
|
36
|
+
async setup(api) {
|
|
37
|
+
const pkgDir = path.resolve(__dirname, '..');
|
|
38
|
+
if (fs.existsSync(path.join(pkgDir, 'package.json'))) {
|
|
39
|
+
await ensureFonts(pkgDir);
|
|
40
|
+
}
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tamer.config.d.ts","sourceRoot":"","sources":["../src/tamer.config.ts"],"names":[],"mappings":";;;AAEA,wBAEC"}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|