django-unfold 0.53.0__py3-none-any.whl → 0.55.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 (56) hide show
  1. {django_unfold-0.53.0.dist-info → django_unfold-0.55.0.dist-info}/METADATA +24 -11
  2. {django_unfold-0.53.0.dist-info → django_unfold-0.55.0.dist-info}/RECORD +56 -33
  3. {django_unfold-0.53.0.dist-info → django_unfold-0.55.0.dist-info}/WHEEL +1 -1
  4. unfold/contrib/filters/admin/__init__.py +17 -0
  5. unfold/contrib/filters/admin/choice_filters.py +173 -0
  6. unfold/contrib/filters/admin/dropdown_filters.py +15 -1
  7. unfold/contrib/filters/admin/mixins.py +25 -0
  8. unfold/contrib/filters/forms.py +41 -3
  9. unfold/contrib/filters/templates/unfold/filters/filters_date_range.html +1 -1
  10. unfold/contrib/filters/templates/unfold/filters/filters_datetime_range.html +1 -1
  11. unfold/layout.py +23 -0
  12. unfold/sites.py +17 -6
  13. unfold/static/admin/js/inlines.js +23 -3
  14. unfold/static/unfold/css/styles.css +1 -1
  15. unfold/static/unfold/fonts/material-symbols/LICENSE +202 -0
  16. unfold/static/unfold/fonts/material-symbols/Material-Symbols-Outlined.woff2 +0 -0
  17. unfold/static/unfold/js/alpine.js +2 -2
  18. unfold/static/unfold/js/select2.init.js +4 -0
  19. unfold/styles.css +2 -1
  20. unfold/templates/admin/change_list.html +15 -13
  21. unfold/templates/admin/change_list_results.html +1 -1
  22. unfold/templates/admin/edit_inline/tabular.html +1 -2
  23. unfold/templates/unfold/components/button.html +1 -1
  24. unfold/templates/unfold/components/chart/cohort.html +2 -2
  25. unfold/templates/unfold/helpers/change_list_filter.html +2 -2
  26. unfold/templates/unfold/helpers/change_list_filter_actions.html +28 -26
  27. unfold/templates/unfold/helpers/edit_inline/tabular_field.html +10 -8
  28. unfold/templates/unfold/helpers/field.html +4 -2
  29. unfold/templates/unfold/helpers/form_label.html +1 -1
  30. unfold/templates/unfold/helpers/tab_action.html +17 -2
  31. unfold/templates/unfold/widgets/clearable_file_input.html +1 -1
  32. unfold/templates/unfold/widgets/clearable_file_input_small.html +1 -1
  33. unfold/templates/unfold/widgets/radio_option.html +1 -1
  34. unfold/templates/unfold_crispy/display_form.html +9 -0
  35. unfold/templates/unfold_crispy/errors.html +3 -0
  36. unfold/templates/unfold_crispy/field.html +23 -0
  37. unfold/templates/unfold_crispy/inputs.html +7 -0
  38. unfold/templates/unfold_crispy/layout/attrs.html +1 -0
  39. unfold/templates/unfold_crispy/layout/baseinput.html +9 -0
  40. unfold/templates/unfold_crispy/layout/button.html +1 -0
  41. unfold/templates/unfold_crispy/layout/buttonholder.html +3 -0
  42. unfold/templates/unfold_crispy/layout/checkbox.html +19 -0
  43. unfold/templates/unfold_crispy/layout/column.html +3 -0
  44. unfold/templates/unfold_crispy/layout/div.html +4 -0
  45. unfold/templates/unfold_crispy/layout/field_errors.html +7 -0
  46. unfold/templates/unfold_crispy/layout/fieldset.html +9 -0
  47. unfold/templates/unfold_crispy/layout/help_text.html +5 -0
  48. unfold/templates/unfold_crispy/layout/help_text_and_errors.html +3 -0
  49. unfold/templates/unfold_crispy/layout/radio_checkbox_select.html +21 -0
  50. unfold/templates/unfold_crispy/layout/row.html +3 -0
  51. unfold/templates/unfold_crispy/layout/table_inline_formset.html +100 -0
  52. unfold/templates/unfold_crispy/uni_form.html +11 -0
  53. unfold/templates/unfold_crispy/whole_uni_form.html +14 -0
  54. unfold/templatetags/unfold.py +26 -14
  55. unfold/widgets.py +88 -1
  56. {django_unfold-0.53.0.dist-info → django_unfold-0.55.0.dist-info}/LICENSE.md +0 -0
unfold/widgets.py CHANGED
@@ -33,6 +33,20 @@ from django.utils.translation import gettext_lazy as _
33
33
 
34
34
  from .exceptions import UnfoldException
35
35
 
