Skip to content

Commit 50947b2

Browse files
committed
styled
1 parent 8667044 commit 50947b2

File tree

6 files changed

+67
-8
lines changed

6 files changed

+67
-8
lines changed

app/components/CodeEditor.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ export default function CodeEditor({
7373
};
7474

7575
return (
76-
<div className="mb-4 code-editor-wrapper position-relative">
76+
<div className="gui-input code-editor-wrapper position-relative">
7777
<InputLabel
7878
label={label}
7979
help={help}

app/renderer.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ function RenderedTreeNode({
135135
children={children}
136136
onChange={onChange}
137137
state={state}
138+
className={props.className}
138139
/>
139140
);
140141
case "nav-tab-content":
@@ -526,10 +527,12 @@ export function RenderedChildren({
526527
children,
527528
onChange,
528529
state,
530+
className,
529531
}: {
530532
children: Array<TreeNode>;
531533
onChange: OnChange;
532534
state: Record<string, any>;
535+
className?: string;
533536
}) {
534537
let elements = children.map((node, idx) => {
535538
let key;
@@ -538,6 +541,10 @@ export function RenderedChildren({
538541
} else {
539542
key = `idx:${idx}`;
540543
}
544+
let prevClassName = node.props.className || "";
545+
if (className && !prevClassName.includes(className)) {
546+
node.props.className = `${className} ${prevClassName}`;
547+
}
541548
return (
542549
<RenderedTreeNode
543550
key={key}

package-lock.json

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

py/gooey_gui/components/common.py

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,18 @@
1515
BLANK_OPTION = "———"
1616

1717

18+
StyleProp = typing.Optional[
19+
typing.TypedDict(
20+
"StyleProp",
21+
{
22+
"selector": dict[str, dict[str, str]],
23+
"@media": dict[str, dict[str, str]],
24+
},
25+
total=False,
26+
)
27+
]
28+
29+
1830
def _default_format(value: typing.Any) -> str:
1931
if value is None:
2032
return BLANK_OPTION
@@ -54,17 +66,17 @@ def nav_tab_content():
5466
return _node("nav-tab-content")
5567

5668

57-
def div(**props) -> core.NestingCtx:
58-
return tag("div", **props)
69+
def div(*, style: StyleProp = None, **props) -> core.NestingCtx:
70+
return tag("div", style=style, **props)
5971

6072

6173
def link(*, to: str, **props) -> core.NestingCtx:
6274
return _node("Link", to=to, **props)
6375

6476

65-
def tag(tag_name: str, **props) -> core.NestingCtx:
77+
def tag(tag_name: str, *, style: StyleProp = None, **props) -> core.NestingCtx:
6678
props["__reactjsxelement"] = tag_name
67-
return _node("tag", **props)
79+
return _node("tag", style=style, **props)
6880

6981

7082
def html(body: str, **props):
@@ -115,11 +127,30 @@ def markdown(
115127

116128

117129
def _node(nodename: str, **props):
130+
if style := props.get("style"):
131+
selector = style.pop("selector", None)
132+
if selector:
133+
identifier = "." + core.md5_values(selector)
134+
for s, rules in selector.items():
135+
_node("css-in-js", selector=s.replace("&", identifier), rules=rules)
136+
props["className"] = " ".join(
137+
filter(None, (props.get("className"), identifier))
138+
)
139+
# media = style.pop("@media", None)
118140
node = core.RenderTreeNode(name=nodename, props=props)
119141
node.mount()
120142
return core.NestingCtx(node)
121143

122144

145+
def styled(css: str) -> core.RenderTreeNode:
146+
css = dedent(css).strip()
147+
className = "gui-" + core.md5_values(css)
148+
selector = "." + className
149+
css = css.replace("&", selector)
150+
core.add_styles(className, css)
151+
return _node("", className=className)
152+
153+
123154
def text(body: str, **props):
124155
core.RenderTreeNode(
125156
name="pre",

py/gooey_gui/core/__init__.py

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,14 @@
1616
realtime_clear_subs,
1717
md5_values,
1818
)
19-
from .renderer import RenderTreeNode, NestingCtx, renderer, route, current_root_ctx
19+
from .renderer import (
20+
RenderTreeNode,
21+
NestingCtx,
22+
renderer,
23+
route,
24+
current_root_ctx,
25+
add_styles,
26+
)
2027
from .state import (
2128
get_session_state,
2229
set_session_state,

py/gooey_gui/core/renderer.py

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@ def current_root_ctx() -> "NestingCtx":
2323
return threadlocal.root_ctx
2424

2525

26+
def add_styles(className: str, css: str):
27+
threadlocal.styles[className] = css
28+
29+
2630
class RenderTreeNode(BaseModel):
2731
name: str
2832
props: ReactHTMLProps = {}
@@ -108,17 +112,27 @@ def renderer(
108112
set_query_params(query_params or {})
109113
realtime_clear_subs()
110114
threadlocal.use_state_count = 0
115+
threadlocal.styles = {}
111116
while True:
112117
try:
113118
root = RenderTreeNode(name="root")
114119
threadlocal.root_ctx = NestingCtx(root)
115120
with threadlocal.root_ctx:
121+
styles_node = RenderTreeNode(
122+
name="tag",
123+
props=dict(__reactjsxelement="style"),
124+
).mount()
116125
try:
117126
ret = render()
118127
except StopException:
119128
ret = None
120129
except RedirectException as e:
121130
return RedirectResponse(e.url, status_code=e.status_code)
131+
if threadlocal.styles:
132+
styles_node.props["dangerouslySetInnerHTML"] = {
133+
"__html": "\n".join(threadlocal.styles.values())
134+
}
135+
print(get_subscriptions())
122136
if isinstance(ret, Response):
123137
return ret
124138
return JSONResponse(

0 commit comments

Comments
 (0)