B
    CVvgW                 @   s  d dl mZ d dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZmZ eG d	d
 d
ZG dd dZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd deZG dd  d eZG d!d" d"eZG d#d$ d$eZG d%d& d&eZ G d'd( d(Z!G d)d* d*eZ"G d+d, d,e"Z#d-S ).    )	dataclass)List)Template)render_to_string)conditional_escape)
SafeString)slugify)TEMPLATE_PACKflatattrender_fieldc               @   s"   e Zd ZU ee ed< eed< dS )PointerZ	positionsnameN)__name__
__module____qualname__r   int__annotations__str r   r   D/tmp/pip-install-o3oxmrkh/django-crispy-forms/crispy_forms/layout.pyr      s   
r   c               @   s   e Zd Zdd ZdS )TemplateNameMixinc             C   s    d| j kr| j | }n| j }|S )Nz%s)template)selftemplate_packr   r   r   r   get_template_name   s    
z#TemplateNameMixin.get_template_nameN)r   r   r   r   r   r   r   r   r      s   r   c               @   s\   e Zd Zdd Zdd Zdd Zdd Zd	d
 ZdddZddddddZ	e
fddZdS )LayoutObjectc             C   s
   | j | S )N)fields)r   slicer   r   r   __getitem__   s    zLayoutObject.__getitem__c             C   s   || j |< d S )N)r   )r   r   valuer   r   r   __setitem__!   s    zLayoutObject.__setitem__c             C   s   | j |= d S )N)r   )r   r   r   r   r   __delitem__$   s    zLayoutObject.__delitem__c             C   s
   t | jS )N)lenr   )r   r   r   r   __len__'   s    zLayoutObject.__len__c             C   s2   d| j kr"t| j|r"t| j|S t| |S dS )z
        This allows us to access self.fields list methods like append or insert, without
        having to declare them one by one
        r   N)__dict__hasattrr   getattrobject__getattribute__)r   r   r   r   r   __getattr__*   s    zLayoutObject.__getattr__Nc             C   s   | j tdddS )a  
        Returns a list of Pointers. First parameter is the location of the
        field, second one the name of the field. Example::

            [
                Pointer([0,1,2], 'field_name1'),
                Pointer([0,3], 'field_name2'),
            ]
        NT)indexgreedy)get_layout_objectsr   )r   r*   r   r   r   get_field_names5   s    
zLayoutObject.get_field_namesr   F)r*   	max_levelr+   c      
      G   s   g }|dk	rt |ts|g}n|dkr*g }t|dko@|d tk}xt| jD ]\}}t ||r|r||t||g | n|t||g |jj	
  t|drNt||k s|rN||g ||d}	||j||	 }qNW |S )a  
        Returns a list of Pointers pointing to layout objects of any type matching
        `LayoutClasses`::

            [
                Pointer([0,1,2], 'div']),
                Pointer([0,3], 'field_name'),
            ]

        :param max_level: An integer that indicates max level depth to reach when
        traversing a layout.
        :param greedy: Boolean that indicates whether to be greedy. If set, max_level
        is skipped.
        N   r   r-   )r*   r.   r+   )
