django-unfold 0.43.0__py3-none-any.whl → 0.44.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. {django_unfold-0.43.0.dist-info → django_unfold-0.44.0.dist-info}/METADATA +1 -1
  2. {django_unfold-0.43.0.dist-info → django_unfold-0.44.0.dist-info}/RECORD +129 -117
  3. {django_unfold-0.43.0.dist-info → django_unfold-0.44.0.dist-info}/WHEEL +1 -1
  4. unfold/contrib/filters/admin.py +5 -5
  5. unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +1 -1
  6. unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +1 -1
  7. unfold/contrib/filters/templates/unfold/filters/filters_numeric_range.html +1 -1
  8. unfold/contrib/filters/templates/unfold/filters/filters_numeric_single.html +1 -1
  9. unfold/contrib/filters/templates/unfold/filters/filters_numeric_slider.html +3 -3
  10. unfold/contrib/forms/templates/unfold/forms/array.html +3 -3
  11. unfold/contrib/forms/templates/unfold/forms/helpers/toolbar.html +25 -25
  12. unfold/contrib/forms/widgets.py +5 -5
  13. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +1 -1
  14. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +2 -2
  15. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +2 -2
  16. unfold/contrib/guardian/templates/unfold/guardian/group_form.html +8 -8
  17. unfold/contrib/guardian/templates/unfold/guardian/user_form.html +8 -8
  18. unfold/contrib/import_export/templates/admin/import_export/change_form.html +1 -1
  19. unfold/contrib/import_export/templates/admin/import_export/export.html +4 -4
  20. unfold/contrib/import_export/templates/admin/import_export/import_confirm.html +4 -4
  21. unfold/contrib/import_export/templates/admin/import_export/import_errors.html +2 -2
  22. unfold/contrib/import_export/templates/admin/import_export/import_form.html +2 -2
  23. unfold/contrib/import_export/templates/admin/import_export/import_preview.html +5 -5
  24. unfold/contrib/import_export/templates/admin/import_export/import_validation.html +8 -8
  25. unfold/contrib/simple_history/templates/simple_history/object_history.html +2 -2
  26. unfold/contrib/simple_history/templates/simple_history/object_history_form.html +1 -1
  27. unfold/contrib/simple_history/templates/simple_history/object_history_list.html +9 -9
  28. unfold/contrib/simple_history/templates/simple_history/submit_line.html +4 -4
  29. unfold/forms.py +13 -2
  30. unfold/settings.py +20 -7
  31. unfold/sites.py +23 -8
  32. unfold/static/admin/js/inlines.js +2 -2
  33. unfold/static/unfold/css/styles.css +1 -1
  34. unfold/static/unfold/js/alpine.resize.js +1 -0
  35. unfold/static/unfold/js/app.js +52 -71
  36. unfold/static/unfold/js/htmx.js +1 -1
  37. unfold/styles.css +67 -71
  38. unfold/templates/admin/actions.html +19 -17
  39. unfold/templates/admin/app_list.html +3 -3
  40. unfold/templates/admin/auth/user/add_form.html +1 -1
  41. unfold/templates/admin/auth/user/change_password.html +2 -2
  42. unfold/templates/admin/base.html +1 -1
  43. unfold/templates/admin/change_list.html +24 -30
  44. unfold/templates/admin/change_list_results.html +40 -6
  45. unfold/templates/admin/date_hierarchy.html +1 -1
  46. unfold/templates/admin/delete_confirmation.html +7 -7
  47. unfold/templates/admin/delete_selected_confirmation.html +7 -7
  48. unfold/templates/admin/edit_inline/stacked.html +4 -4
  49. unfold/templates/admin/edit_inline/tabular.html +8 -151
  50. unfold/templates/admin/filter.html +7 -7
  51. unfold/templates/admin/includes/fieldset.html +2 -2
  52. unfold/templates/admin/includes/object_delete_summary.html +1 -1
  53. unfold/templates/admin/login.html +4 -4
  54. unfold/templates/admin/nav_sidebar.html +1 -8
  55. unfold/templates/admin/object_history.html +7 -7
  56. unfold/templates/admin/pagination.html +36 -30
  57. unfold/templates/admin/search_form.html +11 -9
  58. unfold/templates/admin/submit_line.html +11 -11
  59. unfold/templates/auth/widgets/read_only_password_hash.html +1 -1
  60. unfold/templates/registration/logged_out.html +3 -3
  61. unfold/templates/registration/password_change_done.html +1 -1
  62. unfold/templates/registration/password_change_form.html +1 -1
  63. unfold/templates/unfold/components/button.html +1 -1
  64. unfold/templates/unfold/components/card.html +4 -4
  65. unfold/templates/unfold/components/chart/cohort.html +1 -1
  66. unfold/templates/unfold/components/navigation.html +2 -2
  67. unfold/templates/unfold/components/separator.html +1 -1
  68. unfold/templates/unfold/components/table.html +6 -6
  69. unfold/templates/unfold/components/tracker.html +1 -1
  70. unfold/templates/unfold/helpers/account_links.html +6 -6
  71. unfold/templates/unfold/helpers/actions_row.html +5 -5
  72. unfold/templates/unfold/helpers/add_link.html +1 -1
  73. unfold/templates/unfold/helpers/app_list.html +10 -10
  74. unfold/templates/unfold/helpers/app_list_default.html +10 -10
  75. unfold/templates/unfold/helpers/boolean.html +1 -1
  76. unfold/templates/unfold/helpers/breadcrumb_item.html +1 -1
  77. unfold/templates/unfold/helpers/change_list_actions.html +13 -0
  78. unfold/templates/unfold/helpers/change_list_filter.html +31 -0
  79. unfold/templates/unfold/helpers/change_list_filter_actions.html +23 -0
  80. unfold/templates/unfold/helpers/delete_submit_line.html +2 -2
  81. unfold/templates/unfold/helpers/display_header.html +3 -3
  82. unfold/templates/unfold/helpers/edit_inline/tabular_delete.html +13 -0
  83. unfold/templates/unfold/helpers/edit_inline/tabular_error.html +8 -0
  84. unfold/templates/unfold/helpers/edit_inline/tabular_field.html +25 -0
  85. unfold/templates/unfold/helpers/edit_inline/tabular_heading.html +25 -0
  86. unfold/templates/unfold/helpers/edit_inline/tabular_row.html +27 -0
  87. unfold/templates/unfold/helpers/edit_inline/tabular_title.html +49 -0
  88. unfold/templates/unfold/helpers/field_readonly.html +1 -1
  89. unfold/templates/unfold/helpers/field_readonly_value.html +1 -1
  90. unfold/templates/unfold/helpers/fieldset_row.html +5 -73
  91. unfold/templates/unfold/helpers/fieldset_row_checkbox.html +45 -0
  92. unfold/templates/unfold/helpers/fieldset_row_field.html +21 -0
  93. unfold/templates/unfold/helpers/fieldsets_tabs.html +2 -2
  94. unfold/templates/unfold/helpers/header.html +1 -1
  95. unfold/templates/unfold/helpers/history.html +4 -4
  96. unfold/templates/unfold/helpers/label.html +1 -1
  97. unfold/templates/unfold/helpers/language_switch.html +3 -3
  98. unfold/templates/unfold/helpers/messages/debug.html +1 -1
  99. unfold/templates/unfold/helpers/messages/error.html +1 -1
  100. unfold/templates/unfold/helpers/messages/errornote.html +1 -1
  101. unfold/templates/unfold/helpers/messages/info.html +1 -1
  102. unfold/templates/unfold/helpers/messages/success.html +1 -1
  103. unfold/templates/unfold/helpers/messages/warning.html +1 -1
  104. unfold/templates/unfold/helpers/navigation.html +3 -11
  105. unfold/templates/unfold/helpers/navigation_header.html +13 -0
  106. unfold/templates/unfold/helpers/pagination_ellipsis.html +1 -1
  107. unfold/templates/unfold/helpers/search.html +5 -5
  108. unfold/templates/unfold/helpers/search_results.html +2 -2
  109. unfold/templates/unfold/helpers/site_icon.html +7 -5
  110. unfold/templates/unfold/helpers/site_logo.html +1 -1
  111. unfold/templates/unfold/helpers/submit.html +1 -1
  112. unfold/templates/unfold/helpers/tab_action.html +2 -2
  113. unfold/templates/unfold/helpers/tab_list.html +9 -9
  114. unfold/templates/unfold/helpers/theme_switch.html +5 -5
  115. unfold/templates/unfold/helpers/userlinks.html +4 -0
  116. unfold/templates/unfold/helpers/welcomemsg.html +7 -3
  117. unfold/templates/unfold/layouts/base_simple.html +2 -2
  118. unfold/templates/unfold/layouts/skeleton.html +11 -5
  119. unfold/templates/unfold/widgets/clearable_file_input.html +6 -6
  120. unfold/templates/unfold/widgets/clearable_file_input_small.html +7 -7
  121. unfold/templates/unfold/widgets/foreign_key_raw_id.html +1 -1
  122. unfold/templates/unfold/widgets/radio.html +1 -1
  123. unfold/templates/unfold/widgets/range.html +1 -1
  124. unfold/templates/unfold/widgets/related_widget_wrapper.html +4 -4
  125. unfold/templates/unfold/widgets/textarea_expandable.html +1 -1
  126. unfold/templatetags/unfold.py +104 -0
  127. unfold/templatetags/unfold_list.py +9 -4
  128. unfold/widgets.py +31 -28
  129. unfold/templates/unfold/change_list_filter.html +0 -57
  130. {django_unfold-0.43.0.dist-info → django_unfold-0.44.0.dist-info}/LICENSE.md +0 -0
