Skip to content

Commit 0b74709

Browse files
committed
refactor(antdx): new components notification & think
1 parent 8ce8063 commit 0b74709

File tree

18 files changed

+933
-706
lines changed

18 files changed

+933
-706
lines changed

backend/modelscope_studio/components/antdx/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,5 +27,7 @@
2727
from .thought_chain import AntdXThoughtChain as ThoughtChain
2828
from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem
2929
from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem as ThoughtChainThoughtChainItem
30+
from .think import AntdXThink as Think
3031
from .welcome import AntdXWelcome as Welcome
32+
from .notification import AntdXNotification as Notification
3133
from .x_provider import AntdXXProvider as XProvider

backend/modelscope_studio/components/antdx/components.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,7 @@
2626
from .thought_chain import AntdXThoughtChain
2727
from .thought_chain.item import AntdXThoughtChainItem
2828
from .thought_chain.thought_chain_item import AntdXThoughtChainThoughtChainItem
29+
from .think import AntdXThink
2930
from .welcome import AntdXWelcome
31+
from .notification import AntdXNotification
3032
from .x_provider import AntdXXProvider
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
from __future__ import annotations
2+
3+
from gradio.events import EventListener
4+
from typing import Any, Literal
5+
from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir
6+
7+
8+
class AntdXNotification(ModelScopeLayoutComponent):
9+
"""
10+
Ant Design X: https://x.ant.design/components/notification
11+
"""
12+
EVENTS = [
13+
EventListener("permission",
14+
callback=lambda block: block._internal.update(
15+
bind_permission_event=True)),
16+
EventListener("click",
17+
callback=lambda block: block._internal.update(
18+
bind_click_event=True)),
19+
EventListener("close",
20+
callback=lambda block: block._internal.update(
21+
bind_close_event=True)),
22+
EventListener("error",
23+
callback=lambda block: block._internal.update(
24+
bind_error_event=True)),
25+
EventListener("show",
26+
callback=lambda block: block._internal.update(
27+
bind_show_event=True))
28+
]
29+
30+
# supported slots
31+
SLOTS = []
32+
33+
def __init__(
34+
self,
35+
*,
36+
title: str | None = None,
37+
duration: int | float | None = None,
38+
badge: str | None = None,
39+
body: str | None = None,
40+
data: Any | None = None,
41+
dir: Literal['auto', 'ltr', 'rtl'] | None = None,
42+
icon: str | None = None,
43+
lang: str | None = None,
44+
require_interaction: bool | None = None,
45+
silent: bool | None = None,
46+
tag: str | None = None,
47+
additional_props: dict | None = None,
48+
as_item: str | None = None,
49+
_internal: None = None,
50+
# gradio properties
51+
visible: bool | None = None,
52+
elem_id: str | None = None,
53+
elem_classes: list[str] | str | None = None,
54+
elem_style: dict | None = None,
55+
render: bool = True,
56+
**kwargs):
57+
super().__init__(visible=visible,
58+
elem_id=elem_id,
59+
elem_classes=elem_classes,
60+
render=render,
61+
as_item=as_item,
62+
elem_style=elem_style,
63+
**kwargs)
64+
self.additional_props = additional_props
65+
self.title = title
66+
self.duration = duration
67+
self.badge = badge
68+
self.body = body
69+
self.data = data
70+
self.dir = dir
71+
self.icon = icon
72+
self.lang = lang
73+
self.require_interaction = require_interaction
74+
self.silent = silent
75+
self.tag = tag
76+
77+
FRONTEND_DIR = resolve_frontend_dir("notification", type="antdx")
78+
79+
@property
80+
def skip_api(self):
81+
return True
82+
83+
def preprocess(self, payload: None) -> None:
84+
return payload
85+
86+
def postprocess(self, value: None) -> None:
87+
88+
return value
89+
90+
def example_payload(self) -> None:
91+
return None
92+
93+
def example_value(self) -> None:
94+
return None
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from __future__ import annotations
2+
3+
from gradio.events import EventListener
4+
5+
from ....utils.dev import ModelScopeLayoutComponent, resolve_frontend_dir
6+
7+
8+
class AntdXThink(ModelScopeLayoutComponent):
9+
"""
10+
Ant Design X: https://x.ant.design/components/think
11+
"""
12+
EVENTS = [
13+
EventListener("expand",
14+
callback=lambda block: block._internal.update(
15+
bind_expand_event=True)),
16+
]
17+
18+
# supported slots
19+
SLOTS = ['loading', 'icon', 'title']
20+
21+
def __init__(
22+
self,
23+
additional_props: dict | None = None,
24+
*,
25+
icon: str | None = None,
26+
styles: dict | str | None = None,
27+
class_names: dict | str | None = None,
28+
loading: str | bool = None,
29+
title: str | None = None,
30+
root_class_name: str | None = None,
31+
default_expanded: bool | None = None,
32+
expanded: bool | None = None,
33+
blink: bool | None = None,
34+
as_item: str | None = None,
35+
_internal: None = None,
36+
# gradio properties
37+
visible: bool = True,
38+
elem_id: str | None = None,
39+
elem_classes: list[str] | str | None = None,
40+
elem_style: dict | None = None,
41+
render: bool = True,
42+
**kwargs):
43+
super().__init__(visible=visible,
44+
elem_id=elem_id,
45+
elem_classes=elem_classes,
46+
render=render,
47+
as_item=as_item,
48+
elem_style=elem_style,
49+
**kwargs)
50+
self.additional_props = additional_props
51+
self.icon = icon
52+
self.styles = styles
53+
self.class_names = class_names
54+
self.loading = loading
55+
self.default_expanded = default_expanded
56+
self.expanded = expanded
57+
self.blink = blink
58+
self.title = title
59+
self.root_class_name = root_class_name
60+
61+
FRONTEND_DIR = resolve_frontend_dir("think", type="antdx")
62+
63+
@property
64+
def skip_api(self):
65+
return True
66+
67+
def preprocess(self, payload: None) -> None:
68+
return payload
69+
70+
def postprocess(self, value: None) -> None:
71+
72+
return value
73+
74+
def example_payload(self) -> None:
75+
return None
76+
77+
def example_value(self) -> None:
78+
return None

