django-unfold 0.60.0__py3-none-any.whl → 0.62.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (46) hide show
  1. {django_unfold-0.60.0.dist-info → django_unfold-0.62.0.dist-info}/METADATA +15 -6
  2. {django_unfold-0.60.0.dist-info → django_unfold-0.62.0.dist-info}/RECORD +46 -43
  3. unfold/admin.py +1 -1
  4. unfold/contrib/forms/widgets.py +12 -1
  5. unfold/contrib/import_export/templates/admin/import_export/change_list_import.html +5 -0
  6. unfold/contrib/simple_history/templates/simple_history/submit_line.html +16 -18
  7. unfold/forms.py +2 -2
  8. unfold/mixins/base_model_admin.py +7 -2
  9. unfold/sites.py +15 -2
  10. unfold/static/unfold/css/styles.css +1 -1
  11. unfold/static/unfold/js/app.js +61 -0
  12. unfold/styles.css +5 -8
  13. unfold/templates/admin/auth/user/add_form.html +1 -5
  14. unfold/templates/admin/base.html +1 -1
  15. unfold/templates/admin/change_form.html +8 -6
  16. unfold/templates/admin/change_list.html +4 -2
  17. unfold/templates/admin/change_list_results.html +3 -3
  18. unfold/templates/admin/edit_inline/stacked.html +10 -4
  19. unfold/templates/admin/edit_inline/tabular.html +4 -4
  20. unfold/templates/admin/includes/fieldset.html +9 -3
  21. unfold/templates/admin/search_form.html +14 -5
  22. unfold/templates/admin/submit_line.html +1 -1
  23. unfold/templates/unfold/components/card.html +4 -4
  24. unfold/templates/unfold/helpers/add_link.html +3 -1
  25. unfold/templates/unfold/helpers/fieldsets_tabs.html +3 -3
  26. unfold/templates/unfold/helpers/help_text.html +1 -1
  27. unfold/templates/unfold/helpers/messages.html +4 -4
  28. unfold/templates/unfold/helpers/navigation_header.html +2 -2
  29. unfold/templates/unfold/helpers/pagination.html +1 -1
  30. unfold/templates/unfold/helpers/popup_header.html +27 -0
  31. unfold/templates/unfold/helpers/search.html +16 -12
  32. unfold/templates/unfold/helpers/search_results.html +10 -9
  33. unfold/templates/unfold/helpers/shortcut.html +3 -0
  34. unfold/templates/unfold/helpers/site_branding.html +2 -2
  35. unfold/templates/unfold/helpers/tab_action.html +4 -3
  36. unfold/templates/unfold/helpers/tab_actions.html +1 -1
  37. unfold/templates/unfold/helpers/tab_list.html +1 -1
  38. unfold/templates/unfold/widgets/text.html +1 -1
  39. unfold/templates/unfold_crispy/field.html +12 -10
  40. unfold/templates/unfold_crispy/layout/checkbox.html +20 -4
  41. unfold/templates/unfold_crispy/layout/fieldset.html +3 -3
  42. unfold/templatetags/unfold.py +3 -4
  43. unfold/templatetags/unfold_list.py +4 -1
  44. unfold/widgets.py +2 -1
  45. {django_unfold-0.60.0.dist-info → django_unfold-0.62.0.dist-info}/LICENSE.md +0 -0
  46. {django_unfold-0.60.0.dist-info → django_unfold-0.62.0.dist-info}/WHEEL +0 -0
@@ -1,11 +1,12 @@
1
1
  {% load unfold %}
2
2
 
3
- <li class="{% action_item_classes action %}" {% if not link %}x-data="{actionDropdownOpen: false}" x-ref="actionDropdown{{ action.method_name }}"{% endif %}>
3
+ <li class="{% action_item_classes action %}" {% if not link and action.items|length > 0 %}x-data="{actionDropdownOpen: false}" x-ref="actionDropdown{{ action.method_name }}"{% endif %}>
4
4
  <a {% if link %}href="{{ link }}"{% endif %}class="cursor-pointer flex grow items-center gap-2 px-3 py-2 text-left whitespace-nowrap" {% if blank %} target="_blank"{% endif %} {% include "unfold/helpers/attrs.html" with attrs=action.attrs %}
