Page Menu
Home
Sealhub
Search
Configure Global Search
Log In
Files
F969617
components.sreact.tsx
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
6 KB
Referenced Files
None
Subscribers
None
components.sreact.tsx
View Options
import
{
render
,
renderEarlyAssets
}
from
"@sealcode/jdd"
;
import
{
StatefulPage
}
from
"@sealcode/sealgen"
;
import
{
hasShape
,
predicates
}
from
"@sealcode/ts-predicates"
;
import
type
{
BaseContext
}
from
"koa"
;
import
type
{
Templatable
}
from
"tempstream"
;
import
{
tempstream
,
TempstreamJSX
}
from
"tempstream"
;
import
html
,
{
defaultHead
}
from
"../html.js"
;
import
{
registry
}
from
"../jdd-components/components.js"
;
import
{
makeJDDContext
}
from
"../jdd-context.js"
;
import
{
ComponentInput
}
from
"./component-preview/component-input.js"
;
import
{
ComponentPreviewActions
}
from
"./component-preview/component-preview-actions.js"
;
export
const
actionName
=
"Components"
;
export
type
ComponentPreviewState
=
{
component
:
string
;
component_args
:
Record
<
string
,
unknown
>
;
current_size
?:
string
;
};
export
default
new
(
class
ComponentsPage
extends
StatefulPage
<
ComponentPreviewState
,
typeof
ComponentPreviewActions
>
{
actions
=
ComponentPreviewActions
;
async
getInitialState
(
ctx
:
BaseContext
)
{
const
[
component_name
,
component
]
=
Object
.
entries
(
registry
.
getAll
())[
0
];
const
initial_state
=
{
component
:
component_name
,
component_args
:
await
component
.
getExampleValues
(
makeJDDContext
(
ctx
)),
};
return
initial_state
;
}
async
serializeState
(
ctx
:
BaseContext
,
state
:
ComponentPreviewState
)
{
const
component
=
registry
.
get
(
state
.
component
);
const
result
=
JSON
.
stringify
({
...
state
,
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
component_args
:
component
?
await
component
.
convertParsedToStorage
(
makeJDDContext
(
ctx
),
state
.
component_args
)
:
{},
});
return
result
;
}
async
deserializeState
(
ctx
:
BaseContext
,
state_string
:
string
)
{
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const
raw
=
JSON
.
parse
(
state_string
);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions, @typescript-eslint/no-unsafe-member-access
const
component
=
registry
.
get
(
raw
.
component
as
string
);
// eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
const
result
=
{
...
raw
,
// eslint-disable-next-line @typescript-eslint/no-unsafe-call
component_args
:
component
?
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
await
component
.
convertStorageToParsed
(
makeJDDContext
(
ctx
),
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/no-unsafe-member-access
raw
.
component_args
||
{}
)
:
{},
};
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return
result
as
ComponentPreviewState
;
}
wrapInLayout
(
ctx
:
BaseContext
,
content
:
Templatable
,
state
:
ComponentPreviewState
)
:
Templatable
{
return
html
(
ctx
,
"Components"
,
content
,
{
morphing
:
true
,
preserveScroll
:
true
,
autoRefreshCSS
:
true
,
navbar
:
()
=>
``
,
},
(...
args
)
=>
tempstream
`
${
defaultHead
(...
args
)
}${
renderEarlyAssets
(
registry
,
[
{
component_name
:
state
.
component
,
args
:
state
.
component_args
,
}
,
],
makeJDDContext(ctx)
)}`
);
}
async
preprocessOverrides
(
ctx
:
BaseContext
,
state
:
ComponentPreviewState
,
overrides
:
Record
<
string
,
unknown
>
)
{
const
jdd_context
=
makeJDDContext
(
ctx
);
const
component_name
=
state
.
component
;
if
(
!
component_name
)
{
throw
new
Error
(
"Unspecified component name"
);
}
const
component
=
registry
.
get
(
component_name
);
if
(
!
component
)
{
throw
new
Error
(
`Unknown component:
${
component_name
}
`
);
}
if
(
!
hasShape
({
component_args
:
predicates
.
object
},
overrides
))
{
return
overrides
;
}
const
promises
=
Object
.
entries
(
component
.
getArguments
()).
map
(
async
([
arg_name
,
arg
])
=>
{
const
value
=
overrides
.
component_args
[
arg_name
];
if
(
value
)
{
const
new_value
=
await
arg
.
receivedToParsed
(
jdd_context
,
value
);
overrides
.
component_args
[
arg_name
]
=
new_value
;
}
}
);
await
Promise
.
all
(
promises
);
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
return
overrides
;
}
containerSizes
=
[
"320"
,
"600"
,
"800"
,
"1024"
,
"1300"
,
"1920"
];
render
(
ctx
:
BaseContext
,
state
:
ComponentPreviewState
)
{
const
jdd_context
=
makeJDDContext
(
ctx
);
const
all_components
=
registry
.
getAll
();
const
component
=
registry
.
get
(
state
.
component
)
||
Object
.
values
(
all_components
)[
0
];
return
(
<
div
class
=
"two-column"
id
=
"component-debugger"
style
=
"--resizable-column-width: 50vw"
data
-
controller
=
"component-debugger"
>
<
div
class
=
"component-arguments"
>
{
/*The below button has to be here in order for it to be the default behavior */
}
<
input
type
=
"submit"
value
=
"Preview"
/>
<
select
name
=
"component"
onchange
=
{
this
.
makeActionCallback
(
"change_component"
)}
autocomplete
=
"off"
>
{
Object
.
entries
(
all_components
).
map
(([
name
])
=>
(
<
option
value
=
{
name
}
selected
=
{
name
==
state
.
component
}
>
{
name
}
<
/option>
))}
<
/select>
{
this
.
makeActionButton
(
state
,
"randomize_args"
)}
<
fieldset
class
=
"component-preview-parameters"
>
<
legend
>
Parameters
<
/legend>
{
Object
.
entries
(
component
.
getArguments
()).
map
(
async
([
arg_name
,
arg
])
=>
(
<
ComponentInput
{...{
state
,
ctx
,
arg_path
:
[
arg_name
],
arg
,
value
:
state
.
component_args
[
arg_name
]
===
undefined
?
await
arg
.
getExampleValue
(
jdd_context
)
:
state
.
component_args
[
arg_name
],
onblur
:
this
.
rerender
(),
page
:
this
,
}}
/>
)
)}
<
input
type
=
"submit"
value
=
"Preview"
/>
<
/fieldset>
<
code
>
{
this
.
serializeState
(
ctx
,
state
)}
<
/code>
<
/div>
<
div
class
=
"resize-gutter"
data
-
component
-
debugger
-
target
=
"gutter"
><
/div>
<
div
class
=
"component-preview"
data
-
component
-
debugger
-
target
=
"preview"
>
<
fieldset
>
<
legend
>
Preview
{
" "
}
<
span
data
-
component
-
debugger
-
target
=
"component-width"
><
/span>
<
select
name
=
"size"
autocomplete
=
"off"
class
=
"component-preview-size-select"
data
-
component
-
debugger
-
target
=
"size-select"
data
-
action
=
"change->component-debugger#handleWidthDropdown"
>
{
this
.
containerSizes
.
map
((
size
)
=>
(
<
option
value
=
{
size
}
selected
=
{
size
===
(
state
.
current_size
||
"800"
)}
>
{
`
${
size
}
px`
}
<
/option>
))}
<
/select>
<
noscript
>
{
this
.
makeActionButton
(
state
,
"change_size"
)}
<
/noscript>
<
/legend>
{
render
(
registry
,
[
{
component_name
:
state
.
component
,
args
:
state
.
component_args
,
},
],
jdd_context
)}
<
/fieldset>
{
/* HTML */
`<script>
(function () {
const gutter = document.querySelector(".resize-gutter");
})();
</script>`
}
<
/div>
<
/div>
);
}
})();
File Metadata
Details
Attached
Mime Type
text/x-java
Expires
Sat, Nov 23, 07:15 (1 d, 18 h)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
547919
Default Alt Text
components.sreact.tsx (6 KB)
Attached To
Mode
rPHOTOAPP photo-app-demo
Attached
Detach File
Event Timeline
Log In to Comment