@vue-lynx-example/css-features 0.2.2 → 0.2.4
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/package.json +2 -2
- package/src/App.vue +6 -2
- package/src/VBindCSS.vue +150 -28
- package/src/VBindThreads.vue +129 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue-lynx-example/css-features",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Vue-Lynx CSS features demo — scoped, modules, v-bind()",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
"directory": "examples/css-features"
|
|
18
18
|
},
|
|
19
19
|
"dependencies": {
|
|
20
|
-
"vue-lynx": "0.
|
|
20
|
+
"vue-lynx": "0.3.1"
|
|
21
21
|
},
|
|
22
22
|
"devDependencies": {
|
|
23
23
|
"@lynx-js/rspeedy": "^0.13.5",
|
package/src/App.vue
CHANGED
|
@@ -3,6 +3,7 @@ import PlainStyle from './PlainStyle.vue'
|
|
|
3
3
|
import ScopedStyle from './ScopedStyle.vue'
|
|
4
4
|
import CSSModules from './CSSModules.vue'
|
|
5
5
|
import VBindCSS from './VBindCSS.vue'
|
|
6
|
+
import VBindThreads from './VBindThreads.vue'
|
|
6
7
|
import CSSVarsWorkaround from './CSSVarsWorkaround.vue'
|
|
7
8
|
import ImportedCSS from './ImportedCSS.vue'
|
|
8
9
|
</script>
|
|
@@ -19,15 +20,18 @@ import ImportedCSS from './ImportedCSS.vue'
|
|
|
19
20
|
<!-- 1. Plain <style> — WORKS -->
|
|
20
21
|
<PlainStyle />
|
|
21
22
|
|
|
22
|
-
<!--
|
|
23
|
+
<!-- 2a. <style scoped> — DOES NOT WORK -->
|
|
23
24
|
<ScopedStyle />
|
|
24
25
|
|
|
25
26
|
<!-- 3. <style module> — SHOULD WORK -->
|
|
26
27
|
<CSSModules />
|
|
27
28
|
|
|
28
|
-
<!-- 4. v-bind() in CSS —
|
|
29
|
+
<!-- 4. v-bind() in CSS — WORKS (useCssVars implemented in vue-lynx) -->
|
|
29
30
|
<VBindCSS />
|
|
30
31
|
|
|
32
|
+
<!-- 4b. v-bind() thread comparison — BG (useCssVars) vs MT (setStyleProperty) -->
|
|
33
|
+
<VBindThreads />
|
|
34
|
+
|
|
31
35
|
<!-- 5. Workaround: Reactive inline :style -->
|
|
32
36
|
<CSSVarsWorkaround />
|
|
33
37
|
|
package/src/VBindCSS.vue
CHANGED
|
@@ -1,44 +1,166 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
2
|
+
import { ref, computed } from 'vue'
|
|
3
|
+
|
|
4
|
+
const textColor = ref('#1565c0')
|
|
5
|
+
const bgColor = ref('#e3f2fd')
|
|
6
|
+
const fontSize = ref('14px')
|
|
7
|
+
const opacity = ref(1)
|
|
8
|
+
const borderStyle = ref({ color: '#1565c0' })
|
|
9
|
+
|
|
10
|
+
const invertedColor = computed(() => {
|
|
11
|
+
const map: Record<string, string> = {
|
|
12
|
+
'#1565c0': '#f57f17',
|
|
13
|
+
'#c62828': '#2e7d32',
|
|
14
|
+
'#2e7d32': '#c62828',
|
|
15
|
+
'#f57f17': '#1565c0',
|
|
16
|
+
}
|
|
17
|
+
return map[textColor.value] ?? textColor.value
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
function cycleColor() {
|
|
21
|
+
const colors = ['#1565c0', '#c62828', '#2e7d32', '#f57f17']
|
|
22
|
+
const idx = colors.indexOf(textColor.value)
|
|
23
|
+
textColor.value = colors[(idx + 1) % colors.length]
|
|
24
|
+
const bgs = ['#e3f2fd', '#ffebee', '#e8f5e9', '#fffde7']
|
|
25
|
+
bgColor.value = bgs[(idx + 1) % bgs.length]
|
|
26
|
+
borderStyle.value = { color: colors[(idx + 1) % colors.length] }
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
function cycleFontSize() {
|
|
30
|
+
const sizes = ['12px', '14px', '16px', '20px']
|
|
31
|
+
const idx = sizes.indexOf(fontSize.value)
|
|
32
|
+
fontSize.value = sizes[(idx + 1) % sizes.length]
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function cycleOpacity() {
|
|
36
|
+
const steps = [1, 0.7, 0.4, 0.1]
|
|
37
|
+
const idx = steps.indexOf(opacity.value)
|
|
38
|
+
opacity.value = steps[(idx + 1) % steps.length]
|
|
39
|
+
}
|
|
21
40
|
</script>
|
|
22
41
|
|
|
23
42
|
<template>
|
|
24
43
|
<view :style="{
|
|
25
44
|
display: 'flex',
|
|
26
45
|
flexDirection: 'column',
|
|
27
|
-
backgroundColor:
|
|
46
|
+
backgroundColor: bgColor,
|
|
28
47
|
padding: '12px',
|
|
29
48
|
borderRadius: '8px',
|
|
30
49
|
marginBottom: '12px',
|
|
31
50
|
}">
|
|
32
|
-
<text :style="{ fontSize: '15px', fontWeight: 'bold',
|
|
33
|
-
v-bind() in <style> —
|
|
51
|
+
<text :style="{ fontSize: '15px', fontWeight: 'bold', marginBottom: '4px' }" class="title">
|
|
52
|
+
v-bind() in <style> — WORKS
|
|
53
|
+
</text>
|
|
54
|
+
<text class="description">
|
|
55
|
+
textColor: {{ textColor }} | fontSize: {{ fontSize }} | opacity: {{ opacity }}
|
|
56
|
+
</text>
|
|
57
|
+
|
|
58
|
+
<!-- ref binding -->
|
|
59
|
+
<text class="sample-text" :style="{ fontSize }">
|
|
60
|
+
ref — color: v-bind(textColor)
|
|
61
|
+
</text>
|
|
62
|
+
|
|
63
|
+
<!-- computed binding -->
|
|
64
|
+
<text class="computed-text" :style="{ fontSize }">
|
|
65
|
+
computed — inverted color
|
|
66
|
+
</text>
|
|
67
|
+
|
|
68
|
+
<!-- object property binding: v-bind('obj.prop') -->
|
|
69
|
+
<text class="border-text">
|
|
70
|
+
object prop — v-bind('borderStyle.color')
|
|
34
71
|
</text>
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
72
|
+
|
|
73
|
+
<!-- opacity binding -->
|
|
74
|
+
<text class="opacity-text">
|
|
75
|
+
opacity — v-bind(opacity)
|
|
39
76
|
</text>
|
|
40
|
-
|
|
41
|
-
|
|
77
|
+
|
|
78
|
+
<!-- CSS custom property via v-bind -->
|
|
79
|
+
<text class="var-text">
|
|
80
|
+
CSS var — --accent: v-bind(textColor)
|
|
42
81
|
</text>
|
|
82
|
+
|
|
83
|
+
<view :style="{ display: 'flex', flexDirection: 'row', gap: '8px', marginTop: '8px', flexWrap: 'wrap' }">
|
|
84
|
+
<text
|
|
85
|
+
:style="{
|
|
86
|
+
backgroundColor: '#1565c0',
|
|
87
|
+
color: '#fff',
|
|
88
|
+
padding: '6px 12px',
|
|
89
|
+
borderRadius: '4px',
|
|
90
|
+
fontSize: '12px',
|
|
91
|
+
}"
|
|
92
|
+
:bindtap="cycleColor"
|
|
93
|
+
>
|
|
94
|
+
Cycle Color
|
|
95
|
+
</text>
|
|
96
|
+
<text
|
|
97
|
+
:style="{
|
|
98
|
+
backgroundColor: '#2e7d32',
|
|
99
|
+
color: '#fff',
|
|
100
|
+
padding: '6px 12px',
|
|
101
|
+
borderRadius: '4px',
|
|
102
|
+
fontSize: '12px',
|
|
103
|
+
}"
|
|
104
|
+
:bindtap="cycleFontSize"
|
|
105
|
+
>
|
|
106
|
+
Cycle Size
|
|
107
|
+
</text>
|
|
108
|
+
<text
|
|
109
|
+
:style="{
|
|
110
|
+
backgroundColor: '#6a1b9a',
|
|
111
|
+
color: '#fff',
|
|
112
|
+
padding: '6px 12px',
|
|
113
|
+
borderRadius: '4px',
|
|
114
|
+
fontSize: '12px',
|
|
115
|
+
}"
|
|
116
|
+
:bindtap="cycleOpacity"
|
|
117
|
+
>
|
|
118
|
+
Cycle Opacity
|
|
119
|
+
</text>
|
|
120
|
+
</view>
|
|
43
121
|
</view>
|
|
44
122
|
</template>
|
|
123
|
+
|
|
124
|
+
<style>
|
|
125
|
+
.title {
|
|
126
|
+
color: v-bind(textColor);
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
.description {
|
|
130
|
+
font-size: 11px;
|
|
131
|
+
color: #555;
|
|
132
|
+
margin-bottom: 8px;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
.sample-text {
|
|
136
|
+
color: v-bind(textColor);
|
|
137
|
+
font-weight: bold;
|
|
138
|
+
margin-bottom: 4px;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
.computed-text {
|
|
142
|
+
color: v-bind(invertedColor);
|
|
143
|
+
font-weight: bold;
|
|
144
|
+
margin-bottom: 4px;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
.border-text {
|
|
148
|
+
color: v-bind('borderStyle.color');
|
|
149
|
+
font-weight: bold;
|
|
150
|
+
margin-bottom: 4px;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
.opacity-text {
|
|
154
|
+
color: v-bind(textColor);
|
|
155
|
+
opacity: v-bind(opacity);
|
|
156
|
+
font-weight: bold;
|
|
157
|
+
margin-bottom: 4px;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
.var-text {
|
|
161
|
+
--accent: v-bind(textColor);
|
|
162
|
+
color: var(--accent);
|
|
163
|
+
font-weight: bold;
|
|
164
|
+
margin-bottom: 8px;
|
|
165
|
+
}
|
|
166
|
+
</style>
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
<script setup lang="ts">
|
|
2
|
+
// VBindThreads — audits both style-update paths:
|
|
3
|
+
//
|
|
4
|
+
// LEFT (Background Thread)
|
|
5
|
+
// tap → BG JS handler → reactive ref → useCssVars → SET_STYLE op → MT applies CSS var
|
|
6
|
+
//
|
|
7
|
+
// RIGHT (Main Thread)
|
|
8
|
+
// tap → MT worklet → setStyleProperty() directly (no ops round-trip)
|
|
9
|
+
// + runOnBackground(incrementMtCount) to sync tap count for display
|
|
10
|
+
|
|
11
|
+
import { ref, watch } from 'vue'
|
|
12
|
+
import { useMainThreadRef, runOnBackground, runOnMainThread } from 'vue-lynx'
|
|
13
|
+
|
|
14
|
+
const COLORS = ['#1565c0', '#c62828', '#2e7d32', '#f57f17', '#6a1b9a']
|
|
15
|
+
|
|
16
|
+
// --- Background thread ---
|
|
17
|
+
const bgColorIdx = ref(0)
|
|
18
|
+
const bgColor = ref(COLORS[0]!)
|
|
19
|
+
const bgTapCount = ref(0)
|
|
20
|
+
|
|
21
|
+
function onBgTap() {
|
|
22
|
+
bgTapCount.value++
|
|
23
|
+
bgColorIdx.value = (bgColorIdx.value + 1) % COLORS.length
|
|
24
|
+
bgColor.value = COLORS[bgColorIdx.value]!
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
// --- Main thread ---
|
|
28
|
+
const mtBoxRef = useMainThreadRef(null)
|
|
29
|
+
const mtTapCount = ref(0)
|
|
30
|
+
|
|
31
|
+
// Incremented on BG by runOnBackground() from the MT tap handler
|
|
32
|
+
function incrementMtCount() {
|
|
33
|
+
mtTapCount.value++
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
// MT-local index — lives in MT JS context, not shared with BG reactive state.
|
|
37
|
+
// Captured by the SWC worklet transform into _c.
|
|
38
|
+
let mtColorIdx = 0
|
|
39
|
+
|
|
40
|
+
const onMtTap = () => {
|
|
41
|
+
'main thread'
|
|
42
|
+
// Cycle color directly on MT — no round-trip through BG
|
|
43
|
+
mtColorIdx = (mtColorIdx + 1) % COLORS.length
|
|
44
|
+
const el = (mtBoxRef as unknown as {
|
|
45
|
+
current?: { setStyleProperty?(k: string, v: string): void }
|
|
46
|
+
}).current
|
|
47
|
+
el?.setStyleProperty?.('background-color', COLORS[mtColorIdx]!)
|
|
48
|
+
|
|
49
|
+
// Sync tap count back to BG for display only
|
|
50
|
+
runOnBackground(incrementMtCount)()
|
|
51
|
+
}
|
|
52
|
+
</script>
|
|
53
|
+
|
|
54
|
+
<template>
|
|
55
|
+
<view :style="{
|
|
56
|
+
display: 'flex',
|
|
57
|
+
flexDirection: 'column',
|
|
58
|
+
backgroundColor: '#f3e5f5',
|
|
59
|
+
padding: '12px',
|
|
60
|
+
borderRadius: '8px',
|
|
61
|
+
marginBottom: '12px',
|
|
62
|
+
}">
|
|
63
|
+
<text :style="{ fontSize: '15px', fontWeight: 'bold', marginBottom: '4px', color: '#4a148c' }">
|
|
64
|
+
Thread comparison — style updates
|
|
65
|
+
</text>
|
|
66
|
+
<text :style="{ fontSize: '11px', color: '#555', marginBottom: '10px' }">
|
|
67
|
+
Both boxes cycle colors on tap. BG path uses v-bind() in CSS; MT path calls setStyleProperty() directly.
|
|
68
|
+
</text>
|
|
69
|
+
|
|
70
|
+
<view :style="{ display: 'flex', flexDirection: 'row', gap: '12px' }">
|
|
71
|
+
<!-- Background thread box -->
|
|
72
|
+
<view :style="{ flex: 1 }">
|
|
73
|
+
<text :style="{ fontSize: '11px', color: '#555', marginBottom: '4px', textAlign: 'center' }">
|
|
74
|
+
Background thread
|
|
75
|
+
</text>
|
|
76
|
+
<view
|
|
77
|
+
class="bg-box"
|
|
78
|
+
:bindtap="onBgTap"
|
|
79
|
+
:style="{
|
|
80
|
+
display: 'flex',
|
|
81
|
+
alignItems: 'center',
|
|
82
|
+
justifyContent: 'center',
|
|
83
|
+
height: '80px',
|
|
84
|
+
borderRadius: '8px',
|
|
85
|
+
}"
|
|
86
|
+
>
|
|
87
|
+
<text :style="{ fontSize: '12px', color: '#fff', fontWeight: 'bold' }">
|
|
88
|
+
Taps: {{ bgTapCount }}
|
|
89
|
+
</text>
|
|
90
|
+
</view>
|
|
91
|
+
<text :style="{ fontSize: '10px', color: '#888', marginTop: '4px', textAlign: 'center' }">
|
|
92
|
+
v-bind(bgColor) in CSS
|
|
93
|
+
</text>
|
|
94
|
+
</view>
|
|
95
|
+
|
|
96
|
+
<!-- Main thread box -->
|
|
97
|
+
<view :style="{ flex: 1 }">
|
|
98
|
+
<text :style="{ fontSize: '11px', color: '#555', marginBottom: '4px', textAlign: 'center' }">
|
|
99
|
+
Main thread
|
|
100
|
+
</text>
|
|
101
|
+
<view
|
|
102
|
+
:main-thread-ref="mtBoxRef"
|
|
103
|
+
:main-thread-bindtap="onMtTap"
|
|
104
|
+
:style="{
|
|
105
|
+
display: 'flex',
|
|
106
|
+
alignItems: 'center',
|
|
107
|
+
justifyContent: 'center',
|
|
108
|
+
height: '80px',
|
|
109
|
+
borderRadius: '8px',
|
|
110
|
+
backgroundColor: '#1565c0',
|
|
111
|
+
}"
|
|
112
|
+
>
|
|
113
|
+
<text :style="{ fontSize: '12px', color: '#fff', fontWeight: 'bold' }">
|
|
114
|
+
Taps: {{ mtTapCount }}
|
|
115
|
+
</text>
|
|
116
|
+
</view>
|
|
117
|
+
<text :style="{ fontSize: '10px', color: '#888', marginTop: '4px', textAlign: 'center' }">
|
|
118
|
+
setStyleProperty() on MT
|
|
119
|
+
</text>
|
|
120
|
+
</view>
|
|
121
|
+
</view>
|
|
122
|
+
</view>
|
|
123
|
+
</template>
|
|
124
|
+
|
|
125
|
+
<style>
|
|
126
|
+
.bg-box {
|
|
127
|
+
background-color: v-bind(bgColor);
|
|
128
|
+
}
|
|
129
|
+
</style>
|