django-unfold 0.57.0__py3-none-any.whl → 0.58.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 (27) hide show
  1. {django_unfold-0.57.0.dist-info → django_unfold-0.58.0.dist-info}/METADATA +1 -1
  2. {django_unfold-0.57.0.dist-info → django_unfold-0.58.0.dist-info}/RECORD +27 -27
  3. unfold/contrib/import_export/templates/admin/import_export/base.html +1 -5
  4. unfold/contrib/import_export/templates/admin/import_export/import_form.html +1 -1
  5. unfold/contrib/simple_history/templates/simple_history/object_history_form.html +1 -1
  6. unfold/decorators.py +1 -2
  7. unfold/sites.py +64 -41
  8. unfold/static/unfold/css/styles.css +2 -2
  9. unfold/styles.css +50 -91
  10. unfold/templates/admin/auth/user/change_password.html +1 -1
  11. unfold/templates/admin/submit_line.html +7 -7
  12. unfold/templates/registration/password_change_done.html +1 -1
  13. unfold/templates/registration/password_change_form.html +1 -1
  14. unfold/templates/unfold/components/card.html +23 -23
  15. unfold/templates/unfold/components/progress.html +9 -7
  16. unfold/templates/unfold/components/table.html +5 -5
  17. unfold/templates/unfold/helpers/change_list_filter_actions.html +1 -1
  18. unfold/templates/unfold/helpers/field.html +2 -2
  19. unfold/templates/unfold/helpers/navigation.html +1 -1
  20. unfold/templates/unfold_crispy/field.html +1 -1
  21. unfold/templates/unfold_crispy/layout/checkbox.html +2 -2
  22. unfold/templates/unfold_crispy/layout/fieldset.html +1 -1
  23. unfold/templates/unfold_crispy/layout/table_inline_formset.html +18 -16
  24. unfold/templatetags/unfold.py +14 -0
  25. unfold/widgets.py +2 -2
  26. {django_unfold-0.57.0.dist-info → django_unfold-0.58.0.dist-info}/LICENSE.md +0 -0
  27. {django_unfold-0.57.0.dist-info → django_unfold-0.58.0.dist-info}/WHEEL +0 -0
unfold/styles.css CHANGED
@@ -2,19 +2,29 @@
2
2
  @plugin '@tailwindcss/typography';
3
3
  @custom-variant dark (&:where(.dark, .dark *));
4
4
  @source inline("h-3 w-3 h-[64px] w-[65px]! left-[65px] dark:hover:bg-white/[.06] translate-x-1/4 -translate-y-1/4");
5
- @source inline("{-,}{top,bottom,left,right}-{0..4}");
6
- @source inline("rounded-{t,r,b,l}-default");
5
+ @source inline("{-,}{top,bottom,left,right}-{0..6}");
6
+ @source inline("rounded rounded-{t,r,b,l} rounded-{t,r,b,l}-default");
7
7
  @source inline("{md:,lg:,2xl:,}relative {md:,lg:,2xl:,}flex {md:,lg:,2xl:,}absolute {md:,lg:,2xl:,}sticky");
8
- @source inline("{-,}m{t,r,b,l,x,y,}-{0..4} {-,}p{t,r,b,l,x,y,}-{0..4}");
8
+ @source inline("{-,}m{t,r,b,l,x,y,}-{0..6} {-,}p{t,r,b,l,x,y,}-{0..6}");
9
9
  @source inline("{md:,lg:,}border-{0,2} {md:,lg:,}border-{t,r,b,l}-{0,2}");
10
10
  @source inline("{hover:,dark:,}bg-primary-{50,{100..900..100},950}");
11
11
  @source inline("{hover:,dark:,}border-base-{50,{100..900..100},950} {hover:,dark:,}border-transparent");
12
12
  @source inline("{hover:,dark:,}bg-base-{50,{100..900..100},950}");
13
- @source inline("{md:,lg:,}w-{1/2,1/3,2/3,1/4,2/4,3/4,1/5,2/5,3/5,4/5}");
13
+ @source inline("{md:,lg:,}w-{1/2,1/3,2/3,1/4,2/4,3/4,1/5,2/5,3/5,4/5,1/6,2/6,3/6,4/6,5/6,1/7,2/7,3/7,4/7,5/7,6/7}");
14
14
  @source inline("{md:,lg:,}gap-{0.5,{1..12}}");
15
15
  @source inline("{md:,lg:,}grid-cols-{1..12}");
16
16
  @source inline("{md:,lg:,}col-span-{1..12}");
17
17
 
