11import { Identifier , ItemStack } from 'deepslate'
22import type { ComponentChild , ComponentChildren } from 'preact'
33import { useEffect , useRef , useState } from 'preact/hooks'
4- import { safeJsonParse } from '../../Utils.js'
4+ import { clamp , safeJsonParse } from '../../Utils.js'
55import { ItemDisplay } from '../ItemDisplay.jsx'
66import { TextComponent } from '../TextComponent.jsx'
77import type { PreviewProps } from './index.js'
@@ -62,22 +62,20 @@ function DialogBody({ body }: { body: any }) {
6262 { body ?. map ( ( b : any ) => {
6363 const type = b . type ?. replace ( / ^ m i n e c r a f t : / , '' )
6464 if ( type === 'plain_message' ) {
65- // TODO: make this text wrap
66- return < div style = { `max-width: ${ px ( b . width ?? 200 ) } ; padding: ${ px ( 4 ) } ` } >
65+ return < div class = "dialog-body" style = { `max-width: ${ px ( clamp ( b . width ?? 200 , 1 , 1024 ) ) } ; padding: ${ px ( 4 ) } ` } >
6766 < TextComponent component = { b . contents } />
6867 </ div >
6968 }
7069 if ( type == 'item' ) {
7170 // TODO: add item components
7271 const item = new ItemStack ( Identifier . parse ( b . item ?. id ?? 'air' ) , b . show_decorations ? ( b . item ?. count ?? 1 ) : 1 )
73- console . log ( item )
7472 return < div style = { `display: flex; gap: ${ px ( 2 ) } ; align-items: center; gap: ${ px ( 4 ) } ` } >
75- < div style = { `width: ${ px ( b . width ?? 16 ) } ; height: ${ px ( b . height ?? 16 ) } ` } >
73+ < div style = { `width: ${ px ( clamp ( b . width ?? 16 , 1 , 256 ) ) } ; height: ${ px ( clamp ( b . height ?? 16 , 1 , 256 ) ) } ` } >
7674 < div style = { `width: ${ px ( 16 ) } ; height: ${ px ( 16 ) } ` } >
7775 < ItemDisplay item = { item } tooltip = { b . show_tooltip ?? true } />
7876 </ div >
7977 </ div >
80- { b . description && < div style = { `max-width: ${ px ( b . description . width ?? 200 ) } ;` } >
78+ { b . description && < div style = { `max-width: ${ px ( clamp ( b . description . width ?? 200 , 1 , 1024 ) ) } ;` } >
8179 < TextComponent component = { b . description . contents } />
8280 </ div > }
8381 </ div >
@@ -121,7 +119,7 @@ function DialogContent({ dialog }: { dialog: any }) {
121119 if ( type === 'multi_action_input_form' ) {
122120 return < >
123121 { dialog . inputs ?. map ( ( i : any ) => < InputControl input = { i } /> ) }
124- < ColumnsGrid columns = { 2 } >
122+ < ColumnsGrid columns = { dialog . columns ?? 2 } >
125123 { dialog . actions ?. map ( ( a : any ) =>
126124 < Button label = { a . label } width = { a . width ?? 150 } tooltip = { a . tooltip } />
127125 ) ?? [ ] }
@@ -186,6 +184,7 @@ function DialogFooter({ dialog }: { dialog: any }) {
186184
187185function InputControl ( { input } : { input : any } ) {
188186 const type = input . type ?. replace ( / ^ m i n e c r a f t : / , '' )
187+ // TODO: make interactive
189188
190189 if ( type === 'boolean' ) {
191190 return < div style = { `display: flex; gap: ${ px ( 4 ) } ; align-items: center;` } >
@@ -195,8 +194,9 @@ function InputControl({ input }: { input: any }) {
195194 }
196195
197196 if ( type === 'number_range' ) {
198- const label = { translate : input . label_format ?? 'options.generic_value' , with : [ input . label ?? '' , input . start ?? 0 ] }
199- return < div class = "dialog-slider" style = { `width: ${ px ( input . width ?? 200 ) } ; height: ${ px ( 20 ) } ;` } >
197+ const initial = input . initial ?? ( ( ( input . start ?? 0 ) + ( input . end ?? 0 ) ) / 2 )
198+ const label = { translate : input . label_format ?? 'options.generic_value' , with : [ input . label ?? '' , initial ] }
199+ return < div class = "dialog-slider" style = { `width: ${ px ( clamp ( input . width ?? 200 , 1 , 1024 ) ) } ; height: ${ px ( 20 ) } ;` } >
200200 < div class = "dialog-slider-track" > </ div >
201201 < div class = "dialog-slider-handle" > </ div >
202202 < div class = "dialog-slider-text" >
@@ -209,13 +209,18 @@ function InputControl({ input }: { input: any }) {
209209 const initial = input . options ?. find ( ( o : any ) => o . initial ) ?? input . options ?. [ 0 ]
210210 const initialLabel = typeof initial === 'string' ? initial : initial ?. display ?? initial ?. id ?? ''
211211 const label = input . label_visible === false ? initialLabel : { translate : 'options.generic_value' , with : [ input . label ?? '' , initialLabel ] }
212- return < Button label = { label } width = { input . width ?? 200 } />
212+ return < Button label = { label } width = { clamp ( input . width ?? 200 , 1 , 1024 ) } />
213213 }
214214
215215 if ( type === 'text' ) {
216+ const height = input . multiline
217+ ? ( input . multiline . height
218+ ? clamp ( input . multiline . height , 1 , 512 )
219+ : ( 9 * Math . max ( input . multiline . max_lines ?? 4 , 1 ) + 8 ) )
220+ : 20
216221 return < div style = { `display: flex; flex-direction: column; gap: ${ px ( 4 ) } ;` } >
217222 { input . label_visible !== false && < TextComponent component = { input . label } /> }
218- < div class = "dialog-edit-box" style = { `width: ${ px ( input . width ?? 200 ) } ; height: ${ px ( 20 ) } ;` } >
223+ < div class = "dialog-edit-box" style = { `width: ${ px ( clamp ( input . width ?? 200 , 1 , 1024 ) ) } ; height: ${ px ( height ) } ;` } >
219224 { input . initial && < TextComponent component = { input . initial } /> }
220225 </ div >
221226 </ div >
@@ -233,7 +238,7 @@ function ColumnsGrid({ columns, children }: ColumnsGridProps) {
233238 const gridCount = Math . floor ( totalCount / columns ) * columns
234239 return < div style = { `padding-top: ${ px ( 4 ) } ; display: grid; grid-template-columns: repeat(${ columns } , minmax(0, 1fr)); gap: ${ px ( 2 ) } ; justify-content: center;` } >
235240 { 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 */; ` } >
241+ { totalCount > gridCount && < div style = { `grid-column: span ${ columns } ; display: flex; gap: ${ px ( 2 ) } ; justify-content: center;` } >
237242 { children . slice ( gridCount ) }
238243 </ div > }
239244 </ div >
@@ -246,7 +251,7 @@ interface ButtonProps {
246251}
247252function Button ( { label, width, tooltip } : ButtonProps ) {
248253 return < WithTooltip tooltip = { tooltip } >
249- < div class = "dialog-button" style = { `width: ${ px ( width ) } ; height: ${ px ( 20 ) } ;` } >
254+ < div class = "dialog-button" style = { `width: ${ px ( clamp ( width , 1 , 1024 ) ) } ; height: ${ px ( 20 ) } ;` } >
250255 < TextComponent component = { label } oneline />
251256 </ div >
252257 </ WithTooltip >
0 commit comments