36
+ BUTTON_CLASSES = [
37
+ "border",
38
+ "cursor-pointer",
39
+ "font-medium",
40
+ "px-3",
41
+ "py-2",
42
+ "rounded",
43
+ "text-center",
44
+ "whitespace-nowrap",
45
+ "bg-primary-600",
46
+ "border-transparent",
47
+ "text-white",
48
+ ]
49
+
36
50
  LABEL_CLASSES = [
37
51
  "block",
38
52
  "font-semibold",
@@ -106,7 +120,7 @@ TEXTAREA_CLASSES = [
106
120
  TEXTAREA_EXPANDABLE_CLASSES = [
107
121
  "block",
108
122
  "field-sizing-content",
109
- "!max-w-2xl",
123
+ "min-h-[38px]",
110
124
  ]
111
125
 
112
126
  SELECT_CLASSES = [
@@ -146,6 +160,7 @@ CHECKBOX_CLASSES = [
146
160
  "border-base-300",
147
161
  "cursor-pointer",
148
162
  "h-4",
163
+ "min-w-4",
149
164
  "relative",
150
165
  "rounded-[4px]",
151
166
  "shadow-sm",
@@ -189,6 +204,7 @@ RADIO_CLASSES = [
189
204
  "border-base-300",
190
205
  "cursor-pointer",
191
206
  "h-4",
207
+ "min-w-4",
192
208
  "relative",
193
209
  "rounded-full",
194
210
  "w-4",
@@ -252,6 +268,28 @@ SWITCH_CLASSES = [
252
268
  "dark:checked:bg-green-700",
253
269
  ]
254
270
 
271
+ FILE_CLASSES = [
272
+ "border",
273
+ "border-base-200",
274
+ "flex",
275
+ "grow",
276
+ "items-center",
277
+ "overflow-hidden",
278
+ "rounded",
279
+ "shadow-sm",
280
+ "max-w-2xl",
281
+ "focus-within:ring",
282
+ "group-[.errors]:border-red-600",
283
+ "group-[.errors]:focus-within:ring-red-200",
284
+ "focus-within:ring-primary-300",
285
+ "focus-within:border-primary-600",
286
+ "dark:border-base-700",
287
+ "dark:focus-within:border-primary-600",
288
+ "dark:focus-within:ring-primary-700",
289
+ "dark:group-[.errors]:border-red-500",
290
+ "dark:group-[.errors]:focus-within:ring-red-600/40",
291
+ ]
292
+
255
293
 
256
294
  class UnfoldAdminTextInputWidget(AdminTextInputWidget):
257
295
  def __init__(self, attrs: Optional[dict[str, Any]] = None) -> None:
@@ -340,9 +378,11 @@ class UnfoldAdminEmailInputWidget(AdminEmailInputWidget):
340
378
  class FileFieldMixin:
341
379
  def get_context(self, name, value, attrs):
342
380
  widget = super().get_context(name, value, attrs)
381
+
343
382
  widget["widget"].update(
344
383
  {
345
384
  "class": " ".join([*CHECKBOX_CLASSES, *["form-check-input"]]),
385
+ "file_wrapper_class": " ".join(FILE_CLASSES),
346
386
  "file_input_class": " ".join(
347
387
  [
348
388
  self.attrs.get("class", ""),
@@ -354,6 +394,7 @@ class FileFieldMixin:
354
394
  ),
355
395
  }
356
396
  )
397
+
357
398
  return widget
358
399
 
359
400
 
@@ -388,6 +429,13 @@ class UnfoldAdminDateWidget(AdminDateWidget):
388
429
  }
389
430
  super().__init__(attrs=attrs, format=format)
390
431
 
432
+ class Media:
433
+ js = [
434
+ "admin/js/core.js",
435
+ "admin/js/calendar.js",
436
+ "admin/js/admin/DateTimeShortcuts.js",
437
+ ]
438
+
391
439
 
392
440
  class UnfoldAdminSingleDateWidget(AdminDateWidget):
393
441
  template_name = "unfold/widgets/date.html"
@@ -428,6 +476,13 @@ class UnfoldAdminTimeWidget(AdminTimeWidget):
428
476
  }
429
477
  super().__init__(attrs=attrs, format=format)
430
478
 
479
+ class Media:
480
+ js = [
481
+ "admin/js/core.js",
482
+ "admin/js/calendar.js",
483
+ "admin/js/admin/DateTimeShortcuts.js",
484
+ ]
485
+
431
486
 
432
487
  class UnfoldAdminSingleTimeWidget(AdminTimeWidget):
433
488
  template_name = "unfold/widgets/time.html"
@@ -500,6 +555,13 @@ class UnfoldAdminSplitDateTimeWidget(AdminSplitDateTime):
500
555
  ]
501
556
  MultiWidget.__init__(self, widgets, attrs)
502
557
 
558
+ class Media:
559
+ js = [
560
+ "admin/js/core.js",
561
+ "admin/js/calendar.js",
562
+ "admin/js/admin/DateTimeShortcuts.js",
563
+ ]
564
+
503
565
 
504
566
  class UnfoldAdminSplitDateTimeVerticalWidget(AdminSplitDateTime):
505
567
  template_name = "unfold/widgets/split_datetime_vertical.html"
@@ -597,6 +659,31 @@ class UnfoldAdminSelectWidget(Select):
597
659
  super().__init__(attrs, choices)
598
660
 
599
661
 
662
+ class UnfoldAdminSelect2Widget(Select):
663
+ def __init__(self, attrs=None, choices=()):
664
+ if attrs is None:
665
+ attrs = {}
666
+
667
+ attrs["data-theme"] = "admin-autocomplete"
668
+ attrs["class"] = "unfold-admin-autocomplete admin-autocomplete"
669
+
670
+ super().__init__(attrs, choices)
671
+
672
+ class Media:
673
+ js = (
674
+ "admin/js/vendor/jquery/jquery.js",
675
+ "admin/js/vendor/select2/select2.full.js",
676
+ "admin/js/jquery.init.js",
677
+ "unfold/js/select2.init.js",
678
+ )
679
+ css = {
680
+ "screen": (
681
+ "admin/css/vendor/select2/select2.css",
682
+ "admin/css/autocomplete.css",
683
+ ),
684
+ }
685
+
686
+
600
687
  class UnfoldAdminSelectMultipleWidget(SelectMultiple):
601
688
  def __init__(self, attrs=None, choices=()):
602
689
  if attrs is None: