1
1
import { Identifier , ItemStack } from 'deepslate'
2
- import type { ComponentChild } from 'preact'
3
- import { useEffect , useRef } from 'preact/hooks'
2
+ import type { ComponentChild , ComponentChildren } from 'preact'
3
+ import { useEffect , useRef , useState } from 'preact/hooks'
4
4
import { safeJsonParse } from '../../Utils.js'
5
5
import { ItemDisplay } from '../ItemDisplay.jsx'
6
6
import { TextComponent } from '../TextComponent.jsx'
@@ -46,7 +46,9 @@ function DialogTitle({ title }: { title: any }) {
46
46
// TODO: add warning button tooltip
47
47
return < div style = { `height: ${ px ( 33 ) } ; display: flex; gap: ${ px ( 10 ) } ; justify-content: center; align-items: center` } >
48
48
< TextComponent component = { title } />
49
- < div class = "dialog-warning-button" style = { `width: ${ px ( 20 ) } ; height: ${ px ( 20 ) } ;` } > </ div >
49
+ < WithTooltip tooltip = "This is a custom screen. Click here to learn more." >
50
+ < div class = "dialog-warning-button" style = { `width: ${ px ( 20 ) } ; height: ${ px ( 20 ) } ;` } > </ div >
51
+ </ WithTooltip >
50
52
</ div >
51
53
}
52
54
@@ -111,7 +113,7 @@ function DialogContent({ dialog }: { dialog: any }) {
111
113
if ( type === 'multi_action' ) {
112
114
return < ColumnsGrid columns = { dialog . columns ?? 2 } >
113
115
{ dialog . actions ?. map ( ( a : any ) =>
114
- < Button label = { a . label } width = { a . width ?? 150 } />
116
+ < Button label = { a . label } width = { a . width ?? 150 } tooltip = { a . tooltip } />
115
117
) ?? [ ] }
116
118
</ ColumnsGrid >
117
119
}
@@ -121,7 +123,7 @@ function DialogContent({ dialog }: { dialog: any }) {
121
123
{ dialog . inputs ?. map ( ( i : any ) => < InputControl input = { i } /> ) }
122
124
< ColumnsGrid columns = { 2 } >
123
125
{ dialog . actions ?. map ( ( a : any ) =>
124
- < Button label = { a . label } width = { a . width ?? 150 } />
126
+ < Button label = { a . label } width = { a . width ?? 150 } tooltip = { a . tooltip } />
125
127
) ?? [ ] }
126
128
</ ColumnsGrid >
127
129
</ >
@@ -150,8 +152,8 @@ function DialogFooter({ dialog }: { dialog: any }) {
150
152
151
153
if ( type === 'confirmation' ) {
152
154
return < div style = { `display: flex; gap: ${ px ( 8 ) } ; justify-content: center;` } >
153
- < Button label = { dialog . yes ?. label } width = { dialog . yes ?. width ?? 150 } />
154
- < Button label = { dialog . no ?. label } width = { dialog . no ?. width ?? 150 } />
155
+ < Button label = { dialog . yes ?. label } width = { dialog . yes ?. width ?? 150 } tooltip = { dialog . yes ?. tooltip } />
156
+ < Button label = { dialog . no ?. label } width = { dialog . no ?. width ?? 150 } tooltip = { dialog . no ?. tooltip } />
155
157
</ div >
156
158
}
157
159
@@ -165,7 +167,7 @@ function DialogFooter({ dialog }: { dialog: any }) {
165
167
166
168
if ( type === 'notice' ) {
167
169
return < div style = { `display: flex; gap: ${ px ( 8 ) } ; justify-content: center;` } >
168
- < Button label = { dialog . action ?. label ?? { translate : 'gui.ok' } } width = { dialog . action ?. width ?? 150 } />
170
+ < Button label = { dialog . action ?. label ?? { translate : 'gui.ok' } } width = { dialog . action ?. width ?? 150 } tooltip = { dialog . action ?. tooltip } />
169
171
</ div >
170
172
}
171
173
@@ -175,40 +177,13 @@ function DialogFooter({ dialog }: { dialog: any }) {
175
177
176
178
if ( type === 'simple_input_form' ) {
177
179
return < div style = { `display: flex; gap: ${ px ( 8 ) } ; justify-content: center;` } >
178
- < Button label = { dialog . action ?. label } width = { dialog . action ?. width ?? 150 } />
180
+ < Button label = { dialog . action ?. label } width = { dialog . action ?. width ?? 150 } tooltip = { dialog . action ?. tooltip } />
179
181
</ div >
180
182
}
181
183
182
184
return < > </ >
183
185
}
184
186
185
- interface ColumnsGridProps {
186
- columns : number
187
- children : ComponentChild [ ]
188
- }
189
- function ColumnsGrid ( { columns, children } : ColumnsGridProps ) {
190
- const totalCount = children . length
191
- const gridCount = Math . floor ( totalCount / columns ) * columns
192
- return < div style = { `padding-top: ${ px ( 4 ) } ; display: grid; grid-template-columns: repeat(${ columns } , minmax(0, 1fr)); gap: ${ px ( 2 ) } ; justify-content: center;` } >
193
- { children . slice ( 0 , gridCount ) }
194
- { totalCount > gridCount && < div style = { `grid-column: span ${ columns } ; display: flex; gap: ${ px ( 2 ) } ; justify-content: center; padding-top: ${ px ( 2 ) } /* MC-297977 */;` } >
195
- { children . slice ( gridCount ) }
196
- </ div > }
197
- </ div >
198
- }
199
-
200
- interface ButtonProps {
201
- label : any
202
- width : number
203
- tooltip ?: any
204
- }
205
- function Button ( { label, width } : ButtonProps ) {
206
- // TODO: add tooltip
207
- return < div class = "dialog-button" style = { `width: ${ px ( width ) } ; height: ${ px ( 20 ) } ;` } >
208
- < TextComponent component = { label } oneline />
209
- </ div >
210
- }
211
-
212
187
function InputControl ( { input } : { input : any } ) {
213
188
const type = input . type ?. replace ( / ^ m i n e c r a f t : / , '' )
214
189
@@ -249,6 +224,64 @@ function InputControl({ input }: { input: any }) {
249
224
return < > </ >
250
225
}
251
226
227
+ interface ColumnsGridProps {
228
+ columns : number
229
+ children : ComponentChild [ ]
230
+ }
231
+ function ColumnsGrid ( { columns, children } : ColumnsGridProps ) {
232
+ const totalCount = children . length
233
+ const gridCount = Math . floor ( totalCount / columns ) * columns
234
+ return < div style = { `padding-top: ${ px ( 4 ) } ; display: grid; grid-template-columns: repeat(${ columns } , minmax(0, 1fr)); gap: ${ px ( 2 ) } ; justify-content: center;` } >
235
+ { children . slice ( 0 , gridCount ) }
236
+ { totalCount > gridCount && < div style = { `grid-column: span ${ columns } ; display: flex; gap: ${ px ( 2 ) } ; justify-content: center; padding-top: ${ px ( 2 ) } /* MC-297977 */;` } >
237
+ { children . slice ( gridCount ) }
238
+ </ div > }
239
+ </ div >
240
+ }
241
+
242
+ interface ButtonProps {
243
+ label : any
244
+ width : number
245
+ tooltip ?: any
246
+ }
247
+ function Button ( { label, width, tooltip } : ButtonProps ) {
248
+ return < WithTooltip tooltip = { tooltip } >
249
+ < div class = "dialog-button" style = { `width: ${ px ( width ) } ; height: ${ px ( 20 ) } ;` } >
250
+ < TextComponent component = { label } oneline />
251
+ </ div >
252
+ </ WithTooltip >
253
+ }
254
+
255
+ interface WithTooltipProps {
256
+ tooltip ?: any
257
+ children : ComponentChildren
258
+ }
259
+ function WithTooltip ( { tooltip, children } : WithTooltipProps ) {
260
+ if ( ! tooltip ) {
261
+ return < > { children } </ >
262
+ }
263
+
264
+ const el = useRef < HTMLDivElement > ( null )
265
+ const [ tooltipOffset , setTooltipOffset ] = useState < [ number , number ] > ( [ 0 , 0 ] )
266
+
267
+ useEffect ( ( ) => {
268
+ const onMove = ( e : MouseEvent ) => {
269
+ requestAnimationFrame ( ( ) => {
270
+ setTooltipOffset ( [ e . offsetX + 20 , e . offsetY - 10 ] )
271
+ } )
272
+ }
273
+ el . current ?. addEventListener ( 'mousemove' , onMove )
274
+ return ( ) => el . current ?. removeEventListener ( 'mousemove' , onMove )
275
+ } , [ ] )
276
+
277
+ return < div ref = { el } class = "tooltip-container" >
278
+ { children }
279
+ { < div class = "dialog-tooltip" style = { `left: ${ tooltipOffset [ 0 ] } px; top: ${ tooltipOffset [ 1 ] } px;` } >
280
+ < TextComponent component = { tooltip } />
281
+ </ div > }
282
+ </ div >
283
+ }
284
+
252
285
function px ( n : number ) {
253
286
return `calc(var(--dialog-px) * ${ n } )`
254
287
}
0 commit comments