Open daKmoR opened 2 years ago
this get's quite complicated... maybe use a "full" configuration? š¤
```js client
console.log('just execute');
export const foo = () => html`<p>render the p</p>`;
export const bar = () => html`<p>render the p AND the highlighted code block</p>`;
export const baz = () => html`<p>render the p AND the highlighted code block OPENED within a FRAME</p>`;
follow-up to the discussion https://github.com/modernweb-dev/rocket/discussions/288
my use cases extend the proposal above with the following:
<style>
blocks)js script
with the only difference: shown highlighted code)in addition to that I also want to
the syntax story({ option1: true, option2: 'value' })
has a principal difference: it allows using arbitrary configuration value types with ease, while unique keys leave you only with booleans
it might solve the following cases:
and last, but not least: object syntax will be easier to extend in the future, using real JS
pseudo code
---
defaultStoryConfig: { openCode: true, renderMethod: 'iframe' }
---
```js story({ ...defaultStoryConfig, minHeight: '200px' })
export const myStory = () => html`...my-story-code...`;
since we have `story` and `script`, I think it might be good to keep them both
the difference still makes sense: `story` is for rendering and `script` is for executing only
but the names can be improved, because not every rendering is a story, see the example below:
````markdown
## Setup
Setup data for demos:
```js script({ showCode: true })
import { html } from `lit`;
const users = [
{ firstName: 'John', lastName: 'Doe' },
{ firstName: 'Jane', lastName: 'Doe' },
];
Setup styles for demos:
<style>
/* some basic styles, e.g. for ul and li */
</style>
export const listOfUsers = () => html`
<ul>
${users.map(user => html`<li>${user.firstName} ${user.lastName}</li>`)}
</ul>
`;
export const listOfUsers = () => html`
<style>
/* some isolated styles */
</style>
<ul>
${users.map(user => html`<li>${user.firstName} ${user.lastName}</li>`)}
</ul>
`;
// isolated JS env
import 'path/to/my-user.define.js'
export const listOfUsers = () => {
const localUsers = [...];
return html`
<style>
/* some isolated styles */
</style>
<ul>
${localUsers.map(user => html`<li><my-user user=${user}></my-user></li>`)}
</ul>
`;
}
I'd improve the names like this:
- `story` => `render`
- `script` => `execute`
- `frame` => `wrapper` (to prevent confusion with an iframe)
I'm just scraping the surface here, but I'll be happy to work on a test suite with many input/output examples for my use cases. Do you already have or are you planning to set smth up? I can either extend it or start making it myself and let you extend with your cases later.
all your examples are meant to run client side
right?
so it would be client render
and client execute
?
render
## Client Rendering
```js client render
export const foo = () => html`<p>content</p>`;
ā¤µļø
ā¤µļø (after mdjs-render is registered and initialized)
content
// VS
export const foo = () => html`<p>content</p>`;
ā¤µļø
content
So `js client render` executes the render on the client and requires an initialized web component to render. `js server render` executes the render on the server and does not need any js.
hmmmm....
or do we even want hydration? š¤
e.g. similar to [hydration](https://github.com/modernweb-dev/rocket/discussions/302) of web components...
(`render-mode` is the current attribute for it... again better name would be nice)
export const foo = () => html`<p>content</p>`;
ā¤µļø
content
Benefit would be NO js needed to display it... and it could become interactive on click, on visible, on idle, ...
puuhhh that is getting more and more complex š
I think the workflow should be 1) update to v10 of unified 2) "finish" partial hydration for web components 3) look into this API again
so this might be a little bit š
as I do not want to block you... here are two ideas
a) only do small adjustments to the API for example by "just" adding js story with-code
and release it
b) do (1) and (a) and release as a breaking change => e.g. server/hydration/add js options would happen in a next breaking change
all your examples are meant to run
client side
right?so it would be
client render
andclient execute
?
not really partially I do not understand your original proposal, but I feel like it's just another dimension to what we are discussing here, so can be solved with the same API which translates to another configuration option
also, why do you want to be explicit about it? I mean your end goal is to render, so if you can prerender on the server, then do it as a perf optimisation, if you can't, leave it to the client, if smth doesn't go right automatically, then forcing client/server via an option can give a way to solve it
```js server render
export const foo = () => html`<p>content</p>`;
ā¤µļø
content
this example makes me think we are talking about 2 different "server" render:
1. render only the Light DOM defined in the story template and leave the rest of work to the client
2. full SSR: entire tree with Shadow DOM and all children/other Shadow DOMs produced as a result of it (I'm not an expert in Shadow DOM SSR, so not sure I fully understand how it works), and this is proposed here https://github.com/modernweb-dev/rocket/issues/308
the 1 is pretty simple to do on the server, even if `<p>` is a WC, just rendering LightDOM is easy
while 2 is a totally different story and relying on the automatic behavior is probably not a good idea, so it's indeed important to keep it in mind when designing the API for new MDJS
puuhhh that is getting more and more complex š
I think the workflow should be
- update to v10 of unified
- "finish" partial hydration for web components
- look into this API again
so this might be a little bit š
as I do not want to block you... here are two ideas a) only do small adjustments to the API for example by "just" adding
js story with-code
and release it b) do (1) and (a) and release as a breaking change => e.g. server/hydration/add js options would happen in a next breaking change
thanks for suggesting a way to unblock me :) I agree it's good to start small and solve the low hanging fruits first, but from my perspective the most valuable low hanging fruits are the ones which would solve my 2 issues here:
given the current syntax, I'd introduce 2 new keys as previously discussed in https://github.com/modernweb-dev/rocket/discussions/288, except that after all good input we had here I'd name them differently, currently I like script-with-code
and story-with-code
, but we can change it when PR is technically ready, wdyt?
currently I like script-with-code and story-with-code, but we can change it when PR is technically ready, wdyt?
sounds good to me š looking forward to a PR š¤
in markdown we currently have this
Rendered
Question
now the question is... would that make sense server-side as well? I guess... and what should the key be š¤
should it retain the
story
? or a complete "new" set?suggestion from the top of my head...
js server
js server inject
js server inject-frame
js client
js client inject
(formerjs story
)js client inject-frame
(formerjs story-preview
)hmmm
inject
,inject-frame
seems not very intuitive... anyone got better ideas? š¤