5
5
  {% if not link %}
6
6
  x-on:click="actionDropdownOpen = !actionDropdownOpen"
7
7
  x-bind:class="{'{% if action.variant.value == "default" %}text-primary-600 dark:text-primary-500{% endif %}': actionDropdownOpen }"
8
8
  {% endif %}>
9
+
9
10
  {% if action.icon %}
10
11
  <span class="material-symbols-outlined">
11
12
  {{ action.icon }}
@@ -14,7 +15,7 @@
14
15
 
15
16
  {{ title }}
16
17
 
17
- {% if not link %}
18
+ {% if not link and action.items|length > 0 %}
18
19
  <span class="border-l border-base-200 flex items-center select-none self-stretch ml-auto -mr-1 -my-2 pl-2
19
20
  {% if action.variant.value == "primary" %}
20
21
  border-primary-700 dark:border-primary-500
@@ -36,7 +37,7 @@
36
37
  {% endif %}
37
38
  </a>
38
39
 
39
- {% if not link %}
40
+ {% if not link and action.items|length > 0 %}
40
41
  <template x-teleport="body">
41
42
  <nav x-anchor.bottom-end.offset.4="$refs.actionDropdown{{ action.method_name }}" class="absolute bg-white border border-base-200 flex flex-col -mr-px py-1 right-0 rounded-default shadow-lg top-10 w-52 z-50 dark:bg-base-800 dark:border-base-700" x-transition x-show="actionDropdownOpen" x-on:click.outside="actionDropdownOpen = false">
42
43
  {% for item in action.items %}
@@ -1,5 +1,5 @@
1
1
  {% if actions_list or actions_detail or actions_items or nav_global %}
2
- <ul class="flex flex-col font-medium mb-4 ml-auto mt-2 md:flex-row md:mb-2 md:mt-0 max-md:w-full">
2
+ <ul class="flex flex-col font-medium mb-4 ml-auto mt-2 md:flex-row md:mb-0 md:mt-0 max-md:w-full">
3
3
  {% if actions_items %}
4
4
  {{ actions_items }}
5
5
  {% endif %}
@@ -2,7 +2,7 @@
2
2
 
3
3
  {% if not is_popup %}
4
4
  {% if tabs_list or inlines_list or actions_list or actions_detail or actions_items or nav_global %}
5
- <div class="border-base-200 flex items-start flex-col mb-4 md:border-b dark:md:border-base-800 md:border-l-0 md:flex-row md:items-center">
5
+ <div class="border-base-200 flex items-start flex-col mb-4 min-h-13 md:border-b dark:md:border-base-800 md:border-l-0 md:flex-row md:items-center">
6
6
  {% include "unfold/helpers/tab_items.html" %}
7
7
 
8
8
  {% include "unfold/helpers/tab_actions.html" %}
@@ -1,5 +1,5 @@
1
1
 
2
- <div class="max-w-2xl relative">
2
+ <div class="max-w-2xl relative w-full">
3
3
  {% if widget.prefix %}
4
4
  <span class="absolute left-3 top-0 bottom-0 flex items-center justify-center">
5
5
  {{ widget.prefix }}
@@ -3,21 +3,23 @@
3
3
  {% if field.is_hidden %}
4
4
  {{ field }}
5
5
  {% else %}