18
+ @layer base {
19
+ *,
20
+ ::after,
21
+ ::before,
22
+ ::backdrop,
23
+ ::file-selector-button {
24
+ border-color: var(--color-gray-200, currentColor);
25
+ }
26
+ }
27
+
18
28
  @theme {
19
29
  --font-sans: 'Inter', sans-serif;
20
30
  }
@@ -347,7 +357,11 @@ h3 span:nth-child(3) {
347
357
  @apply outline-none;
348
358
  }
349
359
 
350
- .select2.select2-container.select2-container--focus{
360
+ .select2.select2-container--open {
361
+ @apply border-b-0 border-primary-600 relative outline-2 -outline-offset-2 outline-primary-600;
362
+ }
363
+
364
+ .select2.select2-container.select2-container--focus {
351
365
  @apply outline-2 outline-primary-600 -outline-offset-2;
352
366
  }
353
367
 
@@ -355,152 +369,97 @@ h3 span:nth-child(3) {
355
369
  @apply border-red-600;
356
370
  }
357
371
 
358
- .select2-container.select2-container--admin-autocomplete
359
- .select2-selection--single {
372
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single {
360
373
  @apply h-auto;
361
374
  }
362
375
 
363
- .select2-container.select2-container--admin-autocomplete
364
- .select2-selection--single
365
- .select2-selection__rendered {
376
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
366
377
  @apply font-medium h-9 px-3 py-2 text-font-default-light text-sm dark:text-font-default-dark;
367
378
  }
368
379
 
369
- .select2-container.select2-container--admin-autocomplete
370
- .select2-selection--multiple
371
- .select2-selection__clear,
372
- .select2-container.select2-container--admin-autocomplete
373
- .select2-selection--single
374
- .select2-selection__clear {
380
+ .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear,
381
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {
375
382
  @apply flex items-center h-9 -mt-2 text-[0px] after:text-base-400 hover:after:text-base-700 dark:hover:after:text-base-200 dark:after:text-base-500;
376
383
  }
377
384
 
378
- .select2-container.select2-container--admin-autocomplete
379
- .select2-selection--multiple
380
- .select2-selection__clear:after,
381
- .select2-container.select2-container--admin-autocomplete
382
- .select2-selection--single
383
- .select2-selection__clear:after {
385
+ .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear:after,
386
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear:after {
384
387
  @apply material-symbols-outlined transition-all content-['close'] text-[18px] ;
385
388
  }
386
389
 
387
- .select2-container.select2-container--admin-autocomplete
388
- .select2-selection--single
389
- .select2-selection__arrow {
390
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
390
391
  @apply flex h-9 items-center mr-2 -mt-px;
392
+ @apply after:left-0 after:leading-none after:m-0 after:material-symbols-outlined after:text-base-400 after:text-lg dark:after:text-base-500;
391
393
  }
392
394
 
393
- .select2-container.select2-container--admin-autocomplete
394
- .select2-selection--single
395
- .select2-selection__arrow:after {
396
- @apply left-0 leading-none m-0 material-symbols-outlined text-base-400 text-lg;
395
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow:after {
397
396
  content: "expand_more";
398
397
  }
399
398
 
400
- .select2-container.select2-container--admin-autocomplete
401
- .select2-selection--single
402
- .select2-selection__arrow
403
- b {
399
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {
404
400
  @apply hidden;
405
401
  }
406
402
 
407
- .select2-container.select2-container--admin-autocomplete
408
- .select2-search--dropdown {
409
- @apply flex px-3 py-2;
410
- }
411
-
412
- .select2-container.select2-container--admin-autocomplete
413
- .select2-search--dropdown
414
- .select2-search__field {
415
- @apply bg-base-50 border border-base-200 border-solid grow font-medium mx-0 outline-hidden px-3 py-2 rounded-default shadow-xs text-font-default-light text-sm w-full dark:bg-base-800 dark:border-base-800 dark:text-font-default-dark;
403
+ .select2-container.select2-container--admin-autocomplete .select2-search--dropdown {
404
+ @apply border-b border-base-200 py-1.5 px-1 relative dark:border-base-700 before:absolute before:content-['search'] before:material-symbols-outlined before:left-4 before:top-2.5 before:text-base-400 before:text-lg dark:before:text-base-500;
416
405
  }
417
406
 
418
- .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--above {
419
- @apply rounded-t-none;
407
+ .select2-container.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
408
+ @apply bg-base-100 border-0 border-base-200 border-solid grow font-medium mx-0 outline-hidden px-3 py-2 pl-9 rounded-default text-font-default-light text-sm w-full dark:bg-base-800 dark:border-base-800 dark:text-font-default-dark;
420
409
  }
421
410
 
422
- .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--below {
423
- @apply rounded-b-none;
411
+ .select2-container .select2-results__options {
412
+ @apply py-1;
424
413
  }
425
414
 
426
415
  .select2-container.select2-container--open .select2-dropdown {
427
- @apply border border-transparent outline-2 -outline-offset-2 outline-primary-600 pb-2 shadow-xs dark:bg-base-900;
416
+ @apply bg-white border border-base-200 rounded-default shadow-xs dark:border-base-700 dark:bg-base-900;
428
417
  }
429
418
 
430
419
  .select2-container.select2-container--open .select2-dropdown--below {
431
- @apply rounded-t-none rounded-b -top-0.5;
420
+ @apply mt-1;
432
421
  }
433
422
 
434
423
  .select2-container.select2-container--open .select2-dropdown--above {
435
- @apply rounded-b-none rounded-default -bottom-0.5;
424
+ @apply mb-1;
436
425
  }
437
426
 
438
- .select2-container.select2-container--admin-autocomplete
439
- .select2-results__option {
440
- @apply block px-3 py-2 text-font-default-light text-sm transition-all dark:text-font-default-dark;
427
+ .select2-container.select2-container--admin-autocomplete .select2-results__option {
428
+ @apply block mb-0.5 mx-1 px-2 py-2 rounded-default text-font-default-light transition-all hover:bg-base-100 hover:text-base-700 dark:hover:bg-base-800 dark:hover:text-base-200 dark:text-font-default-dark last:mb-0;
441
429
  }
442
-
443
- .select2-container.select2-container--admin-autocomplete
444
- .select2-results__option[aria-selected="true"] {
445
- @apply text-primary-600 dark:text-primary-500;
446
- }
447
-
448
- .select2-container.select2-container--admin-autocomplete
449
- .select2-results__option--highlighted[aria-selected="true"] {
450
- @apply text-primary-600 dark:text-primary-500;
430
+ .select2-container.select2-container--admin-autocomplete .select2-results__option[aria-selected="true"] {
431
+ @apply text-primary-600 dark:text-primary-500 flex items-center text-primary-600 dark:text-primary-500 after:content-['check'] after:material-symbols-outlined after:ml-auto;
451
432
  }
452
433
 
453
- .select2-container.select2-container--admin-autocomplete
454
- .select2-selection--multiple
455
- .select2-selection__clear {
434
+ .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {
456
435
  @apply m-0 mr-3 top-0;
457
436
  }
458
437
 
459
-
460
- .select2-container.select2-container--admin-autocomplete
461
- .select2-selection--multiple
462
- .select2-selection__rendered {
438
+ .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {
463
439
  @apply pl-1 pr-6 py-0 pt-1;
464
440
  }
465
441
 
466
- .select2-container.select2-container--admin-autocomplete
467
- .select2-selection--single
468
- .select2-selection__rendered {
442
+ .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
469
443
  @apply pr-8;
470
444
  }
471
445
 
472
- .select2-container--admin-autocomplete
473
- .select2-selection--multiple
474
- li.select2-selection__choice {
446
+ .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice {
475
447
  @apply bg-base-100 block font-medium h-7 leading-7 m-0 mr-1 mb-1 px-2 shadow-inner text-sm text-base-600 hover:text-base-700 truncate dark:bg-base-800 dark:text-base-300 dark:hover:text-base-200;
476
448
  }
477
449
 
478
- .select2-container--admin-autocomplete
479
- .select2-selection--multiple
480
- li.select2-selection__choice
481
- .select2-selection__choice__remove {
450
+ .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice .select2-selection__choice__remove {
482
451
  @apply align-top text-[0px] hover:text-base-600 dark:hover:text-base-200;
483
452
  }
484
453
 
485
- .select2-container--admin-autocomplete
486
- .select2-selection--multiple
487
- li.select2-selection__choice
488
- .select2-selection__choice__remove:after {
454
+ .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice .select2-selection__choice__remove:after {
489
455
  @apply h-7 leading-7! material-symbols-outlined;
490
456
 
491
457
  content: "close";
492
458
  font-size: 14px;
493
459
  }
494
460
 
495
- .select2-container--admin-autocomplete
496
- .select2-selection--multiple
497
- li.select2-search--inline
498
- .select2-search__field {
499
- @apply m-0 h-7 text-base-500 text-sm;
500
- }
501
-
502
- .select2.select2-container--open {
503
- @apply border-b-0 border-primary-600 relative outline-2 -outline-offset-2 outline-primary-600;
461
+ .select2-container--admin-autocomplete .select2-selection--multiple li.select2-search--inline .select2-search__field {
462
+ @apply m-0 h-7 ml-2 text-base-500 text-sm;
504
463
  }
505
464
 
506
465
  /*******************************************************
@@ -1,7 +1,7 @@
1
1
  {% extends "admin/base_site.html" %}
2
2
  {% load admin_urls i18n static %}
3
3
 
4
- {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">{% endblock %}
4
+ {% block extrastyle %}{{ block.super }}{% endblock %}
5
5
  {% block bodyclass %}{{ block.super }} {{ opts.app_label }}-{{ opts.model_name }} change-form{% endblock %}
6
6
 
7
7
  {% if not is_popup %}
@@ -5,13 +5,13 @@
5
5
  <div class="flex flex-col-reverse gap-3 items-center mx-auto lg:flex-row-reverse container lg:h-[64px]">
6
6
  {% block submit-row %}
7
7
  {% if show_save %}
8
- <button type="submit" form="{{ opts.model_name }}_form" name="_save" class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded-default text-white w-full lg:w-auto">
8
+ <button type="submit" form="{{ opts.model_name }}_form" name="_save" class="bg-primary-600 block border border-transparent cursor-pointer font-medium px-3 py-2 rounded-default text-white w-full lg:w-auto">
9
9
  {% translate 'Save' %}
10
10
  </button>
11
11
  {% endif %}
12
12
 
13
13
  {% for action in actions_submit_line %}
14
- <button type="submit" form="{{ opts.model_name }}_form" {% if not action.attrs.name %}name="{{ action.action_name }}"{% endif %} class="border border-base-200 flex font-medium gap-2 items-center px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900" {% include "unfold/helpers/attrs.html" with attrs=action.attrs %}>
14
+ <button type="submit" form="{{ opts.model_name }}_form" {% if not action.attrs.name %}name="{{ action.action_name }}"{% endif %} class="border border-base-200 cursor-pointer flex font-medium gap-2 items-center justify-center px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900" {% include "unfold/helpers/attrs.html" with attrs=action.attrs %}>
15
15
  {% if action.icon %}
16
16
  <span class="material-symbols-outlined">
17
17
  {{ action.icon }}
@@ -23,7 +23,7 @@
23
23
  {% endfor %}
24
24
 
25
25
  {% if show_save_and_continue %}
26
- <button type="submit" form="{{ opts.model_name }}_form" name="_continue" class="border border-base-200 font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
26
+ <button type="submit" form="{{ opts.model_name }}_form" name="_continue" class="border border-base-200 cursor-pointer font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
27
27
  {% if can_change %}
28
28
  {% translate 'Save and continue editing' %}
29
29
  {% else %}
@@ -33,13 +33,13 @@
33
33
  {% endif %}
34
34
 
35
35
  {% if show_save_and_add_another %}
36
- <button type="submit" form="{{ opts.model_name }}_form" name="_addanother" class="border border-base-200 font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
36
+ <button type="submit" form="{{ opts.model_name }}_form" name="_addanother" class="border border-base-200 cursor-pointer font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
37
37
  {% translate 'Save and add another' %}
38
38
  </button>
39
39
  {% endif %}
40
40
 
41
41
  {% if show_save_as_new %}
42
- <button type="submit" form="{{ opts.model_name }}_form" name="_saveasnew" class="border border-base-200 font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
42
+ <button type="submit" form="{{ opts.model_name }}_form" name="_saveasnew" class="border border-base-200 cursor-pointer font-medium px-3 py-2 rounded-default transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
43
43
  {% translate 'Save as new' %}
44
44
  </button>
45
45
  {% endif %}
@@ -48,7 +48,7 @@
48
48
  {% if show_close or adminform.model_admin.change_form_show_cancel_button %}
49
49
  {% url opts|admin_urlname:'changelist' as changelist_url %}
50
50
 
51
- <a href="{% add_preserved_filters changelist_url %}" class="border border-base-200 font-medium px-3 py-2 rounded-default text-center transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
51
+ <a href="{% add_preserved_filters changelist_url %}" class="border border-base-200 cursor-pointer font-medium px-3 py-2 rounded-default text-center transition-all w-full hover:bg-base-50 lg:block lg:w-auto dark:border-base-700 dark:hover:text-base-200 dark:hover:bg-base-900">
52
52
  {% translate 'Close' %}
53
53
  </a>
54
54
  {% endif %}
@@ -56,7 +56,7 @@
56
56
  {% if show_delete_link and original %}
57
57
  {% url opts|admin_urlname:'delete' original.pk|admin_urlquote as delete_url %}
58
58
 
59
- <a href="{% add_preserved_filters delete_url %}" class="bg-red-600 flex items-center justify-center font-medium h-[38px] ml-auto px-3 py-2 rounded-default text-center text-white w-full lg:w-auto dark:bg-red-500/20 dark:text-red-500">
59
+ <a href="{% add_preserved_filters delete_url %}" class="bg-red-600 cursor-pointer flex items-center justify-center font-medium h-[38px] ml-auto px-3 py-2 rounded-default text-center text-white w-full lg:w-auto dark:bg-red-500/20 dark:text-red-500">
60
60
  {% translate "Delete" %} {{ opts.verbose_name }}
61
61
  </a>
62
62
  {% endif %}
@@ -1,7 +1,7 @@
1
1
  {% extends "admin/base_site.html" %}
2
2
  {% load admin_urls i18n static %}
3
3
 
4
- {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">{% endblock %}
4
+ {% block extrastyle %}{{ block.super }}">{% endblock %}
5
5
 
6
6
  {% if not is_popup %}
7
7
  {% block breadcrumbs %}
@@ -1,7 +1,7 @@
1
1
  {% extends "admin/base_site.html" %}
2
2
  {% load admin_urls i18n static %}
3
3
 
4
- {% block extrastyle %}{{ block.super }}<link rel="stylesheet" type="text/css" href="{% static "admin/css/forms.css" %}">{% endblock %}
4
+ {% block extrastyle %}{{ block.super }}{% endblock %}
5
5
 
6
6
  {% if not is_popup %}
7
7
  {% block breadcrumbs %}
@@ -1,27 +1,27 @@
1
- <div class="bg-white border border-base-200 flex flex-col grow overflow-hidden p-6 relative rounded-default shadow-xs dark:bg-base-900 dark:border-base-800 {% if class %} {{ class }}{% endif %}">
2
- {% if title %}
3
- <h2 class="bg-base-50 border-b border-base-200 font-semibold mb-6 -mt-6 -mx-6 py-4 px-6 text-font-important-light dark:text-font-important-dark dark:border-base-800 dark:bg-white/[.02]">
4
- {{ title }}
5
- </h2>
6
- {% endif %}
7
-
8
- <div class="grow relative {% if icon %} pl-6{% endif %}">
9
- {{ children }}
10
-
11
- {% if label %}
12
- <div class="absolute right-0 top-0">
13
- {% include "unfold/helpers/label.html" with text=label type="primary" %}
14
- </div>
15
- {% endif %}
1
+ <{% if href %}a href="{{ href }}"{% else %}div{% endif %} class="bg-white block border border-base-200 flex flex-col grow overflow-hidden p-6 relative rounded-default shadow-xs dark:bg-base-900 dark:border-base-800 {% if href %}cursor-pointer transition-all hover:border-base-300 hover:shadow-md hover:shadow-base-200 dark:hover:border-base-700 dark:hover:shadow-base-800/50 {% endif %}{% if class %} {{ class }}{% endif %}">
2
+ {% if title %}
3
+ <h2 class="border-b border-base-200 font-semibold mb-6 -mt-6 -mx-6 py-4 px-6 text-[15px] text-font-important-light dark:text-font-important-dark dark:border-base-800">
4
+ {{ title }}
5
+ </h2>
6
+ {% endif %}
16
7
 
17
- {% if icon %}
18
- <span class="material-symbols-outlined absolute -left-6 text-base-300 top-1/2 -translate-x-1/3 -translate-y-1/2 text-6xl! dark:text-base-500">{{ icon }}</span>
19
- {% endif %}
20
- </div>
8
+ <span class="grow relative {% if icon %} pl-6{% endif %}">
9
+ {{ children }}
21
10
 
22
- {% if footer %}
23
- <div class="border-t border-base-200 flex items-center -mb-6 -mx-6 mt-6 pb-2 pt-2 px-6 text-sm dark:border-base-800">
24
- {{ footer }}
11
+ {% if label %}
12
+ <div class="absolute right-0 top-0">
13
+ {% include "unfold/helpers/label.html" with text=label type="primary" %}
25
14
  </div>
26
15
  {% endif %}
27
- </div>
16
+
17
+ {% if icon %}
18
+ <span class="material-symbols-outlined absolute -left-6 text-base-300 top-1/2 -translate-x-1/3 -translate-y-1/2 text-6xl! dark:text-base-500">{{ icon }}</span>
19
+ {% endif %}
20
+ </span>
21
+
22
+ {% if footer %}
23
+ <span class="border-t border-base-200 flex items-center -mb-6 -mx-6 mt-6 pb-2 pt-2 px-6 text-sm dark:border-base-800">
24
+ {{ footer }}
25
+ </span>
26
+ {% endif %}
27
+ </{% if href %}a{% else %}div{% endif %}>
@@ -1,21 +1,23 @@
1
1
  <div class="{% if class %}{{ class }}{% endif %}">
2
- <div class="overflow-hidden relative px-2 py-1 text-sm">
3
- {% if value %}
4
- <div class="absolute bottom-0 left-0 rounded-default top-0 bg-primary-100 z-10 dark:bg-primary-500/20" style="width: {{ value }}%"></div>
5
- {% endif %}
6
-
2
+ <div class="flex flex-col gap-2 relative">
7
3
  <div class="flex flex-row relative z-20">
8
4
  {% if title %}
9
- <h3 class="text-font-default-light dark:text-font-default-dark text-sm">
5
+ <h3 class="text-font-important-light dark:text-font-important-dark text-sm">
10
6
  {{ title }}
11
7
  </h3>
12
8
  {% endif %}
13
9
 
14
10
  {% if description %}
15
- <strong class="font-semibold text-font-important-light ml-auto dark:text-font-important-dark">
11
+ <strong class="bg-base-100 font-medium text-font-important-light ml-auto px-1.5 py-1 rounded-default text-xs dark:text-font-important-dark dark:bg-base-800">
16
12
  {{ description }}
17
13
  </strong>
18
14
  {% endif %}
19
15
  </div>
16
+
17
+ {% if value %}
18
+ <div class="bg-gray-100 overflow-hidden rounded-default dark:bg-base-800">
19
+ <div class="h-1.5 bg-primary-600 rounded-default z-10 dark:bg-primary-500" title="{{ value }}%" style="width: {{ value }}%"></div>
20
+ </div>
21
+ {% endif %}
20
22
  </div>
21
23
  </div>
@@ -1,6 +1,6 @@
1
1
  {% load i18n unfold %}
2
2
 
3
- <div class="flex flex-col">
3
+ <div class="flex flex-col {% if class %}{{ class }}{% endif %}">
4
4
  {% if title %}
5
5
  <h3 class="font-semibold mb-1 text-font-important-light text-sm dark:text-font-important-dark">
6
6
  {{ title }}
@@ -11,10 +11,10 @@
11
11
  <div {% if height %}style="max-height: {{ height }}px;" data-simplebar{% endif %}>
12
12
  <table class="block border-spacing-none border-separate w-full lg:table">
13
13
  {% if table.headers %}
14
- <thead class="text-base-900 dark:text-base-100 {% if height %}sticky top-0{% endif %}">
14
+ <thead class="text-font-important-light dark:text-font-important-dark {% if height %}sticky top-0{% endif %}">
15
15
  <tr class="bg-base-50 dark:bg-base-900">
16
16
  {% for header in table.headers %}
17
- <th class="align-middle border-b border-base-200 font-semibold py-2 text-left text-sm whitespace-nowrap sortable column-description hidden px-3 lg:table-cell dark:border-base-800 dark:bg-white/[.02] {% if card_included == 1 %}first:pl-6 last:pr-6{% endif %}">
17
+ <th class="align-middle border-b border-base-200 font-semibold py-2 text-left whitespace-nowrap sortable column-description hidden px-3 lg:table-cell dark:border-base-800 dark:bg-white/[.02] {% if card_included == 1 %}first:pl-6 last:pr-6{% endif %}">
18
18
  {{ header|capfirst }}
19
19
  </th>
20
20
  {% endfor %}
@@ -25,9 +25,9 @@
25
25
  {% if table.rows %}
26
26
  <tbody class="block lg:table-row-group">
27
27
  {% for row in table.rows %}
28
- <tr class="{% if striped == 1 %}{% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}{% endif %} block group {% if forloop.first %}first-row{% endif %} {% if not card_included == 1 %}border mb-3 rounded-default shadow-xs{% else %}border-b{% endif %} lg:table-row lg:border-none lg:mb-0 lg:shadow-none dark:border-base-800">
28
+ <tr class="{% if striped == 1 %}{% cycle '' 'bg-base-50 dark:bg-white/[.02]' %}{% endif %} block group {% if forloop.first %}first-row{% endif %} {% if not card_included == 1 %}border border-base-200 mb-3 rounded-default shadow-xs{% else %}border-b border-base-200 last:border-b-0{% endif %} lg:table-row lg:border-none lg:mb-0 lg:shadow-none dark:border-base-800">
29
29
  {% for cell in row %}
30
- <td class="px-3 py-2 align-middle flex border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden text-left before:flex before:capitalize before:content-[attr(data-label)] before:items-center before:mr-auto first:border-t-0 lg:group-[.first-row]:border-t-0 lg:before:hidden lg:first:border-t lg:py-3 lg:table-cell dark:border-base-800 {% if card_included == 1 %}lg:first:pl-6 lg:last:pr-6{% endif %}" {% if table.headers %}data-label="{{ table.headers|index:forloop.counter0 }}"{% endif %}>
30
+ <td class="px-3 py-2 align-middle flex border-t border-base-200 font-normal gap-4 min-w-0 overflow-hidden text-left before:flex before:capitalize before:content-[attr(data-label)] before:font-semibold before:text-font-important-light dark:before:text-font-important-dark before:items-center before:mr-auto first:border-t-0 lg:group-[.first-row]:border-t-0 lg:before:hidden {% if not forloop.parentloop.first %}lg:first:border-t{% endif %} lg:py-3 lg:table-cell dark:border-base-800 {% if card_included == 1 %}lg:first:pl-6 lg:last:pr-6{% endif %}" {% if table.headers %}data-label="{{ table.headers|index:forloop.counter0 }}"{% endif %}>
31
31
  {{ cell }}
32
32
  </td>
33
33
  {% endfor %}
@@ -3,7 +3,7 @@
3
3
  {% if cl.model_admin.list_filter_submit or cl.is_facets_optional or cl.has_active_filters %}
4
4
  <div class="bg-white border-t border-base-200 p-3 py-2.5 dark:bg-base-800 dark:border-base-700{% if not cl.model_admin.list_filter_sheet %} 2xl:border-t-0! 2xl:bg-transparent! 2xl:px-0{% endif %}">
5
5
  {% if cl.model_admin.list_filter_submit %}
6
- <button type="submit" class="bg-primary-600 block border border-transparent font-medium px-3 py-2 rounded-default text-white w-full">
6
+ <button type="submit" class="bg-primary-600 block border border-transparent cursor-pointer font-medium px-3 py-2 rounded-default text-white w-full">
7
7
  {% trans "Apply Filters" %}
8
8
  </button>
9
9
  {% endif %}
@@ -1,7 +1,7 @@
1
1
  {% load unfold %}
2
2
 
3
3
  {% if field.field.widget.input_type == "checkbox" and field.field.widget|class_name != "UnfoldAdminCheckboxSelectMultiple"%}
4
- <div class="{% if field.errors %}errors {% endif %}flex flex-col group mb-6 last:mb-4">
4
+ <div class="{% if field.errors %}errors {% endif %}flex flex-col group mb-5 last:mb-4">
5
5
  <div class="flex flex-row gap-2 items-center">
6
6
  {{ field }}
7
7
 
@@ -13,7 +13,7 @@
13
13
  {% include "unfold/helpers/help_text.html" with help_text=field.help_text %}
14
14
  </div>
15
15
  {% else %}
16
- <div class="{% if field.errors %}errors {% endif %}flex flex-col gap-2 group mb-6 last:mb-4">
16
+ <div class="{% if field.errors %}errors {% endif %}flex flex-col gap-2 group mb-5 last:mb-4">
17
17
  {% include "unfold/helpers/form_label.html" with field=field %}
18
18
 
19
19
  {{ field }}
@@ -1,6 +1,6 @@
1
1
  {% load i18n unfold %}
2
2
 
3
- <nav class="bg-base-50 flex flex-col min-h-screen dark:bg-base-950/20 {% element_classes 'navigation_inner' %}">
3
+ <nav id="nav-sidebar-inner" class="bg-base-50 flex flex-col min-h-screen dark:bg-base-950/20 {% element_classes 'navigation_inner' %}">
4
4
  {% include "unfold/helpers/navigation_header.html" %}
5
5
 
6
6
  {% include "unfold/helpers/search.html" %}
@@ -3,7 +3,7 @@
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{% 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 %} row{% 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
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 %}">
9
9
  {{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}
@@ -1,13 +1,13 @@
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">
4
+ <label for="{{ field.id_for_label }}" class="flex flex-row gap-3 items-center {% if tag == "td" %}mt-9{% endif %}">
5
5
  {% crispy_field field 'class' form_classes.switch %} <span>{{ field.label }}{% if field.field.required %} <span class="asteriskField">*</span>{% endif %}</span>
6
6
  </label>
7
7
 
8
8
  {% include 'unfold_crispy/layout/help_text_and_errors.html' %}
9
9
  {% else %}
10
- {% with field=field|add_css_class:form_classes.checkbox %}
10
+ {% with field=field|add_css_class:form_classes.switch %}
11
11
  {% if tag == "td" %}
12
12
  <div class="flex items-center justify-center h-[38px]">
13
13
  {% crispy_field field %}
@@ -1,6 +1,6 @@
1
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 }}>
2
2
  {% if legend %}
3
- <legend class="border-b border-base-200 font-semibold float-left pb-3 -mx-3 px-3 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 pb-3 -mx-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 %}
@@ -15,20 +15,22 @@
15
15
  {{ formset.management_form|crispy }}
16
16
 
17
17
  <table class="w-full">
18
- <thead>
19
- {% if formset.readonly and not formset.queryset.exists %}
20
- {% else %}
21
- <tr>
22
- {% for field in formset.forms.0 %}
23
- {% if field.label and not field.is_hidden %}
24
- <th for="{{ field.auto_id }}" class="align-middle font-semibold py-2 text-left text-font-important-light dark:text-font-important-dark whitespace-nowrap px-3 {% if field.name == "DELETE" %}w-0{% endif %}">
25
- {{ field.label }}{% if field.field.required and not field|is_checkbox %} <span class="asteriskField">*</span>{% endif %}
26
- </th>
27
- {% endif %}
28
- {% endfor %}
29
- </tr>
30
- {% endif %}
31
- </thead>
18
+ {% if not form_show_labels %}
19
+ <thead>
20
+ {% if formset.readonly and not formset.queryset.exists %}
21
+ {% else %}
22
+ <tr>
23
+ {% for field in formset.forms.0 %}
24
+ {% if field.label and not field.is_hidden %}
25
+ <th for="{{ field.auto_id }}" class="align-middle font-semibold py-2 text-left text-font-important-light dark:text-font-important-dark whitespace-nowrap px-3 {% if field.name == "DELETE" %}w-0{% endif %}">
26
+ {{ field.label }}{% if field.field.required and not field|is_checkbox %} <span class="asteriskField">*</span>{% endif %}
27
+ </th>
28
+ {% endif %}
29
+ {% endfor %}
30
+ </tr>
31
+ {% endif %}
32
+ </thead>
33
+ {% endif %}
32
34
 
33
35
  <tbody {% if formset_id %}id="{{ formset_id }}-rows"{% endif %}>
34
36
  {% for form in formset %}
@@ -42,7 +44,7 @@
42
44
 
43
45
  <tr>
44
46
  {% for field in form %}
45
- {% include 'unfold_crispy/field.html' with tag="td" form_show_labels=False %}
47
+ {% include 'unfold_crispy/field.html' with tag="td" %}
46
48
  {% endfor %}
47
49
  </tr>
48
50
  {% endfor %}
@@ -52,7 +54,7 @@
52
54
  <tbody>
53
55
  <tr class="empty-form">
54
56
  {% for field in formset.empty_form %}
55
- {% include 'unfold_crispy/field.html' with tag="td" form_show_labels=False %}
57
+ {% include 'unfold_crispy/field.html' with tag="td" %}
56
58
  {% endfor %}
57
59
  </tr>
58
60
 
@@ -108,6 +108,20 @@ def class_name(value: Any) -> str:
108
108
  return value.__class__.__name__
109
109
 
110
110
 
111
+ @register.filter
112
+ def is_list(value: Any) -> str:
113
+ return isinstance(value, list)
114
+
115
+
116
+ @register.filter
117
+ def has_active_item(items: list[dict]) -> bool:
118
+ for item in items:
119
+ if "active" in item and item["active"]:
120
+ return True
121
+
122
+ return False
123
+
124
+
111
125
  @register.filter
112
126
  def index(indexable: Mapping[int, Any], i: int) -> Any:
113
127
  try:
unfold/widgets.py CHANGED
@@ -168,7 +168,7 @@ CHECKBOX_CLASSES = [
168
168
  "dark:border-base-500",
169
169
  "dark:checked:after:text-white",
170
170
  "focus:outline",
171
- "focus:outline-1",
171
+ "focus:outline-2",
172
172
  "focus:outline-offset-2",
173
173
  "focus:outline-primary-500",
174
174
  "after:absolute",
@@ -210,7 +210,7 @@ RADIO_CLASSES = [
210
210
  "dark:border-base-500",
211
211
  "hover:border-base-400",
212
212
  "focus:outline",
213
- "focus:outline-1",
213
+ "focus:outline-2",
214
214
  "focus:outline-offset-2",
215
215
  "focus:outline-primary-500",
216
216
  "after:absolute",