isinstancelistr"   r   	enumerater   appendr   	__class__r   lowerr%   r,   )
r   r*   r.   r+   ZLayoutClassesZpointersZ	str_classilayout_objectZ
new_kwargsr   r   r   r,   A   s    
zLayoutObject.get_layout_objectsc                s$   t d fdd| jD S )N c             3   s&   | ]}t | fd iV  qdS )r   N)r   ).0field)contextformkwargsr   r   r   	<genexpr>i   s    z3LayoutObject.get_rendered_fields.<locals>.<genexpr>)r   joinr   )r   r<   r;   r   r=   r   )r;   r<   r=   r   r   get_rendered_fieldsg   s    z LayoutObject.get_rendered_fields)N)r   r   r   r   r    r!   r#   r)   r-   r,   r	   r@   r   r   r   r   r      s   
&r   c               @   s$   e Zd ZdZdd ZefddZdS )Layouta  
    Form Layout. It is conformed by Layout objects: `Fieldset`, `Row`, `Column`, `MultiField`,
    `HTML`, `ButtonHolder`, `Button`, `Hidden`, `Reset`, `Submit` and fields. Form fields
    have to be strings.
    Layout objects `Fieldset`, `Row`, `Column`, `MultiField` and `ButtonHolder` can hold other
    Layout objects within. Though `ButtonHolder` should only hold `HTML` and BaseInput
    inherited classes: `Button`, `Hidden`, `Reset` and `Submit`.

    Example::

        helper.layout = Layout(
            Fieldset('Company data',
                'is_company'
            ),
            Fieldset(_('Contact details'),
                'email',
                Row('password1', 'password2'),
                'first_name',
                'last_name',
                HTML('<img src="/media/somepicture.jpg"/>'),
                'company'
            ),
            ButtonHolder(
                Submit('Save', 'Save', css_class='button white'),
            ),
        )
    c             G   s   t || _d S )N)r1   r   )r   r   r   r   r   __init__   s    zLayout.__init__c             K   s   | j |||f|S )N)r@   )r   r<   r;   r   r=   r   r   r   render   s    zLayout.renderN)r   r   r   __doc__rB   r	   rC   r   r   r   r   rA   m   s   rA   c               @   s2   e Zd ZdZdZddddddZefddZdS )	ButtonHolderag  
    Layout object. It wraps fields in a <div class="buttonHolder">

    This is where you should put Layout objects that render to form buttons

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : HTML or BaseInput
        The layout objects to render within the ``ButtonHolder``. It should
        only hold `HTML` and `BaseInput` inherited objects.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.

    Examples
    --------

    An example using ``ButtonHolder`` in your layout::

        ButtonHolder(
            HTML(<span style="display: hidden;">Information Saved</span>),
            Submit('Save', 'Save')
        )
    z%s/layout/buttonholder.htmlN)css_id	css_classr   c            G   s&   t || _|| _|| _|p| j| _d S )N)r1   r   rF   rG   r   )r   rF   rG   r   r   r   r   r   rB      s    
zButtonHolder.__init__c             K   s:   | j |||f|}| |}|| |d t|| S )N)Zbuttonholderfields_output)r@   r   updater   flatten)r   r<   r;   r   r=   htmlr   r   r   r   rC      s    
zButtonHolder.render)r   r   r   rD   r   rB   r	   rC   r   r   r   r   rE      s   $rE   c               @   s6   e Zd ZdZdZdZddddddZefdd	ZdS )
	BaseInputa  
    A base class to reduce the amount of code in the Input classes.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.
    z%s/layout/baseinput.htmlr8   N)rF   rG   r   c            K   sl   || _ || _|r|| _nt| j }| j d| | _i | _|rR|  jd| 7  _|pZ| j| _t|| _	d S )Nz-id- )
r   r   idr   
input_typeattrsfield_classesr   r
   
flat_attrs)r   r   r   rF   rG   r   r=   Zslugr   r   r   rB      s    
zBaseInput.__init__c             K   s<   t t| j|| _| |}|d| i t|| S )z
        Renders an `<input />` if container is used as a Layout object.
        Input button value can be a variable in context.
        input)r   r   r   rC   r   rI   r   rJ   )r   r<   r;   r   r=   r   r   r   r   rC      s    
zBaseInput.render)	r   r   r   rD   r   rQ   rB   r	   rC   r   r   r   r   rL      s
   rL   c               @   s   e Zd ZdZdZdZdS )Submita  
    Used to create a Submit button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> submit = Submit('Search the Site', 'search this site')
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary" id="submit-id-search-the-site"/>'

    >>> submit = Submit('Search the Site', 'search this site', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Submit('submit', 'Submit'))
    Zsubmitzbtn btn-primaryN)r   r   r   rD   rO   rQ   r   r   r   r   rT     s   :rT   c               @   s   e Zd ZdZdZdZdS )Buttonai  
    Used to create a button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> button = Button('Button 1', 'Press Me!')
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn" id="button-id-button-1"/>'

    >>> button = Button('Button 1', 'Press Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Button('Button 1', 'Press Me!'))
    buttonZbtnN)r   r   r   rD   rO   rQ   r   r   r   r   rU   G  s   :rU   c               @   s   e Zd ZdZdZdZdS )Hiddena  
    Used to create a Hidden input descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> hidden = Hidden("hidden", "hide-me")
    >>> hidden.render("", "", Context())
    '<input type="hidden" name="hidden" value="hide-me"/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Hidden("hidden", "hide-me"))
    hiddenN)r   r   r   rD   rO   rQ   r   r   r   r   rW     s   3rW   c               @   s   e Zd ZdZdZdZdS )Reseta  
    Used to create a reset button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> reset = Reset('Reset This Form', 'Revert Me!')
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse" id="reset-id-reset-this-form"/>'

    >>> reset = Reset('Reset This Form', 'Revert Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Reset('Reset This Form', 'Revert Me!'))
    resetzbtn btn-inverseN)r   r   r   rD   rO   rQ   r   r   r   r   rY     s   :rY   c               @   s2   e Zd ZdZdZddddddZefddZdS )	Fieldseta  
    A layout object which wraps fields in a ``<fieldset>``

    Parameters
    ----------
    legend : str
        The content of the fieldset's ``<legend>``. This text is context
        aware, to bring this to life see the examples section.
    *fields : str
        Any number of fields as positional arguments to be rendered within
        the ``<fieldset>``
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<fieldset>``.

    Examples
    --------

    The Fieldset Layout object is added to your ``Layout`` for example::

        Fieldset("Text for the legend",
            "form_field_1",
            "form_field_2",
            css_id="my-fieldset-id",
            css_class="my-fieldset-class",
            data="my-data"
        )

    The above layout will be rendered as::

        '''
        <fieldset id="fieldset-id" class="my-fieldset-class" data="my-data">
           <legend>Text for the legend</legend>
           # form fields render here
        </fieldset>
        '''

    The first parameter is the text for the fieldset legend. This text is context aware,
    so you can do things like::

        Fieldset("Data for {{ user.username }}",
            'form_field_1',
            'form_field_2'
        )
    z%s/layout/fieldset.htmlN)rG   rF   r   c            O   s6   t || _|| _|| _|| _|p$| j| _t|| _d S )N)r1   r   legendrG   rF   r   r
   rR   )r   r\   rG   rF   r   r   r=   r   r   r   rB   :  s    
zFieldset.__init__c             K   sR   | j |||f|}| jr.tt| j|}ntd}| |}t|| ||dS )Nr8   )fieldsetr\   r   )r@   r\   r   r   rC   r   r   r   )r   r<   r;   r   r=   r   r\   r   r   r   r   rC   B  s    
zFieldset.render)r   r   r   rD   r   rB   r	   rC   r   r   r   r   r[      s   6r[   c               @   s<   e Zd ZdZdZdZdddddddddZefdd	ZdS )

MultiFielda  
    MultiField container for Bootstrap3. Renders to a MultiField <div>.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_template: str
        The template which fields will be rendered with.

    Parameters
    ----------
    label: str
        The label for the multifield.
    *fields: str
        The fields to be rendered within the multifield.
    label_class: str, optional
        CSS classes to be added to the multifield label. By default None.
    help_text: str, optional
        Help text will be available in the context of the multifield template.
        This is unused in the bootstrap3 template provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A DOM id for the layout object which will be added to the wrapping
        ``<div>`` if provided. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    field_template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the wrapping
        ``<div>``.

    z%s/layout/multifield.htmlz%s/multifield.htmlN)label_class	help_textrG   rF   r   field_templatec      
      O   sV   t || _|| _|pd| _|p d| _|| _|| _|p8| j| _|pD| j| _t	|	| _
d S )NZ
blockLabelZ
ctrlHolder)r1   r   Z
label_htmlr_   rG   rF   r`   r   ra   r
   rR   )
r   labelr_   r`   rG   rF   r   ra   r   r=   r   r   r   rB   y  s    


zMultiField.__init__c       	      K   s   |d r<x2dd |   D D ]}||jkr|  jd7  _qW | j| }| j|||f|| j| d|}| |}|| |d t||	 S )NZform_show_errorsc             s   s   | ]}|j V  qd S )N)r   )r9   pointerr   r   r   r>     s    z$MultiField.render.<locals>.<genexpr>z error)r   Z
labelclassr7   )Z
multifieldrH   )
r-   errorsrG   ra   r@   r_   r   rI   r   rJ   )	r   r<   r;   r   r=   r:   ra   rH   r   r   r   r   rC     s     


zMultiField.render)	r   r   r   rD   r   ra   rB   r	   rC   r   r   r   r   r^   N  s   &r^   c               @   s6   e Zd ZdZdZdZddddddZefddZdS )	Diva  
    Layout object. It wraps fields in a ``<div>``.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Div(
            'form_field_1',
            'form_field_2',
            css_id='div-example',
            css_class='divs',
        )

    It is also possible to nest Layout Objects within a Div::

        Div(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/div.htmlN)rF   rG   r   c            O   sT   t || _| jr*|r*|  jd| 7  _n
|r4|| _|| _|pB| j| _t|| _d S )NrM   )r1   r   rG   rF   r   r
   rR   )r   rF   rG   r   r   r=   r   r   r   rB     s    

zDiv.__init__c             K   s,   | j |||f|}| |}t|| |dS )N)divr   )r@   r   r   )r   r<   r;   r   r=   r   r   r   r   r   rC     s    
z
Div.render)	r   r   r   rD   r   rG   rB   r	   rC   r   r   r   r   re     s
   2re   c               @   s   e Zd ZdZdZdS )Rowa  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a row. e.g. ``form-row`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Row('form_field_1', 'form_field_2', css_id='row-example')

    It is also possible to nest Layout Objects within a Row::

        Row(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/row.htmlN)r   r   r   rD   r   r   r   r   r   rg     s   /rg   c               @   s   e Zd ZdZdZdS )Columna  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a column. e.g. ``col-md`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. If using the Bootstrap4 template pack the default
        ``col-md`` is removed if this string contins another ``col-`` class.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Column('form_field_1', 'form_field_2', css_id='col-example')

    It is also possible to nest Layout Objects within a Row::

        Div(
            Column(
                Field('form_field', css_class='field-class'),
                css_class='col-sm,
            ),
            Column('form_field_2', css_class='col-sm'),
        )
    z%s/layout/column.htmlN)r   r   r   rD   r   r   r   r   r   rh   %  s   1rh   c               @   s$   e Zd ZdZdd ZefddZdS )HTMLa#  
    Layout object. It can contain pure HTML and it has access to the whole
    context of the page where the form is being rendered.

    Examples::

        HTML("{% if saved %}Data saved{% endif %}")
        HTML('<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />')
    c             C   s
   || _ d S )N)rK   )r   rK   r   r   r   rB   f  s    zHTML.__init__c             K   s   t t| j|S )N)r   r   rK   rC   )r   r<   r;   r   r=   r   r   r   rC   i  s    zHTML.renderN)r   r   r   rD   rB   r	   rC   r   r   r   r   ri   [  s   	ri   c               @   s8   e Zd ZdZdZi ZddddddZedfddZdS )	Fielda  
    A Layout object, usually containing one field name, where you can add
    attributes to it easily.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    attrs : dict
        Attributes to be applied to the field. These are converted into html
        attributes. e.g. ``data_id: 'test'`` in the attrs dict will become
        ``data-id='test'`` on the field's ``<input>``.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    css_class : str, optional
        CSS classes to be applied to the field. These are added to any classes
        included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.
    **kwargs : dict, optional
        Additional attributes are converted into key="value", pairs. These
        attributes are added to the ``<div>``.

    Examples
    --------

    Example::

        Field('field_name', style="color: #333;", css_class="whatever", id="field_name")
    z%s/field.htmlN)rG   wrapper_classr   c            O   sx   t || _| j | _|rHd| jkr>| jd  d| 7  < n
|| jd< || _|pV| j| _| jdd | D  d S )NclassrM   c             S   s"   i | ]\}}t ||d dqS )_-)r   replace)r9   kvr   r   r   
<dictcomp>  s    z"Field.__init__.<locals>.<dictcomp>)r1   r   rP   copyrk   r   rI   items)r   rG   rk   r   r   r=   r   r   r   rB     s    


zField.__init__c             K   sF   |d kri }| j r| j |d< | |}| j|||f|| j|d|S )Nrk   )r   rP   extra_context)rk   r   r@   rP   )r   r<   r;   r   ru   r=   r   r   r   r   rC     s    

zField.render)	r   r   r   rD   r   rP   rB   r	   rC   r   r   r   r   rj   m  s
   'rj   c               @   s"   e Zd ZdZddddddZdS )MultiWidgetFielda  
    Layout object. For fields with :class:`~django.forms.MultiWidget` as
    ``widget``, you can pass additional attributes to each widget.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    attrs : str, optional
        Additional attrs to be added to each widget. These are added to any
        classes included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.

    Examples
    --------

    Example::

        MultiWidgetField(
            'multiwidget_field_name',
            attrs=(
                {'style': 'width: 30px;'},
                {'class': 'second_widget_class'}
            ),
        )
    N)rP   r   rk   c            G   s*   t || _|pi | _|p| j| _|| _d S )N)r1   r   rP   r   rk   )r   rP   r   rk   r   r   r   r   rB     s    

zMultiWidgetField.__init__)r   r   r   rD   rB   r   r   r   r   rv     s   &rv   N)$Zdataclassesr   typingr   Zdjango.templater   Zdjango.template.loaderr   Zdjango.utils.htmlr   Zdjango.utils.safestringr   Zdjango.utils.textr   Zcrispy_forms.utilsr	   r
   r   r   r   r   rA   rE   rL   rT   rU   rW   rY   r[   r^   re   rg   rh   ri   rj   rv   r   r   r   r   <module>   s2   
P$7?@@9@NYJ46P