@@ -0,0 +1,13 @@
1
+ <div class="border-b border-base-200 mb-5 py-3 dark:border-base-800">
2
+ <div class="flex font-semibold gap-3 h-10 items-center px-6">
3
+ {% if site_logo %}
4
+ {% include "unfold/helpers/site_logo.html" %}
5
+ {% elif branding %}
6
+ {% include "unfold/helpers/site_icon.html" %}
7
+ {% endif %}
8
+
9
+ <div class="block cursor-pointer h-4.5 ml-auto xl:!hidden hover:text-base-700 dark:hover:text-base-200" x-on:click="sidebarMobileOpen = !sidebarMobileOpen">
10
+ <span class="material-symbols-outlined">close</span>
11
+ </div>
12
+ </div>
13
+ </div>
@@ -1,3 +1,3 @@
1
- <span class="text-gray-400">
1
+ <span class="text-base-400">
2
2
  {{ ellipsis }}
3
3
  </span>
@@ -1,9 +1,9 @@
1
1
  {% load i18n %}
2
2
 
3
3
  {% if sidebar_show_search %}
4
- <div class="mb-5 mx-3 relative" x-data="{openSearchResults: false}">
5
- <div class="bg-white border flex items-center overflow-hidden rounded-md shadow-sm focus-within:ring focus-within:ring-primary-300 focus-within:border-primary-600 dark:bg-gray-900 dark:border-gray-700 dark:focus-within:border-primary-600 dark:focus-within:ring-primary-700 dark:focus-within:ring-opacity-50">
6
- <span class="material-symbols-outlined md-18 pl-3 text-gray-400">manage_search</span>
4
+ <div class="mb-2.5 mx-3 relative" x-data="{openSearchResults: false}">
5
+ <div class="bg-white border border-base-200 flex items-center overflow-hidden rounded shadow-sm focus-within:ring focus-within:ring-primary-300 focus-within:border-primary-600 dark:bg-base-900 dark:border-base-700 dark:focus-within:border-primary-600 dark:focus-within:ring-primary-700 dark:focus-within:ring-opacity-50">
6
+ <span class="material-symbols-outlined md-18 pl-3 text-base-400">manage_search</span>
7
7
 
8
8
  <input type="search"
9
9
  id="nav-filter"
@@ -14,10 +14,10 @@
14
14
  hx-trigger="keyup changed delay:500ms, search"
15
15
  hx-target="#search-results"
16
16
  hx-indicator=".htmx-indicator"
17
- class="flex-grow font-medium overflow-hidden pl-2 pr-3 py-2 text-font-default-light text-sm focus:outline-none dark:bg-gray-900 dark:text-font-default-dark"
17
+ class="flex-grow font-medium overflow-hidden pl-2 pr-3 py-2 text-font-default-light text-sm placeholder-base-400 focus:outline-none dark:bg-base-900 dark:text-font-default-dark"
18
18
  placeholder="{% translate 'Search apps and models...' %}" aria-label="{% translate 'Filter navigation items' %}" />
19
19
  <div class="absolute opacity-0 htmx-indicator mt-0.5 right-2 top-2">
20
- <span class="animate-spin material-symbols-outlined md-18 text-gray-300">sync</span>
20
+ <span class="animate-spin material-symbols-outlined md-18 text-base-300">sync</span>
21
21
  </div>
22
22
  </div>
23
23
 
@@ -1,9 +1,9 @@
1
1
  {% if results %}
2
- <ul class="absolute bg-white border left-0 mt-12 right-0 rounded top-0 shadow-sm text-sm z-10 dark:bg-gray-800 dark:border-gray-700">
2
+ <ul class="absolute bg-white border border-base-200 left-0 mt-12 right-0 rounded top-0 shadow-sm text-sm z-10 dark:bg-base-800 dark:border-base-700">
3
3
  {% for app in results %}
4
4
  {% for model in app.models %}
5
5
  <li>
6
- <a href="{{ model.admin_url }}" class="block px-3 py-2 truncate hover:text-gray-700 dark:hover:text-gray-200">
6
+ <a href="{{ model.admin_url }}" class="block px-3 py-2 truncate hover:text-base-700 dark:hover:text-base-200">
7
7
  {{ app.name }} <span class="align-text-top material-symbols-outlined md-18">arrow_right_alt</span> {{ model.name }}
8
8
  </a>
9
9
  </li>
@@ -3,17 +3,19 @@
3
3
  {% if site_icon %}
4
4
  <a href="{% url "admin:index" %}">
5
5
  {% if site_icon.light and site_icon.dark %}
6
- <img src="{{ site_icon.dark }}" alt="{% trans 'Home' %}" class="h-8 hidden mr-4 dark:block"/>
6
+ <img src="{{ site_icon.dark }}" alt="{% trans 'Home' %}" class="h-8 hidden dark:block"/>
7
7
 
8
- <img src="{{ site_icon.light }}" alt="{% trans 'Home' %}" class="block h-8 mr-4 dark:hidden" />
8
+ <img src="{{ site_icon.light }}" alt="{% trans 'Home' %}" class="block h-8 dark:hidden" />
9
9
  {% else %}
10
- <img src="{{ site_icon }}" class="h-8 mr-4" alt="{% trans 'Home' %}" />
10
+ <img src="{{ site_icon }}" class="h-8" alt="{% trans 'Home' %}" />
11
11
  {% endif %}
12
12
  </a>
13
13
  {% else %}
14
- <a href="{% url "admin:index" %}" class="bg-primary-600 flex h-8 items-center justify-center rounded-md mr-4 text-white text-xs w-8">
14
+ <a href="{% url "admin:index" %}" class="bg-primary-600 flex h-8 items-center justify-center rounded text-white text-xs w-8">
15
15
  <span class="material-symbols-outlined md-18">{% if site_symbol %}{{ site_symbol }}{% else %}settings{% endif %}</span>
16
16
  </a>
17
17
  {% endif %}
18
18
 
19
- {{ branding }}
19
+ <span class="text-font-important-light tracking-tight dark:text-font-important-dark xl:text-base">
20
+ {{ branding }}
21
+ </span>
@@ -1,6 +1,6 @@
1
1
  {% load i18n %}
2
2
 
3
- <a href="{% url "admin:index" %}">
3
+ <a href="{% url "admin:index" %}">
4
4
  {% if site_logo.light and site_logo.dark %}
5
5
  <img src="{{ site_logo.dark }}" alt="{% trans 'Home' %}" class="h-8 hidden mr-4 dark:block"/>
6
6
 
@@ -1,3 +1,3 @@
1
- <button type="submit" {% if name %}name="{{ name}}"{% endif %} class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded-md self-end text-sm text-white">
1
+ <button type="submit" {% if name %}name="{{ name}}"{% endif %} class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded self-end text-sm text-white">
2
2
  {{ title }}
3
3
  </button>
@@ -1,5 +1,5 @@
1
- <li class="border-b flex-grow text-center md:border-b-0 md:border-r last:border-0 dark:border-gray-800">
2
- <a href="{{ link }}" class="block px-4 py-2 text-left whitespace-nowrap"{% if blank %} target="_blank"{% endif %} {% include "unfold/helpers/attrs.html" with attrs=action.attrs %}>
1
+ <li class="border-b flex-grow text-center md:border-b-0 md:border-r last:border-0 dark:border-base-700">
2
+ <a href="{{ link }}" class="block px-4 py-2 text-left whitespace-nowrap hover:text-primary-600 dark:hover:text-primary-500"{% if blank %} target="_blank"{% endif %} {% include "unfold/helpers/attrs.html" with attrs=action.attrs %}>
3
3
  {{ title }}
4
4
  </a>
5
5
  </li>
@@ -2,13 +2,13 @@
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="flex items-start flex-col mb-4 text-sm w-full md:border-b dark:md:border-gray-800 md:border-l-0 md:flex-row md:items-center md:justify-end">
5
+ <div class="flex items-start flex-col mb-4 text-sm w-full md:border-b dark:md:border-base-800 md:border-l-0 md:flex-row md:items-center md:justify-end">
6
6
  {% if inlines_list or tabs_list %}
7
- <ul class="border rounded-md flex flex-col w-full md:flex-row md:border-b-0 md:border-t-0 md:border-l-0 md:border-r-0 dark:border-gray-800">
7
+ <ul class="border rounded flex flex-col w-full md:flex-row md:border-b-0 md:border-t-0 md:border-l-0 md:border-r-0 dark:border-base-800">
8
8
  {% for item in tabs_list %}
9
9
  {% if item.has_permission %}
10
- <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-gray-800">
11
- <a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}" class="block px-3 py-2 md:py-4 md:px-0 dark:border-gray-800 {% if item.active %} border-b font-semibold -mb-px text-primary-600 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-500 md:border-primary-500 dark:md:!border-primary-600{% else %}font-medium hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
10
+ <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-base-800">
11
+ <a href="{% if item.link_callback %}{{ item.link_callback }}{% else %}{{ item.link }}{% endif %}" class="block px-3 py-2 md:py-4 md:px-0 dark:border-base-800 {% if item.active %} border-b font-semibold -mb-px text-primary-600 hover:text-primary-600 dark:text-primary-500 dark:hover:text-primary-500 md:border-primary-500 dark:md:!border-primary-600{% else %}font-medium hover:text-primary-600 dark:hover:text-primary-500{% endif %}">
12
12
  {{ item.title }}
13
13
  </a>
14
14
  </li>
@@ -16,21 +16,21 @@
16
16
  {% endfor %}
17
17
 
18
18
  {% if inlines_list %}
19
- <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-gray-800">
19
+ <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-base-800">
20
20
  <a class="block cursor-pointer font-medium px-3 py-2 md:py-4 md:px-0"
21
21
  href="#general"
22
22
  x-on:click="activeTab = 'general'"
23
- x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == 'general', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-gray-800': activeTab != 'general'}">
23
+ x-bind:class="{'border-b border-base-200 dark:border-base-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == 'general', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-base-800': activeTab != 'general'}">
24
24
  {% trans "General" %}
25
25
  </a>
26
26
  </li>
27
27
 
28
28
  {% for inline in inlines_list %}
29
- <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-gray-800">
29
+ <li class="border-b last:border-b-0 md:border-b-0 md:mr-8 dark:border-base-800">
30
30
  <a class="block cursor-pointer font-medium px-3 py-2 md:py-4 md:px-0"
31
31
  href="#{{ inline.opts.verbose_name|slugify }}"
32
32
  x-on:click="activeTab = '{{ inline.opts.verbose_name|slugify }}'"
33
- x-bind:class="{'border-b border-gray-200 dark:border-gray-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ inline.opts.verbose_name|slugify }}', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-gray-800': activeTab != '{{ inline.opts.verbose_name|slugify }}'}">
33
+ x-bind:class="{'border-b border-base-200 dark:border-base-800 md:border-primary-500 dark:md:!border-primary-600 font-semibold -mb-px text-primary-600 dark:text-primary-500': activeTab == '{{ inline.opts.verbose_name|slugify }}', 'hover:text-primary-600 dark:hover:text-primary-500 dark:border-base-800': activeTab != '{{ inline.opts.verbose_name|slugify }}'}">
34
34
  {% if inline.formset.max_num == 1 %}
35
35
  {{ inline.opts.verbose_name|capfirst }}
36
36
  {% else %}
@@ -44,7 +44,7 @@
44
44
  {% endif %}
45
45
 
46
46
  {% if actions_list or actions_detail or actions_items or nav_global %}
47
- <ul class="border flex flex-col font-medium mb-4 mt-2 rounded-md shadow-sm md:flex-row md:mb-2 md:mt-0 dark:border-gray-800 max-md:w-full">
47
+ <ul class="border flex flex-col font-medium mb-4 mt-2 rounded shadow-sm md:flex-row md:mb-2 md:mt-0 dark:border-base-700 max-md:w-full">
48
48
  {% for action in actions_list %}
49
49
  {% include "unfold/helpers/tab_action.html" with title=action.title link=action.path %}
50
50
  {% endfor %}
@@ -1,28 +1,28 @@
1
1
  {% load i18n %}
2
2
 
3
3
  <div class="relative" x-data="{ openTheme: false }">
4
- <a class="block cursor-pointer leading-none hover:text-gray-700 dark:hover:text-gray-200" x-on:click="openTheme = !openTheme">
4
+ <a class="block cursor-pointer h-4.5 leading-none hover:text-base-700 dark:hover:text-base-200" x-on:click="openTheme = !openTheme">
5
5
  <span class="material-symbols-outlined">
6
6
  <span x-text="adminTheme == 'dark' && 'dark_mode' || adminTheme == 'light' && 'light_mode' || 'computer'"></span>
7
7
  </span>
8
8
  </a>
9
9
 
10
- <nav class="absolute bg-white border flex flex-col leading-none py-1 -right-2 rounded shadow-lg top-7 w-40 z-50 dark:bg-gray-800 dark:border-gray-700" x-cloak x-show="openTheme" @click.outside="openTheme = false">
11
- <a class="cursor-pointer flex flex-row leading-none mx-1 px-3 py-1.5 rounded hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-gray-200"
10
+ <nav class="absolute bg-white border flex flex-col leading-none py-1 -right-2 rounded shadow-lg top-7 w-40 z-50 dark:bg-base-800 dark:border-base-700" x-cloak x-show="openTheme" @click.outside="openTheme = false">
11
+ <a class="cursor-pointer flex flex-row leading-none mx-1 px-3 py-1.5 rounded hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
12
12
  x-on:click="adminTheme = 'dark'"
13
13
  x-bind:class="adminTheme == 'dark' && 'text-primary-600 dark:text-primary-500 dark:hover:!text-primary-500 hover:!text-primary-600'">
14
14
  <span class="material-symbols-outlined mr-2">dark_mode</span>
15
15
  <span class="leading-none self-center">{% trans "Dark" %}</span>
16
16
  </a>
17
17
 
18
- <a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-gray-200"
18
+ <a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
19
19
  x-on:click="adminTheme = 'light'"
20
20
  x-bind:class="adminTheme == 'light' && 'text-primary-600 dark:text-primary-500 dark:hover:!text-primary-500 hover:!text-primary-600'">
21
21
  <span class="material-symbols-outlined mr-2">light_mode</span>
22
22
  <span class="leading-none self-center">{% trans "Light" %}</span>
23
23
  </a>
24
24
 
25
- <a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded hover:bg-gray-100 hover:text-gray-700 dark:hover:bg-gray-700 dark:hover:text-gray-200"
25
+ <a class="cursor-pointer flex flex-row mx-1 px-3 py-1.5 rounded hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-700 dark:hover:text-base-200"
26
26
  x-on:click="adminTheme = 'auto'"
27
27
  x-bind:class="adminTheme == 'auto' && 'text-primary-600 dark:text-primary-500 dark:hover:!text-primary-500 hover:!text-primary-600'">
28
28
  <span class="material-symbols-outlined mr-2">computer</span>
@@ -7,6 +7,10 @@
7
7
  {% include "unfold/helpers/label.html" with text=environment.0 type=environment.1 %}
8
8
  {% endif %}
9
9
 
10
+ {% if extra_userlinks %}
11
+ {{ extra_userlinks }}
12
+ {% endif %}
13
+
10
14
  {% if show_languages %}
11
15
  {% include "unfold/helpers/language_switch.html" %}
12
16
  {% endif %}
@@ -1,13 +1,17 @@
1
1
  {% load i18n %}
2
2
 
3
3
  <div class="flex flex-row flex-grow font-semibold items-center min-w-0 mr-3">
4
- <span class="cursor-pointer hidden flex-row items-center text-sm xl:flex">
5
- <span class="material-symbols-outlined" hx-get="{% url "admin:toggle_sidebar" %}" hx-swap="none" x-on:click="sidebarDesktopOpen = !sidebarDesktopOpen">
4
+ <span class="cursor-pointer flex flex-row items-center">
5
+ <span class="material-symbols-outlined !hidden xl:!block" hx-get="{% url "admin:toggle_sidebar" %}" hx-swap="none" x-on:click="sidebarDesktopOpen = !sidebarDesktopOpen">
6
+ dock_to_right
7
+ </span>
8
+
9
+ <span class="material-symbols-outlined !block xl:!hidden" x-on:click="sidebarMobileOpen = !sidebarMobileOpen">
6
10
  dock_to_right
7
11
  </span>
8
12
  </span>
9
13
 
10
- <span class="hidden bg-gray-200 h-5 mx-3 w-px xl:block dark:bg-gray-700"></span>
14
+ <span class="block bg-base-200 h-5 mx-3 w-px dark:bg-base-700"></span>
11
15
 
12
16
  <h1 class="overflow-hidden text-ellipsis text-sm whitespace-nowrap xl:text-base text-font-important-light dark:text-font-important-dark">
13
17
  {% if content_title %}
@@ -3,14 +3,14 @@
3
3
  {% load i18n %}
4
4
 
5
5
  {% block base %}
6
- <div class="flex min-h-screen">
6
+ <div id="page" class="flex min-h-screen">
7
7
  {% if not is_popup and is_nav_sidebar_enabled %}
8
8
  {% block nav-sidebar %}
9
9
  {% include "admin/nav_sidebar.html" %}
10
10
  {% endblock %}
11
11
  {% endif %}
12
12
 
13
- <div id="main" class="shadow flex-grow min-w-0">
13
+ <div id="main" class="flex-grow min-w-0" x-resize="mainWidth = $width">
14
14
  {% block content_before %}
15
15
  {% include "unfold/helpers/header.html" %}
16
16
  {% endblock %}
@@ -10,9 +10,10 @@
10
10
  {% capture as nav_global silent %}{% block nav-global %}{% endblock %}{% endcapture %}
11
11
  {% capture as nav_global_side silent %}{% block nav-global-side %}{% endblock %}{% endcapture %}
12
12
  {% capture as actions_items silent %}{% block actions-items %}{% endblock %}{% endcapture %}
13
+ {% capture as extra_userlinks silent %}{% block extra_userlinks %}{% endblock %}{% endcapture %}
13
14
 
14
15
  <!DOCTYPE html>
15
- <html lang="{{ LANGUAGE_CODE|default:"en-us" }}" dir="{{ LANGUAGE_BIDI|yesno:"rtl,ltr,auto" }}" {% if theme %}class="{{ theme }}"{% else %}x-data="{ adminTheme: $persist('auto').as('adminTheme') }" x-bind:class="{'dark': adminTheme === 'dark' || (adminTheme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)}" x-cloak{% endif %}>
16
+ <html lang="{{ LANGUAGE_CODE|default:"en-us" }}" dir="{{ LANGUAGE_BIDI|yesno:"rtl,ltr,auto" }}" {% if theme %}class="{{ theme }}"{% endif %} x-data="{ adminTheme: {% if theme %}'{{ theme }}'{% else %}$persist('auto').as('adminTheme'){% endif %} }" x-bind:class="{'dark': adminTheme === 'dark' || (adminTheme === 'auto' && window.matchMedia('(prefers-color-scheme: dark)').matches)}" x-cloak>
16
17
 
17
18
  <head>
18
19
  <title>{% block title %}{% endblock %}</title>
@@ -34,6 +35,7 @@
34
35
  <script src="{% static 'unfold/js/alpine.anchor.js' %}" defer></script>
35
36
  <script src="{% static 'unfold/js/alpine.persist.js' %}" defer></script>
36
37
  <script src="{% static 'unfold/js/alpine.sort.js' %}" defer></script>
38
+ <script src="{% static 'unfold/js/alpine.resize.js' %}" defer></script>
37
39
  <script src="{% static 'unfold/js/alpine.js' %}" defer></script>
38
40
  <script src="{% static 'unfold/js/htmx.js' %}"></script>
39
41
  <script src="{% static 'unfold/js/chart.js' %}"></script>
@@ -55,10 +57,16 @@
55
57
  {% block blockbots %}
56
58
  <meta name="robots" content="NONE,NOARCHIVE">
57
59
  {% endblock %}
60
+ </head>
58
61
 
62
+ <body class="antialiased bg-white font-sans text-font-default-light text-sm dark:bg-base-900 dark:text-font-default-dark {% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}" data-admin-utc-offset="{% now "Z" %}" x-data="{ mainWidth: 0, activeTab: 'general', sidebarMobileOpen: false, sidebarDesktopOpen: {% if request.session.toggle_sidebar == False %}false{% else %}true{% endif %} }" x-init="activeTab = window.location.hash?.replace('#', '') || 'general'">
59
63
  {% if colors %}
60
- <style>
64
+ <style id="unfold-theme-colors">
61
65
  :root {
66
+ {% if border_radius %}
67
+ --border-radius: {{ border_radius }};
68
+ {% endif %}
69
+
62
70
  {% for name, weights in colors.items %}
63
71
  {% for weight, value in weights.items %}
64
72
  --color-{{ name }}-{{ weight }}: {{ value }};
@@ -67,12 +75,10 @@
67
75
  }
68
76
  </style>
69
77
  {% endif %}
70
- </head>
71
78
 
72
- <body class="antialiased bg-white font-sans text-font-default-light text-sm dark:bg-gray-900 dark:text-font-default-dark {% if is_popup %}popup {% endif %}{% block bodyclass %}{% endblock %}" data-admin-utc-offset="{% now "Z" %}" x-data="{ activeTab: 'general', sidebarMobileOpen: false, sidebarDesktopOpen: {% if request.session.toggle_sidebar == False %}false{% else %}true{% endif %} }" x-init="activeTab = window.location.hash?.replace('#', '') || 'general'">
73
79
  {% block base %}{% endblock %}
74
80
 
75
- <div id="modal-overlay" class="backdrop-blur-sm bg-opacity-80 bg-gray-900 bottom-0 fixed hidden left-0 mr-1 right-0 top-0 z-50"></div>
81
+ <div id="modal-overlay" class="backdrop-blur-sm bg-opacity-80 bg-base-900 bottom-0 fixed hidden left-0 mr-1 right-0 top-0 z-50"></div>
76
82
  <script src="{% static 'unfold/js/simplebar.js' %}"></script>
77
83
  </body>
78
84
 
@@ -8,9 +8,9 @@
8
8
  </div>
9
9
  {% endif %}
10
10
 
11
- <div class="border flex items-center overflow-hidden rounded-md shadow-sm text-sm max-w-2xl dark:border-gray-700">
11
+ <div class="border border-base-200 flex items-center overflow-hidden rounded shadow-sm text-sm max-w-2xl dark:border-base-700">
12
12
  {% if widget.is_initial and not widget.required %}
13
- <div class="bg-gray-50 border-r flex flex-none items-center self-stretch px-3 dark:bg-white/[.02] dark:border-gray-700 dark:text-font-default-dark">
13
+ <div class="bg-base-50 border-r border-base-200 flex flex-none items-center self-stretch px-3 dark:bg-white/[.02] dark:border-base-700 dark:text-font-default-dark">
14
14
  <label for="{{ widget.checkbox_id }}" class="flex items-center">
15
15
  <input type="checkbox"{% if widget.class %} class="{{ widget.class }}"{% endif %} name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}" />
16
16
 
@@ -21,20 +21,20 @@
21
21
  </div>
22
22
  {% endif %}
23
23
 
24
- <input type="text" aria-label="{% trans 'Choose file to upload' %}" value="{% if widget.value %}{{ widget.value.url }}{% else %}{% trans 'Choose file to upload' %}{% endif %}" disabled class="bg-white flex-grow font-medium min-w-0 px-3 py-2 text-ellipsis dark:bg-gray-900">
24
+ <input type="text" aria-label="{% trans 'Choose file to upload' %}" value="{% if widget.value %}{{ widget.value.url }}{% else %}{% trans 'Choose file to upload' %}{% endif %}" disabled class="bg-white flex-grow font-medium min-w-0 px-3 py-2 text-ellipsis dark:bg-base-900">
25
25
 
26
- <div class="flex flex-none items-center leading-none self-stretch">
26
+ <div class="bg-white flex flex-none items-center leading-none self-stretch dark:bg-base-900">
27
27
  <div class="hidden">
28
28
  <input type="{{ widget.type }}" name="{{ widget.name }}" {% include "django/forms/widgets/attrs.html" %} />
29
29
  </div>
30
30
 
31
31
  {% if widget.is_initial %}
32
- <a href="{{ widget.value.url }}" class="border-r cursor-pointer text-gray-400 px-3 hover:text-gray-700 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200" target="_blank">
32
+ <a href="{{ widget.value.url }}" class="border-r border-base-200 cursor-pointer text-base-400 px-3 hover:text-base-700 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200" target="_blank">
33
33
  <span class="material-symbols-outlined">download</span>
34
34
  </a>
35
35
  {% endif %}
36
36
 
37
- <label for="{{ widget.attrs.id }}" class="cursor-pointer text-gray-400 px-3 hover:text-gray-700 dark:text-gray-500 dark:hover:text-gray-200">
37
+ <label for="{{ widget.attrs.id }}" class="cursor-pointer text-base-400 px-3 hover:text-base-700 dark:text-base-500 dark:hover:text-base-200">
38
38
  <span class="material-symbols-outlined">upload</span>
39
39
  </label>
40
40
  </div>
@@ -1,9 +1,9 @@
1
1
  {% load i18n static %}
2
2
 
3
3
  <div class="flex flex-row">
4
- <div class="border flex items-center overflow-hidden rounded-md shadow-sm text-sm max-w-2xl w-full focus-within:ring focus-within:ring-primary-300 focus-within:border-primary-600 dark:border-gray-700 dark:focus-within:border-primary-600 dark:focus-within:ring-primary-700 dark:focus-within:ring-opacity-50">
4
+ <div class="border border-base-200 flex items-center overflow-hidden rounded shadow-sm text-sm max-w-2xl w-full focus-within:ring focus-within:ring-primary-300 focus-within:border-primary-600 dark:border-base-700 dark:focus-within:border-primary-600 dark:focus-within:ring-primary-700 dark:focus-within:ring-opacity-50">
5
5
  {% if widget.is_initial and not widget.required %}
6
- <div class="bg-gray-50 border-r flex flex-none items-center self-stretch px-3 dark:bg-gray-900 dark:border-r-gray-700">
6
+ <div class="bg-base-50 border-r border-base-200 flex flex-none items-center self-stretch px-3 dark:bg-base-900 dark:border-r-gray-700">
7
7
  <label for="{{ widget.checkbox_id }}" class="flex items-center">
8
8
  <input type="checkbox"{% if widget.class %} class="{{ widget.class }}"{% endif %} name="{{ widget.checkbox_name }}" id="{{ widget.checkbox_id }}" />
9
9
 
@@ -14,7 +14,7 @@
14
14
  </div>
15
15
  {% endif %}
16
16
 
17
- <input type="text" aria-label="{% trans 'Choose file to upload' %}" value="{% if widget.value %}{{ widget.value.url }}{% else %}{% trans 'Choose file to upload' %}{% endif %}" disabled class="bg-white flex-grow font-medium min-w-0 px-3 py-2 text-ellipsis dark:bg-gray-900">
17
+ <input type="text" aria-label="{% trans 'Choose file to upload' %}" value="{% if widget.value %}{{ widget.value.url }}{% else %}{% trans 'Choose file to upload' %}{% endif %}" disabled class="bg-white flex-grow font-medium min-w-0 px-3 py-2 text-ellipsis dark:bg-base-900">
18
18
 
19
19
  <div class="flex flex-none items-center leading-none self-stretch">
20
20
  <div class="hidden">
@@ -22,12 +22,12 @@
22
22
  </div>
23
23
 
24
24
  {% if widget.is_initial %}
25
- <a href="{{ widget.value.url }}" class="border-r cursor-pointer text-gray-400 px-3 hover:text-gray-700 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200" target="_blank">
25
+ <a href="{{ widget.value.url }}" class="border-r border-base-200 cursor-pointer text-base-400 px-3 hover:text-base-700 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200" target="_blank">
26
26
  <span class="material-symbols-outlined">download</span>
27
27
  </a>
28
28
  {% endif %}
29
29
 
30
- <label for="{{ widget.attrs.id }}" class="cursor-pointer text-gray-400 px-3 hover:text-gray-700 dark:text-gray-500 dark:hover:text-gray-200">
30
+ <label for="{{ widget.attrs.id }}" class="cursor-pointer text-base-400 px-3 hover:text-base-700 dark:text-base-500 dark:hover:text-base-200">
31
31
  <span class="material-symbols-outlined">file_upload</span>
32
32
  </label>
33
33
  </div>
@@ -35,11 +35,11 @@
35
35
 
36
36
  {% if widget.attrs.accept == 'image/*' and widget.is_initial %}
37
37
  <div class="h-9.5 ml-3 relative w-9.5">
38
- <div class="absolute border flex font-medium h-full items-center left-0 rounded-md justify-center shadow-sm text-gray-400 top-0 w-full z-10 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-500">
38
+ <div class="absolute border flex font-medium h-full items-center left-0 rounded justify-center shadow-sm text-base-400 top-0 w-full z-10 dark:bg-base-900 dark:border-base-700 dark:text-base-500">
39
39
  ?
40
40
  </div>
41
41
 
42
- <a href="{{ widget.value.url }}" target="_blank" class="bg-center bg-cover bg-no-repeat block h-9.5 overflow-hidden relative rounded-md w-9.5 z-20" style="background-image: url('{{ widget.value.url }}')">
42
+ <a href="{{ widget.value.url }}" target="_blank" class="bg-center bg-cover bg-no-repeat block h-9.5 overflow-hidden relative rounded w-9.5 z-20" style="background-image: url('{{ widget.value.url }}')">
43
43
  </a>
44
44
  </div>
45
45
  {% endif %}
@@ -2,7 +2,7 @@
2
2
  {% include 'django/forms/widgets/input.html' %}
3
3
 
4
4
  {% if related_url %}
5
- <a href="{{ related_url }}" class="related-lookup view-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-gray-400 text-sm w-9.5 hover:text-gray-700 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200" id="lookup_id_{{ widget.name }}">
5
+ <a href="{{ related_url }}" class="related-lookup view-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-base-400 text-sm w-9.5 hover:text-base-700 dark:bg-base-900 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200" id="lookup_id_{{ widget.name }}">
6
6
  <span class="material-symbols-outlined text-sm">search</span>
7
7
  </a>
8
8
  {% endif %}
@@ -1,5 +1,5 @@
1
1
  {% with id=widget.attrs.id %}
2
- <div{% if id %} id="{{ id }}"{% endif %} class="flex gap-2 {% if radio_style == 1 %} flex-row{% else %} flex-col{% endif %}">
2
+ <div{% if id %} id="{{ id }}"{% endif %} class="flex gap-2 {% if radio_style == 1 %} flex-row gap-4{% else %} flex-col{% endif %}">
3
3
  {% for group, options, index in widget.optgroups %}
4
4
  {% if group %}
5
5
  <div>
@@ -3,7 +3,7 @@
3
3
  {% include widget.template_name %}
4
4
 
5
5
  {% if forloop.first %}
6
- <div class="px-4 text-gray-300">
6
+ <div class="px-4 text-base-300">
7
7
  -
8
8
  </div>
9
9
  {% endif %}
@@ -9,7 +9,7 @@
9
9
  {% if not is_hidden %}
10
10
  {% if can_add_related or can_change_related or can_delete_related or can_view_related%}
11
11
  {% if can_change_related %}
12
- <a class="related-widget-wrapper-link change-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-gray-400 text-sm w-9.5 hover:text-gray-700 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200"
12
+ <a class="related-widget-wrapper-link change-related bg-white border border-base-200 cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-base-400 text-sm w-9.5 hover:text-base-700 dark:bg-base-900 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200"
13
13
  id="change_id_{{ name }}"
14
14
  data-popup="yes"