6
- <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="group {% if tag == "td" %}align-top border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden px-3 py-3 text-left dark:border-base-800 dark:before:text-font-important-dark {% if form_show_labels and forloop.parentloop.first %}border-t-0{% endif %}{% endif %} {% if field.errors %}errors{% endif %} {% if field_class %} {{ field_class }}{% endif %} {% if field|is_checkbox and tag == "td" %}flex flex-row gap-2 items-center{% else %}{% if 'form-horizontal' in form_class %} row{% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
6
+ <{% if tag %}{{ tag }}{% else %}div{% endif %} id="div_{{ field.auto_id }}" class="group {% if tag == "td" %}align-top border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden px-3 py-3 text-left dark:border-base-800 dark:before:text-font-important-dark {% if form_show_labels and forloop.parentloop.first %}border-t-0{% endif %}{% endif %} {% if field.errors %}errors{% endif %} {% if field_class %} {{ field_class }}{% endif %} {% if field|is_checkbox and tag == "td" %}flex flex-row gap-2 items-center{% else %} {% if 'form-horizontal' in form_class %} border-b border-base-200 border-dashed flex flex-col -mx-3 px-3 py-2.5 lg:flex-row last:-mb-3 dark:border-base-800 last:border-b-0 {% endif %}{% endif %}{% if wrapper_class %} {{ wrapper_class }}{% endif %}{% if field.css_classes %} {{ field.css_classes }}{% endif %}">
7
7
  {% if field.label and not field|is_checkbox and form_show_labels %}