config/changelog/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
},
2626
"devDependencies": {
2727
"@changesets/types": "^6.1.0",
28-
"@types/node": "^25.4.0",
28+
"@types/node": "^25.5.0",
2929
"tsup": "^8.5.1"
3030
}
3131
}

config/lint-config/package.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
"dependencies": {
1919
"@eslint/compat": "^2.0.3",
2020
"@eslint/js": "^10.0.1",
21-
"@typescript-eslint/parser": "^8.57.0",
21+
"@typescript-eslint/parser": "^8.57.1",
2222
"eslint-config-prettier": "^10.1.8",
2323
"eslint-import-resolver-typescript": "^4.4.4",
2424
"eslint-plugin-import": "^2.32.0",
@@ -28,17 +28,17 @@
2828
"eslint-plugin-react-hooks": "^7.0.1",
2929
"eslint-plugin-react-refresh": "^0.5.2",
3030
"eslint-plugin-simple-import-sort": "^12.1.0",
31-
"eslint-plugin-svelte": "^3.15.1",
31+
"eslint-plugin-svelte": "^3.15.2",
3232
"globals": "^17.4.0",
3333
"postcss": "^8.5.8",
3434
"postcss-less": "^6.0.0",
3535
"stylelint-config-rational-order": "^0.1.2",
3636
"stylelint-config-standard": "^40.0.0",
3737
"stylelint-declaration-block-no-ignored-properties": "^3.0.0",
38-
"stylelint-order": "^8.0.0",
38+
"stylelint-order": "^8.1.1",
3939
"stylelint-prettier": "^5.0.3",
4040
"svelte-eslint-parser": "^1.6.0",
41-
"typescript-eslint": "^8.57.0"
41+
"typescript-eslint": "^8.57.1"
4242
},
4343
"devDependencies": {
4444
"@types/eslint": "^9.6.1",
Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
<script lang="ts">
2+
import {
3+
getProps,
4+
importComponent,
5+
processProps,
6+
} from '@svelte-preprocess-react/component';
7+
import { getSlots } from '@svelte-preprocess-react/svelte-contexts/slot.svelte';
8+
import cls from 'classnames';
9+
10+
const AwaitedNotification = importComponent(() => import('./notification'));
11+
12+
const props = $props();
13+
const {
14+
gradio,
15+
getComponentProps,
16+
getAdditionalProps,
17+
children,
18+
updateProps,
19+
} = getProps<{
20+
additional_props?: Record<string, any>;
21+
_internal: {
22+
layout?: boolean;
23+
};
24+
title?: string;
25+
}>(() => props);
26+
27+
const getProceedProps = processProps(() => {
28+
const {
29+
visible,
30+
_internal,
31+
as_item,
32+
elem_classes,
33+
elem_id,
34+
elem_style,
35+
...restProps
36+
} = getComponentProps();
37+
return {
38+
gradio,
39+
additionalProps: getAdditionalProps(),
40+
_internal,
41+
as_item,
42+
restProps,
43+
visible,
44+
elem_id,
45+
elem_classes,
46+
elem_style,
47+
};
48+
});
49+
const proceedProps = $derived(getProceedProps());
50+
51+
const slots = getSlots();
52+
</script>
53+
54+
{#await AwaitedNotification then Notification}
55+
<Notification
56+
style={proceedProps.elem_style}
57+
className={cls(proceedProps.elem_classes, 'ms-gr-antdx-notification')}
58+
id={proceedProps.elem_id}
59+
{...proceedProps.restProps}
60+
{...proceedProps.additionalProps}
61+
title={proceedProps.additionalProps.title ||
62+
proceedProps.restProps.title ||
63+
''}
64+
slots={slots.value}
65+
visible={proceedProps.visible as boolean}
66+
onVisible={(v) => {
67+
updateProps({
68+
visible: v,
69+
});
70+
}}
71+
>
72+
{@render children?.()}
73+
</Notification>
74+
{/await}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import config from '../../defineConfig.js';
2+
3+
export default config();
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { sveltify } from '@svelte-preprocess-react';
2+
import { useEffect } from 'react';
3+
import { notification, type XNotificationOpenArgs } from '@ant-design/x';
4+
import { useMemoizedFn } from '@utils/hooks/useMemoizedFn';
5+
6+
export const Notification = sveltify<
7+
XNotificationOpenArgs & {
8+
visible: boolean;
9+
onVisible: (visible: boolean) => void;
10+
onPermission?: (permission: NotificationPermission) => void;
11+
}
12+
>(({ slots, onClose, visible, onVisible, tag, onPermission, ...props }) => {
13+
const [{ permission }, { open, close, requestPermission }] =
14+
notification.useNotification();
15+
const onPermissionMemoized = useMemoizedFn(onPermission);
16+
17+
useEffect(() => {
18+
onPermissionMemoized(permission);
19+
}, [permission, onPermissionMemoized]);
20+
useEffect(() => {
21+
if (visible) {
22+
const run = async () => {
23+
let result = permission;
24+
if (result !== 'granted') {
25+
result = await requestPermission();
26+
}
27+
if (result === 'granted') {
28+
open({
29+
...props,
30+
tag,
31+
onClose(...args) {
32+
onVisible?.(false);
33+
onClose?.(...args);
34+
},
35+
});
36+
}
37+
};
38+
run();
39+
} else {
40+
close(tag ? [tag] : undefined);
41+
}
42+
43+
return () => {
44+
close(tag ? [tag] : undefined);
45+
};
46+
}, [visible, tag]);
47+
return null;
48+
});
49+
50+
export default Notification;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
{
2+
"name": "@modelscope-studio/antd-notification",
3+
"type": "module",
4+
"exports": {
5+
".": {
6+
"gradio": "./Index.svelte",
7+
"default": "./Index.svelte"
8+
},
9+
"./package.json": {
10+
"gradio": "./package.json",
11+
"default": "./package.json"
12+
}
13+
}
14+
}

0 commit comments

Comments
 (0)