15
15
  data-href-template="{{ change_related_template_url }}?{{ url_params }}"
@@ -19,7 +19,7 @@
19
19
  {% endif %}
20
20
 
21
21
  {% if can_add_related %}
22
- <a class="related-widget-wrapper-link add-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-gray-400 text-sm w-9.5 hover:text-gray-700 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200"
22
+ <a class="related-widget-wrapper-link add-related bg-white border border-base-200 cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-base-400 text-sm w-9.5 hover:text-base-700 dark:bg-base-900 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200"
23
23
  data-popup="yes"
24
24
  id="add_id_{{ name }}"
25
25
  href="{{ add_related_url }}?{{ url_params }}"
@@ -29,7 +29,7 @@
29
29
  {% endif %}
30
30
 
31
31
  {% if can_view_related %}
32
- <a class="related-widget-wrapper-link view-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-gray-400 text-sm w-9.5 hover:text-gray-700 dark:bg-gray-900 dark:border-gray-700 dark:text-gray-500 dark:hover:text-gray-200"
32
+ <a class="related-widget-wrapper-link view-related bg-white border border-base-200 cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-base-400 text-sm w-9.5 hover:text-base-700 dark:bg-base-900 dark:border-base-700 dark:text-base-500 dark:hover:text-base-200"
33
33
  id="view_id_{{ name }}"
34
34
  data-href-template="{{ change_related_template_url }}?{{ view_related_url_params }}"
35
35
  title="{% blocktranslate %}View selected {{ model }}{% endblocktranslate %}">
@@ -38,7 +38,7 @@
38
38
  {% endif %}
39
39
 
40
40
  {% if can_delete_related %}
41
- <a class="related-widget-wrapper-link delete-related bg-white border cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-red-600 text-sm w-9.5 dark:bg-gray-900 dark:border-gray-700 dark:text-red-500"
41
+ <a class="related-widget-wrapper-link delete-related bg-white border border-base-200 cursor-pointer flex items-center h-9.5 justify-center ml-2 rounded shadow-sm shrink-0 text-red-600 text-sm w-9.5 dark:bg-base-900 dark:border-base-700 dark:text-red-500"
42
42
  id="delete_id_{{ name }}"
43
43
  data-href-template="{{ delete_related_template_url }}?{{ url_params }}"
44
44
  data-popup="yes"
@@ -1,5 +1,5 @@
1
1
  <div class="relative">
2
- <div class="border break-words font-medium invisible max-w-4xl px-3 py-2 text-sm" style="min-height: 64px">
2
+ <div class="border border-base-200 break-words font-medium invisible max-w-4xl px-3 py-2 text-sm" style="min-height: 64px">
3
3
  {% if widget.value %}{{ widget.value|linebreaks }}{% endif %}
4
4
  </div>
5
5
 
@@ -270,3 +270,107 @@ def preserve_changelist_filters(context: Context) -> Dict[str, Dict[str, str]]:
270
270
  }
271
271
 
272
272
  return {"params": preserved_params}
273
+
274
+
275
+ @register.simple_tag(takes_context=True)
276
+ def fieldset_rows_classes(context: Context) -> str:
277
+ classes = [
278
+ "aligned",
279
+ ]
280
+
281
+ if not context.get("stacked"):
282
+ classes.extend(
283
+ [
284
+ "border",
285
+ "border-base-200",
286
+ "mb-8",
287
+ "rounded",
288
+ "shadow-sm",
289
+ "dark:border-base-800",
290
+ ]
291
+ )
292
+
293
+ return " ".join(set(classes))
294
+
295
+
296
+ @register.simple_tag(takes_context=True)
297
+ def fieldset_row_classes(context: Context) -> str:
298
+ classes = [
299
+ "field-row",
300
+ "group/row",
301
+ ]
302
+
303
+ formset = context.get("inline_admin_formset", None)
304
+ adminform = context.get("adminform", None)
305
+ line = context.get("line")
306
+
307
+ # Hide the field in case of ordering field for sorting
308
+ for field in line:
309
+ if (
310
+ formset
311
+ and hasattr(field.field, "name")
312
+ and field.field.name == formset.opts.ordering_field
313
+ and formset.opts.hide_ordering_field
314
+ ):
315
+ classes.append("hidden")
316
+
317
+ # Compressed fields special styling
318
+ if adminform and adminform.model_admin.compressed_fields:
319
+ classes.extend(
320
+ [
321
+ "lg:border-b",
322
+ "lg:border-base-200",
323
+ "dark:lg:border-base-800",
324
+ "last:lg:border-b-0",
325
+ ]
326
+ )
327
+
328
+ if len(line.fields) > 1:
329
+ classes.extend(
330
+ [
331
+ "flex",
332
+ "flex-row",
333
+ "flex-wrap",
334
+ ]
335
+ )
336
+
337
+ if not line.has_visible_field:
338
+ classes.append("hidden")
339
+
340
+ return " ".join(set(classes))
341
+
342
+
343
+ @register.simple_tag(takes_context=True)
344
+ def fieldset_line_classes(context: Context) -> str:
345
+ classes = [
346
+ "field-line",
347
+ "flex",
348
+ "flex-col",
349
+ "flex-grow",
350
+ "group/line",
351
+ "p-3",
352
+ ]
353
+ field = context.get("field")
354
+ adminform = context.get("adminform")
355
+
356
+ if hasattr(field.field, "name") and field.field.name:
357
+ classes.append(f"field-{field.field.name}")
358
+
359
+ if hasattr(field, "errors") and field.errors():
360
+ classes.append("errors")
361
+
362
+ if adminform.model_admin.compressed_fields:
363
+ classes.extend(
364
+ [
365
+ "border-b",
366
+ "border-base-200",
367
+ "group-[.last]/row:border-b-0",
368
+ "lg:border-b-0",
369
+ "lg:border-l",
370
+ "lg:flex-row",
371
+ "dark:border-base-800",
372
+ "first:lg:border-l-0",
373
+ ]
374
+ )
375
+
376
+ return " ".join(set(classes))