Skip to content

Commit b0197ef

Browse files
authored
feat: integrate antdx (#48)
* feat: integrate antdx * feat(antdx): bubble * fix: build mode * feat(antdx): welcome & prompts * feat(antdx): thought-chain * feat(antdx): sender, attachments, suggestion * feat(antdx): x-provider * fix: card meta * fix: children * chore: add changeset
1 parent 3253ae6 commit b0197ef

168 files changed

Lines changed: 5844 additions & 996 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/brown-trains-flow.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modelscope-studio/antd': patch
3+
'@modelscope-studio/frontend': patch
4+
'modelscope_studio': patch
5+
---
6+
7+
fix: missing component children rendering
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
'@modelscope-studio/antdx': minor
3+
'@modelscope-studio/frontend': minor
4+
'modelscope_studio': minor
5+
---
6+
7+
feat: integrate antdx

backend/modelscope_studio/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from .components.antd.components import *
2+
from .components.antdx.components import *
23
from .components.base import *
34
from .components.legacy.components import *
45
from .external import load

backend/modelscope_studio/components/antd/affix/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ def __init__(
3232
offset_bottom: int | float | None = None,
3333
offset_top: int | float | None = None,
3434
get_target: str | None = None,
35+
root_class_name: str | None = None,
3536
as_item: str | None = None,
3637
_internal: None = None,
3738
# gradio properties
@@ -58,6 +59,7 @@ def __init__(
5859
self.offset_bottom = offset_bottom
5960
self.offset_top = offset_top
6061
self.get_target = get_target
62+
self.root_class_name = root_class_name
6163

6264
FRONTEND_DIR = resolve_frontend_dir("affix")
6365

backend/modelscope_studio/components/antd/auto_complete/__init__.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,8 @@ class AntdAutoComplete(ModelScopeDataLayoutComponent):
4141

4242
# supported slots
4343
SLOTS = [
44-
'allowClear.clearIcon', 'dropdownRender', 'children', 'notFoundContent'
44+
'allowClear.clearIcon', 'dropdownRender', 'children',
45+
'notFoundContent', 'options'
4546
]
4647

4748
def __init__(

backend/modelscope_studio/components/antd/empty/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@ def __init__(
2525
| None = None,
2626
image_style: dict | None = None,
2727
root_class_name: str | None = None,
28+
styles: dict | None = None,
29+
class_names: dict | None = None,
2830
as_item: str | None = None,
2931
_internal: None = None,
3032
# gradio properties
@@ -42,6 +44,8 @@ def __init__(
4244
elem_style=elem_style,
4345
**kwargs)
4446
self.props = props
47+
self.styles = styles
48+
self.class_names = class_names
4549
self.description = description
4650
self.image = image
4751
self.image_style = image_style
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
from .attachments import AntdXAttachments as Attachments
2+
from .attachments.file_card import \
3+
AntdXAttachmentsFileCard as AttachmentsFileCard
4+
from .bubble import AntdXBubble as Bubble
5+
from .bubble.list import AntdXBubbleList as BubbleList
6+
from .bubble.list.item import AntdXBubbleListItem as BubbleListItem
7+
from .bubble.list.role import AntdXBubbleListRole as BubbleListRole
8+
from .conversations import AntdXConversations as Conversations
9+
from .conversations.item import AntdXConversationsItem as ConversationsItem
10+
from .prompts import AntdXPrompts as Prompts
11+
from .prompts.item import AntdXPromptsItem as PromptsItem
12+
from .sender import AntdXSender as Sender
13+
from .sender.header import AntdXSenderHeader as SenderHeader
14+
from .suggestion import AntdXSuggestion as Suggestion
15+
from .suggestion.item import AntdXSuggestionItem as SuggestionItem
16+
from .thought_chain import AntdXThoughtChain as ThoughtChain
17+
from .thought_chain.item import AntdXThoughtChainItem as ThoughtChainItem
18+
from .welcome import AntdXWelcome as Welcome
19+
from .x_provider import AntdXXProvider as XProvider
Lines changed: 222 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,222 @@
1+
from __future__ import annotations
2+
3+
import tempfile
4+
from pathlib import Path
5+
from typing import TYPE_CHECKING, Any, Callable, Literal
6+
7+
import gradio_client.utils as client_utils
8+
from gradio import processing_utils
9+
from gradio.components.base import Component
10+
from gradio.data_classes import FileData, ListFiles
11+
from gradio.events import EventListener
12+
from gradio.utils import NamedString
13+
from gradio_client import handle_file
14+
15+
from ....utils.dev import ModelScopeDataLayoutComponent, resolve_frontend_dir
16+
from .file_card import AntdXAttachmentsFileCard
17+
18+
if TYPE_CHECKING:
19+
from gradio.components import Timer
20+
21+
22+
# as inputs, outputs
23+
class AntdXAttachments(ModelScopeDataLayoutComponent):
24+
"""
25+
Ant Design: https://ant.design/components/attachments
26+
"""
27+
28+
FileCard = AntdXAttachmentsFileCard
29+
30+
EVENTS = [
31+
EventListener("change",
32+
callback=lambda block: block._internal.update(
33+
bind_change_event=True)),
34+
EventListener("drop",
35+
callback=lambda block: block._internal.update(
36+
bind_drop_event=True)),
37+
EventListener("download",
38+
callback=lambda block: block._internal.update(
39+
bind_download_event=True)),
40+
EventListener("preview",
41+
callback=lambda block: block._internal.update(
42+
bind_preview_event=True)),
43+
EventListener("remove",
44+
callback=lambda block: block._internal.update(
45+
bind_remove_event=True))
46+
]
47+
48+
# supported slots
49+
SLOTS = [
50+
'showUploadList.extra',
51+
'showUploadList.previewIcon',
52+
'showUploadList.removeIcon',
53+
'showUploadList.downloadIcon',
54+
'iconRender',
55+
'itemRender',
56+
'placeholder',
57+
'placeholder.title',
58+
'placeholder.description',
59+
'placeholder.icon',
60+
]
61+
62+
data_model = ListFiles
63+
64+
def __init__(
65+
self,
66+
value: list[str] | Callable | None = None,
67+
props: dict | None = None,
68+
*,
69+
accept: str | None = None,
70+
action: str | None = None,
71+
before_upload: str | None = None,
72+
custom_request: str | None = None,
73+
data: dict | str | None = None,
74+
default_file_list: list[dict] | None = None,
75+
directory: bool | None = None,
76+
disabled: bool | None = None,
77+
items: list[dict] | None = None,
78+
get_drop_container: str | None = None,
79+
overflow: Literal['wrap', 'scrollX', 'scrollY'] | None = None,
80+
placeholder: str | None = None,
81+
headers: dict | None = None,
82+
icon_render: str | None = None,
83+
is_image_url: str | None = None,
84+
item_render: str | None = None,
85+
list_type: Literal['text', 'picture', 'picture-card',
86+
'picture-circle'] | None = None,
87+
max_count: int | None = None,
88+
method: str | None = None,
89+
multiple: bool | None = None,
90+
form_name: str | None = None,
91+
open_file_dialog_on_click: bool | None = True,
92+
preview_file: str | None = None,
93+
progress: dict | None = None,
94+
show_upload_list: bool | dict | None = True,
95+
with_credentials: bool | None = None,
96+
class_names: dict | None = None,
97+
root_style: dict | None = None,
98+
styles: dict | None = None,
99+
root_class_name: str | None = None,
100+
as_item: str | None = None,
101+
_internal: None = None,
102+
# gradio properties
103+
visible: bool = True,
104+
elem_id: str | None = None,
105+
elem_classes: list[str] | str | None = None,
106+
elem_style: dict | None = None,
107+
key: int | str | None = None,
108+
every: Timer | float | None = None,
109+
inputs: Component | list[Component] | set[Component] | None = None,
110+
render: bool = True,
111+
**kwargs):
112+
113+
super().__init__(as_item=as_item,
114+
visible=visible,
115+
value=value,
116+
elem_id=elem_id,
117+
elem_classes=elem_classes,
118+
key=key,
119+
elem_style=elem_style,
120+
every=every,
121+
inputs=inputs,
122+
render=render,
123+
**kwargs)
124+
self.props = props
125+
self.accept = accept
126+
self.action = action
127+
self.before_upload = before_upload
128+
self.custom_request = custom_request
129+
self.data = data
130+
self.default_file_list = default_file_list
131+
self.directory = directory
132+
self.disabled = disabled
133+
self.items = items
134+
self.get_drop_container = get_drop_container
135+
self.overflow = overflow
136+
self.placeholder = placeholder
137+
self.class_names = class_names
138+
self.root_style = root_style
139+
self.styles = styles
140+
self.headers = headers
141+
self.icon_render = icon_render
142+
self.is_image_url = is_image_url
143+
self.item_render = item_render
144+
self.list_type = list_type
145+
self.max_count = max_count
146+
self.method = method
147+
self.multiple = multiple
148+
self.form_name = form_name
149+
self.open_file_dialog_on_click = open_file_dialog_on_click
150+
self.preview_file = preview_file
151+
self.progress = progress
152+
self.show_upload_list = show_upload_list
153+
self.with_credentials = with_credentials
154+
self.root_class_name = root_class_name
155+
156+
FRONTEND_DIR = resolve_frontend_dir("attachments", type="antdx")
157+
158+
def _process_single_file(self, f: FileData) -> NamedString:
159+
file_name = f.path
160+
file = tempfile.NamedTemporaryFile(delete=False, dir=self.GRADIO_CACHE)
161+
file.name = file_name
162+
return NamedString(file_name)
163+
164+
def preprocess(self, payload: ListFiles | None) -> list[str] | None:
165+
"""
166+
Parameters:
167+
payload: File information as a list of FileData objects.
168+
Returns:
169+
Passes the file as a list of `str`.
170+
"""
171+
if payload is None:
172+
return None
173+
174+
return [self._process_single_file(f) for f in payload] # type: ignore
175+
176+
def _download_files(self, value: list[str]) -> list[str]:
177+
downloaded_files = []
178+
for file in value:
179+
if client_utils.is_http_url_like(file):
180+
downloaded_file = processing_utils.save_url_to_cache(
181+
file, self.GRADIO_CACHE)
182+
downloaded_files.append(downloaded_file)
183+
else:
184+
downloaded_files.append(file)
185+
return downloaded_files
186+
187+
def postprocess(self, value: list[str] | None) -> ListFiles | None:
188+
"""
189+
Parameters:
190+
value: a `list[str]` of filepaths/URLs.
191+
Returns:
192+
File information as a list of FileData objects.
193+
"""
194+
if value is None:
195+
return None
196+
value = self._download_files(value)
197+
return ListFiles(root=[
198+
FileData(
199+
path=file,
200+
orig_name=Path(file).name,
201+
size=Path(file).stat().st_size,
202+
) for file in value
203+
])
204+
205+
@property
206+
def skip_api(self):
207+
return False
208+
209+
def api_info(self) -> dict[str, list[str]]:
210+
return ListFiles.model_json_schema()
211+
212+
def example_payload(self) -> Any:
213+
return [
214+
handle_file(
215+
"https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf"
216+
)
217+
]
218+
219+
def example_value(self) -> Any:
220+
return [
221+
"https://github.com/gradio-app/gradio/raw/main/test/test_files/sample_file.pdf"
222+
]
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
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 AntdXAttachmentsFileCard(ModelScopeLayoutComponent):
9+
"""
10+
Ant Design X: https://x.ant.design/components/attachments
11+
"""
12+
EVENTS = [
13+
EventListener("remove",
14+
callback=lambda block: block._internal.update(
15+
bind_remove_event=True))
16+
]
17+
18+
# supported slots
19+
SLOTS = []
20+
21+
def __init__(
22+
self,
23+
props: dict | None = None,
24+
*,
25+
item: dict | None = None,
26+
as_item: str | None = None,
27+
_internal: None = None,
28+
# gradio properties
29+
visible: bool = True,
30+
elem_id: str | None = None,
31+
elem_classes: list[str] | str | None = None,
32+
elem_style: dict | None = None,
33+
render: bool = True,
34+
**kwargs):
35+
super().__init__(visible=visible,
36+
elem_id=elem_id,
37+
elem_classes=elem_classes,
38+
render=render,
39+
as_item=as_item,
40+
elem_style=elem_style,
41+
**kwargs)
42+
self.props = props
43+
self.item = item
44+
45+
FRONTEND_DIR = resolve_frontend_dir("attachments",
46+
'file-card',
47+
type="antdx")
48+
49+
@property
50+
def skip_api(self):
51+
return True
52+
53+
def preprocess(self, payload: None) -> None:
54+
return payload
55+
56+
def postprocess(self, value: None) -> None:
57+
58+
return value
59+
60+
def example_payload(self) -> None:
61+
return None
62+
63+
def example_value(self) -> None:
64+
return None

0 commit comments

Comments
 (0)