8
- <label {% if field.id_for_label %}for="{{ field.id_for_label }}"{% endif %} class="block font-semibold mb-2 text-font-important-light text-sm dark:text-font-important-dark {% if label_class %} {{ label_class }}{% endif %}">
8
+ <label {% if field.id_for_label %}for="{{ field.id_for_label }}"{% endif %} class="block font-semibold text-font-important-light dark:text-font-important-dark {% if 'form-horizontal' in form_class %}mb-2 lg:mb-0 lg:min-w-56 {% if not field|is_checkbox and not field|is_radioselect and not field|is_checkboxselectmultiple %}lg:mt-2{% endif %} lg:w-56{% else %}mb-2{% endif %} {% if label_class %} {{ label_class }}{% endif %}">
9
9
  {{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}
10
10
  </label>
11
11
  {% endif %}
12
12
 
13
- {% if field|is_checkboxselectmultiple or field|is_radioselect %}
14
- {% include 'unfold_crispy/layout/radio_checkbox_select.html' %}
15
- {% elif field|is_checkbox %}
16
- {% include 'unfold_crispy/layout/checkbox.html' %}
17
- {% else %}
18
- {% crispy_field field %}
13
+ <div class="grow">
14
+ {% if field|is_checkboxselectmultiple or field|is_radioselect %}
15
+ {% include 'unfold_crispy/layout/radio_checkbox_select.html' %}
16
+ {% elif field|is_checkbox %}
17
+ {% include 'unfold_crispy/layout/checkbox.html' %}
18
+ {% else %}
19
+ {% crispy_field field %}
19
20
 
20
- {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
21
- {% endif %}
21
+ {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
22
+ {% endif %}
23
+ </div>
22
24
  </{% if tag %}{{ tag }}{% else %}div{% endif %}>
23
25
  {% endif %}
@@ -1,11 +1,27 @@
1
1
  {% load crispy_forms_field unfold %}
2
2
 
3
3
  {% if form_show_labels %}
4
- <label for="{{ field.id_for_label }}" class="flex flex-row gap-3 items-center {% if tag == "td" %}mt-9{% endif %}">
5
- {% crispy_field field 'class' form_classes.switch %} <span>{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}</span>
6
- </label>
4
+ {% if 'form-horizontal' in form_class %}
5
+ <div class="flex flex-col min-h-[38px] lg:flex-row lg:gap-3 lg:items-center">
6
+ <div class="flex flex-row max-lg:flex-row-reverse max-lg:justify-end gap-3 lg:items-center lg:gap-0 lg:justify-start">
7
+ <label for="{{ field.id_for_label }}" class="flex flex-row font-semibold gap-3 items-center text-base-900 lg:min-w-56 lg:w-56 dark:text-base-100 {% if tag == "td" %}mt-9{% endif %}">
8
+ <span>{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}</span>
9
+ </label>
7
10
 
8
- {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
11
+ {% crispy_field field 'class' form_classes.switch %}
12
+ </div>
13
+
14
+ <div class="">
15
+ {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
16
+ </div>
17
+ </div>
18
+ {% else %}
19
+ <label for="{{ field.id_for_label }}" class="flex flex-row font-semibold gap-3 items-center text-base-900 dark:text-base-100 {% if tag == "td" %}mt-9{% endif %}">
20
+ {% crispy_field field 'class' form_classes.switch %} <span>{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}</span>
21
+ </label>
22
+
23
+ {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
24
+ {% endif %}
9
25
  {% else %}
10
26
  {% with field=field|add_css_class:form_classes.switch %}
11
27
  {% if tag == "td" %}
@@ -1,11 +1,11 @@
1
- <fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %} class="fieldset group flex flex-col gap-5 grow rounded-default border-base-200 shadow-xs aligned border p-3 relative dark:border-base-800 {% if fieldset.css_class %} {{ fieldset.css_class }}{% endif %}" {{ fieldset.flat_attrs }}>
1
+ <fieldset {% if fieldset.css_id %}id="{{ fieldset.css_id }}"{% endif %} class="fieldset group flex flex-col grow rounded-default border-base-200 shadow-xs aligned border p-3 relative dark:border-base-800 {% if fieldset.css_class %} {{ fieldset.css_class }}{% endif %}" {{ fieldset.flat_attrs }}>
2
2
  {% if legend %}
3
- <legend class="border-b border-base-200 font-semibold float-left pb-3 -mx-3 px-3 text-[15px] text-font-important-light dark:text-font-important-dark dark:border-base-800">
3
+ <legend class="border-b border-base-200 font-semibold float-left {% if 'form-horizontal' not in form_class %}mb-5{% endif %} -mx-3 pb-3 px-3 text-[15px] text-font-important-light dark:text-font-important-dark dark:border-base-800">
4
4
  {{ legend|safe }}
5
5
  </legend>
6
6
  {% endif %}
7
7
 
8
- <div class="flex flex-col gap-5">
8
+ <div class="flex flex-col {% if 'form-horizontal' not in form_class %} gap-5{% endif %}">
9
9
  {{ fields|safe }}
10
10
  </div>
11
11
  </fieldset>
@@ -340,7 +340,7 @@ def preserve_changelist_filters(context: Context) -> dict[str, dict[str, str]]:
340
340
  @register.simple_tag(takes_context=True)
341
341
  def element_classes(context: Context, key: str) -> str:
342
342
  if key in context.get("element_classes", {}):
343
- if isinstance(context["element_classes"][key], list | tuple):
343
+ if isinstance(context["element_classes"][key], (list, tuple)):
344
344
  return " ".join(context["element_classes"][key])
345
345
 
346
346
  return context["element_classes"][key]
@@ -359,7 +359,6 @@ def fieldset_rows_classes(context: Context) -> str:
359
359
  [
360
360
  "border",
361
361
  "border-base-200",
362
- "mb-8",
363
362
  "rounded-default",
364
363
  "shadow-xs",
365
364
  "dark:border-base-800",
@@ -385,8 +384,8 @@ def fieldset_row_classes(context: Context) -> str:
385
384
  if (
386
385
  formset
387
386
  and hasattr(field.field, "name")
388
- and field.field.name == formset.opts.ordering_field
389
- and formset.opts.hide_ordering_field
387
+ and field.field.name == getattr(formset.opts, "ordering_field", None)
388
+ and getattr(formset.opts, "hide_ordering_field", False)
390
389
  ):
391
390
  classes.append("hidden")
392
391
 
@@ -38,7 +38,10 @@ from unfold.widgets import UnfoldBooleanWidget
38
38
 
39
39
  register = Library()
40
40
 
41
- LINK_CLASSES = []
41
+ LINK_CLASSES = [
42
+ "text-font-important-light",
43
+ "dark:text-font-important-dark",
44
+ ]
42
45
 
43
46
  ROW_CLASSES = [
44
47
  "align-middle",
unfold/widgets.py CHANGED
@@ -290,7 +290,8 @@ FILE_CLASSES = [
290
290
 
291
291
  class UnfoldPrefixSuffixMixin:
292
292
  def get_context(self, name, value, attrs):
293
- widget = {}
293
+ context = super().get_context(name, value, attrs)
294
+ widget = context["widget"]
294
295
 
295
296
  if "prefix" in self.attrs:
296
297
  widget["prefix"] = self.attrs["prefix"]