99from ..components import _component_factory
1010from ..enums import ComponentType , SeparatorSpacingSize
1111from ..utils import find , get
12+ from .action_row import ActionRow
1213from .file import File
1314from .item import Item , ItemCallbackType
1415from .media_gallery import MediaGallery
@@ -35,8 +36,7 @@ class Container(Item[V]):
3536
3637 The current items supported are as follows:
3738
38- - :class:`discord.ui.Button`
39- - :class:`discord.ui.Select`
39+ - :class:`discord.ui.ActionRow`
4040 - :class:`discord.ui.Section`
4141 - :class:`discord.ui.TextDisplay`
4242 - :class:`discord.ui.MediaGallery`
@@ -64,17 +64,6 @@ class Container(Item[V]):
6464 "id" ,
6565 )
6666
67- __container_children_items__ : ClassVar [list [ItemCallbackType ]] = []
68-
69- def __init_subclass__ (cls ) -> None :
70- children : list [ItemCallbackType ] = []
71- for base in reversed (cls .__mro__ ):
72- for member in base .__dict__ .values ():
73- if hasattr (member , "__discord_ui_model_type__" ):
74- children .append (member )
75-
76- cls .__container_children_items__ = children
77-
7867 def __init__ (
7968 self ,
8069 * items : Item ,
@@ -95,34 +84,11 @@ def __init__(
9584 spoiler = spoiler ,
9685 )
9786 self .color = colour or color
98-
99- for func in self .__container_children_items__ :
100- item : Item = func .__discord_ui_model_type__ (
101- ** func .__discord_ui_model_kwargs__
102- )
103- item .callback = partial (func , self , item )
104- self .add_item (item )
105- setattr (self , func .__name__ , item )
10687 for i in items :
10788 self .add_item (i )
10889
10990 def _add_component_from_item (self , item : Item ):
110- if item ._underlying .is_v2 ():
111- self ._underlying .components .append (item ._underlying )
112- else :
113- found = False
114- for row in reversed (self ._underlying .components ):
115- if (
116- isinstance (row , ActionRow ) and row .width + item .width <= 5
117- ): # If a valid ActionRow exists
118- row .children .append (item ._underlying )
119- found = True
120- elif not isinstance (row , ActionRow ):
121- # create new row if last component is v2
122- break
123- if not found :
124- row = ActionRow .with_components (item ._underlying )
125- self ._underlying .components .append (row )
91+ self ._underlying .components .append (item ._underlying )
12692
12793 def _set_components (self , items : list [Item ]):
12894 self ._underlying .components .clear ()
@@ -146,6 +112,9 @@ def add_item(self, item: Item) -> Self:
146112 if not isinstance (item , Item ):
147113 raise TypeError (f"expected Item not { item .__class__ !r} " )
148114
115+ if isinstance (item , (Button , Select )):
116+ raise TypeError (f"{ item .__class__ !r} cannot be added directly. Use ActionRow instead." )
117+
149118 item ._view = self .view
150119 if hasattr (item , "items" ):
151120 item .view = self
@@ -167,7 +136,10 @@ def remove_item(self, item: Item | str | int) -> Self:
167136 if isinstance (item , (str , int )):
168137 item = self .get_item (item )
169138 try :
170- self .items .remove (item )
139+ if isinstance (item , Container ):
140+ self .items .remove (item )
141+ else :
142+ item .parent .remove_item (item )
171143 except ValueError :
172144 pass
173145 return self
@@ -198,6 +170,27 @@ def get_item(self, id: str | int) -> Item | None:
198170 return child
199171 return child
200172
173+ def add_row (
174+ self ,
175+ * items : Item ,
176+ id : int | None = None ,
177+ ) -> Self :
178+ """Adds an :class:`ActionRow` to the container.
179+
180+ To append a pre-existing :class:`ActionRow`, use :meth:`add_item` instead.
181+
182+ Parameters
183+ ----------
184+ *items: Union[:class:`Button`, :class:`Select`]
185+ The items this action row contains.
186+ id: Optiona[:class:`int`]
187+ The action row's ID.
188+ """
189+
190+ a = ActionRow (* items , id = id )
191+
192+ return self .add_item (a )
193+
201194 def add_section (
202195 self ,
203196 * items : Item ,
@@ -340,17 +333,13 @@ def view(self, value):
340333 for item in self .items :
341334 item .parent = self
342335 item ._view = value
343- if hasattr (item , "items" ):
336+ if hasattr (item , "items" ) or hasattr ( item , "children" ) :
344337 item .view = value
345338
346339 @property
347340 def type (self ) -> ComponentType :
348341 return self ._underlying .type
349342
350- @property
351- def width (self ) -> int :
352- return 5
353-
354343 def is_dispatchable (self ) -> bool :
355344 return any (item .is_dispatchable () for item in self .items )
356345
@@ -360,13 +349,7 @@ def is_persistent(self) -> bool:
360349 def refresh_component (self , component : ContainerComponent ) -> None :
361350 self ._underlying = component
362351 i = 0
363- flattened = []
364- for c in component .components :
365- if isinstance (c , ActionRow ):
366- flattened += c .children
367- else :
368- flattened .append (c )
369- for y in flattened :
352+ for y in component .components :
370353 x = self .items [i ]
371354 x .refresh_component (y )
372355 i += 1
0 commit comments