django-unfold 0.12.0__py3-none-any.whl → 0.13.0__py3-none-any.whl

Sign up to get free protection for your applications and to get access to all the features.
Files changed (32) hide show
  1. {django_unfold-0.12.0.dist-info → django_unfold-0.13.0.dist-info}/METADATA +209 -102
  2. {django_unfold-0.12.0.dist-info → django_unfold-0.13.0.dist-info}/RECORD +32 -13
  3. unfold/admin.py +26 -6
  4. unfold/contrib/guardian/__init__.py +0 -0
  5. unfold/contrib/guardian/apps.py +6 -0
  6. unfold/contrib/guardian/templates/admin/guardian/model/change_form.html +13 -0
  7. unfold/contrib/guardian/templates/admin/guardian/model/field.html +11 -0
  8. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage.html +35 -0
  9. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_group.html +55 -0
  10. unfold/contrib/guardian/templates/admin/guardian/model/obj_perms_manage_user.html +56 -0
  11. unfold/contrib/guardian/templates/unfold/guardian/group_form.html +72 -0
  12. unfold/contrib/guardian/templates/unfold/guardian/user_form.html +72 -0
  13. unfold/contrib/simple_history/__init__.py +0 -0
  14. unfold/contrib/simple_history/apps.py +6 -0
  15. unfold/contrib/simple_history/templates/simple_history/_object_history_list.html +80 -0
  16. unfold/contrib/simple_history/templates/simple_history/object_history.html +21 -0
  17. unfold/contrib/simple_history/templates/simple_history/object_history_form.html +55 -0
  18. unfold/contrib/simple_history/templates/simple_history/submit_line.html +25 -0
  19. unfold/settings.py +1 -0
  20. unfold/sites.py +4 -0
  21. unfold/static/unfold/css/styles.css +1 -1
  22. unfold/styles.css +134 -66
  23. unfold/templates/admin/edit_inline/tabular.html +1 -1
  24. unfold/templates/admin/includes/fieldset.html +3 -7
  25. unfold/templates/admin/widgets/radio.html +20 -0
  26. unfold/templates/admin/widgets/radio_option.html +12 -0
  27. unfold/templates/unfold/helpers/field_readonly.html +9 -0
  28. unfold/templates/unfold/helpers/submit.html +3 -0
  29. unfold/templatetags/unfold.py +14 -0
  30. unfold/widgets.py +19 -0
  31. /django_unfold-0.12.0.dist-info/LICENSE → /django_unfold-0.13.0.dist-info/LICENSE.md +0 -0
  32. {django_unfold-0.12.0.dist-info → django_unfold-0.13.0.dist-info}/WHEEL +0 -0
unfold/styles.css CHANGED
@@ -5,16 +5,17 @@
5
5
  @tailwind utilities;
6
6
 
7
7
  html {
8
- --color-primary-50: theme('colors.purple.50');
9
- --color-primary-100: theme('colors.purple.100');
10
- --color-primary-200: theme('colors.purple.200');
11
- --color-primary-300: theme('colors.purple.300');
12
- --color-primary-400: theme('colors.purple.400');
13
- --color-primary-500: theme('colors.purple.500');
14
- --color-primary-600: theme('colors.purple.600');
15
- --color-primary-700: theme('colors.purple.700');
16
- --color-primary-800: theme('colors.purple.800');
17
- --color-primary-900: theme('colors.purple.900');
8
+ --color-primary-50: theme("colors.purple.50");
9
+ --color-primary-100: theme("colors.purple.100");
10
+ --color-primary-200: theme("colors.purple.200");
11
+ --color-primary-300: theme("colors.purple.300");
12
+ --color-primary-400: theme("colors.purple.400");
13
+ --color-primary-500: theme("colors.purple.500");
14
+ --color-primary-600: theme("colors.purple.600");
15
+ --color-primary-700: theme("colors.purple.700");
16
+ --color-primary-800: theme("colors.purple.800");
17
+ --color-primary-900: theme("colors.purple.900");
18
+ --color-primary-950: theme("colors.purple.950");
18
19
  }
19
20
 
20
21
  /*******************************************************
@@ -34,7 +35,7 @@ html {
34
35
  }
35
36
 
36
37
  .material-symbols-outlined {
37
- font-family: 'Material Symbols Outlined';
38
+ font-family: "Material Symbols Outlined";
38
39
  font-weight: normal;
39
40
  font-style: normal;
40
41
  font-size: 18px;
@@ -45,13 +46,13 @@ html {
45
46
  white-space: nowrap;
46
47
  word-wrap: normal;
47
48
  direction: ltr;
48
- -moz-font-feature-settings: 'liga';
49
+ -moz-font-feature-settings: "liga";
49
50
  -moz-osx-font-smoothing: grayscale;
50
51
  }
51
52
 
52
53
  .scrollable-top:after {
53
- @apply absolute bg-gradient-to-t from-gray-100 h-4 left-0 right-0 -top-4 dark:bg-none;
54
- content: '';
54
+ @apply absolute bg-gradient-to-t from-gray-100 h-4 left-0 right-0 -top-4 dark:bg-none;
55
+ content: "";
55
56
  }
56
57
  }
57
58
 
@@ -71,41 +72,68 @@ html {
71
72
  }
72
73
 
73
74
  /*******************************************************
74
- Forms
75
+ Select
75
76
  *******************************************************/
76
77
  select:not([class*="bg-none"]):not([multiple]) {
77
78
  background-image: url("data:image/svg+xml,%3csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 48 48'%3e%3cpath fill='#6B7280' d='M24 31.4 11.3 18.7l2.85-2.8L24 25.8l9.85-9.85 2.85 2.8Z'/%3e%3c/svg%3e");
78
- background-position: right .70rem center;
79
+ background-position: right 0.7rem center;
79
80
  background-repeat: no-repeat;
80
81
  background-size: 1.125rem 1.125rem;
81
82
  }
82
83
 
83
84
  select:after {
84
- content: '';
85
+ content: "";
85
86
  display: block;
86
87
  }
87
88
 
88
- #page input[type=checkbox] {
89
+ /*******************************************************
90
+ Checkbox
91
+ *******************************************************/
92
+ #page input[type="checkbox"] {
89
93
  @apply appearance-none bg-white block border border-gray-300 cursor-pointer h-4 relative rounded w-4 dark:bg-gray-700 dark:border-gray-500 hover:border-gray-400;
90
- @apply focus:outline focus:outline-1 focus:outline-offset-2 focus:outline-primary-500
94
+ @apply focus:outline focus:outline-1 focus:outline-offset-2 focus:outline-primary-500;
91
95
  }
92
96
 
93
- #page input[type=checkbox]:after {
97
+ #page input[type="checkbox"]:after {
94
98
  @apply absolute flex h-4 items-center justify-center leading-none -ml-px -mt-px text-white transition-all text-sm w-4 dark:text-gray-700;
95
99
 
96
100
  content: "done";
97
101
  font-family: "Material Symbols Outlined";
98
102
  }
99
103
 
100
- #page input[type=checkbox]:checked {
104
+ #page input[type="checkbox"]:checked {
101
105
  @apply bg-primary-600 border-primary-600 transition-all;
102
106
  }
103
107
 
104
- #page input[type=checkbox]:checked:after {
108
+ #page input[type="checkbox"]:checked:after {
105
109
  @apply text-white;
106
110
  }
107
111
 
108
- #page input[type=checkbox].hidden {
112
+ #page input[type="checkbox"].hidden {
113
+ display: none;
114
+ }
115
+
116
+ /*******************************************************
117
+ Radio
118
+ *******************************************************/
119
+ #page input[type="radio"] {
120
+ @apply appearance-none bg-white block border border-gray-300 cursor-pointer h-4 relative rounded-full w-4 dark:bg-gray-700 dark:border-gray-500 hover:border-gray-400;
121
+ @apply focus:outline focus:outline-1 focus:outline-offset-2 focus:outline-primary-500;
122
+ }
123
+
124
+ #page input[type="radio"]:after {
125
+ @apply absolute bg-white content-[''] flex h-2 items-center justify-center leading-none left-1/2 rounded-full text-white top-1/2 transition-all -translate-x-1/2 -translate-y-1/2 text-sm w-2 dark:text-gray-700 dark:bg-transparent;
126
+ }
127
+
128
+ #page input[type="radio"]:checked {
129
+ @apply bg-primary-600 border-primary-600 transition-all;
130
+ }
131
+
132
+ #page input[type="radio"]:checked:after {
133
+ @apply bg-white dark:bg-gray-200;
134
+ }
135
+
136
+ #page input[type="radio"].hidden {
109
137
  display: none;
110
138
  }
111
139
 
@@ -117,7 +145,7 @@ table select {
117
145
 
118
146
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" height="24px" viewBox="0 0 24 24" width="24px" fill="rgb(156, 163, 175)"><path d="M0 0h24v24H0V0z" fill="none"/><path d="M7 10l5 5 5-5H7z"/></svg>');
119
147
  background-size: 1.125rem 1.125rem;
120
- background-position: right .5rem center;
148
+ background-position: right 0.5rem center;
121
149
  }
122
150
 
123
151
  table select:focus {
@@ -145,7 +173,7 @@ table tr.selected {
145
173
 
146
174
  .datetimeshortcuts a:first-child:after {
147
175
  @apply border-l flex h-9 items-center justify-center leading-none material-symbols-outlined py-2 text-base text-center w-9 hover:text-gray-700 dark:border-gray-700 dark:hover:text-white;
148
- content: 'timer';
176
+ content: "timer";
149
177
  }
150
178
 
151
179
  .datetimeshortcuts a:first-child:after {
@@ -158,7 +186,7 @@ table tr.selected {
158
186
 
159
187
  .date-icon:after {
160
188
  @apply border-l h-9 items-center justify-center leading-none material-symbols-outlined py-2 text-base text-center w-9 hover:text-gray-700 dark:border-gray-700;
161
- content: 'edit';
189
+ content: "edit";
162
190
  }
163
191
 
164
192
  .date-icon:after {
@@ -171,7 +199,7 @@ table tr.selected {
171
199
 
172
200
  .clock-icon:after {
173
201
  @apply border-l h-9 items-center justify-center material-symbols-outlined py-2 text-base text-center w-9 hover:text-gray-700 dark:border-gray-700 dark:hover:text-white;
174
- content: 'edit';
202
+ content: "edit";
175
203
  }
176
204
 
177
205
  .clock-icon:after {
@@ -241,11 +269,11 @@ table tr.selected {
241
269
  }
242
270
 
243
271
  .selector-add:after {
244
- content: 'arrow_forward';
272
+ content: "arrow_forward";
245
273
  }
246
274
 
247
275
  .selector-remove:after {
248
- content: 'arrow_back';
276
+ content: "arrow_back";
249
277
  }
250
278
 
251
279
  .related-widget-wrapper-link {
@@ -302,52 +330,73 @@ h3 span:nth-child(3) {
302
330
  @apply border-red-600;
303
331
  }
304
332
 
305
- .select2-container.select2-container--admin-autocomplete .select2-selection--single {
333
+ .select2-container.select2-container--admin-autocomplete
334
+ .select2-selection--single {
306
335
  @apply h-auto;
307
336
  }
308
337
 
309
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__rendered {
310
- @apply font-medium h-9 px-3 py-2 text-gray-500 text-sm dark:text-gray-400;
338
+ .select2-container.select2-container--admin-autocomplete
339
+ .select2-selection--single
340
+ .select2-selection__rendered {
341
+ @apply font-medium h-9 px-3 py-2 text-gray-500 text-sm dark:text-gray-400;
311
342
  }
312
343
 
313
- .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear,
314
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear {
344
+ .select2-container.select2-container--admin-autocomplete
345
+ .select2-selection--multiple
346
+ .select2-selection__clear,
347
+ .select2-container.select2-container--admin-autocomplete
348
+ .select2-selection--single
349
+ .select2-selection__clear {
315
350
  @apply flex items-center mr-5 h-9 -mt-2 text-0;
316
351
  }
317
352
 
318
- .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear:after,
319
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__clear:after {
353
+ .select2-container.select2-container--admin-autocomplete
354
+ .select2-selection--multiple
355
+ .select2-selection__clear:after,
356
+ .select2-container.select2-container--admin-autocomplete
357
+ .select2-selection--single
358
+ .select2-selection__clear:after {
320
359
  @apply material-symbols-outlined text-gray-500;
321
360
  content: "close";
322
361
  font-size: 14px;
323
362
  }
324
363
 
325
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow {
364
+ .select2-container.select2-container--admin-autocomplete
365
+ .select2-selection--single
366
+ .select2-selection__arrow {
326
367
  @apply flex h-9 items-center mr-2 -mt-px;
327
368
  }
328
369
 
329
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow:after {
370
+ .select2-container.select2-container--admin-autocomplete
371
+ .select2-selection--single
372
+ .select2-selection__arrow:after {
330
373
  @apply left-0 leading-none m-0 material-symbols-outlined text-gray-500 text-lg;
331
374
  content: "expand_more";
332
375
  }
333
376
 
334
- .select2-container.select2-container--admin-autocomplete .select2-selection--single .select2-selection__arrow b {
377
+ .select2-container.select2-container--admin-autocomplete
378
+ .select2-selection--single
379
+ .select2-selection__arrow
380
+ b {
335
381
  @apply hidden;
336
382
  }
337
383
 
338
- .select2-container.select2-container--admin-autocomplete .select2-search--dropdown {
384
+ .select2-container.select2-container--admin-autocomplete
385
+ .select2-search--dropdown {
339
386
  @apply flex px-3 py-2;
340
387
  }
341
388
 
342
- .select2-container.select2-container--admin-autocomplete .select2-search--dropdown .select2-search__field {
389
+ .select2-container.select2-container--admin-autocomplete
390
+ .select2-search--dropdown
391
+ .select2-search__field {
343
392
  @apply bg-gray-50 border border-gray-200 border-solid flex-grow font-medium mx-0 outline-none px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm w-auto dark:bg-gray-800 dark:border-gray-800 dark:text-gray-400;
344
393
  }
345
394
 
346
- .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--above {
395
+ .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--above {
347
396
  @apply rounded-t-none;
348
397
  }
349
398
 
350
- .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--below {
399
+ .select2-container.select2-container--admin-autocomplete.select2-container--open.select2-container--below {
351
400
  @apply rounded-b-none;
352
401
  }
353
402
 
@@ -363,38 +412,55 @@ h3 span:nth-child(3) {
363
412
  @apply rounded-b-none rounded-t-md after:bottom-0 after:-mb-1 after:mt-0 after:top-auto;
364
413
  }
365
414
 
366
- .select2-container.select2-container--admin-autocomplete .select2-results__option {
415
+ .select2-container.select2-container--admin-autocomplete
416
+ .select2-results__option {
367
417
  @apply block px-3 py-2 text-gray-500 text-sm transition-all dark:text-gray-400;
368
418
  }
369
419
 
370
- .select2-container.select2-container--admin-autocomplete .select2-results__option--highlighted[aria-selected] {
420
+ .select2-container.select2-container--admin-autocomplete
421
+ .select2-results__option--highlighted[aria-selected] {
371
422
  @apply text-primary-500;
372
423
  }
373
424
 
374
- .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__clear {
425
+ .select2-container.select2-container--admin-autocomplete
426
+ .select2-selection--multiple
427
+ .select2-selection__clear {
375
428
  @apply m-0 mr-2 top-0;
376
429
  }
377
430
 
378
- .select2-container.select2-container--admin-autocomplete .select2-selection--multiple .select2-selection__rendered {
431
+ .select2-container.select2-container--admin-autocomplete
432
+ .select2-selection--multiple
433
+ .select2-selection__rendered {
379
434
  @apply pl-1 pr-6 py-0 pt-1;
380
435
  }
381
436
 
382
- .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice {
437
+ .select2-container--admin-autocomplete
438
+ .select2-selection--multiple
439
+ li.select2-selection__choice {
383
440
  @apply bg-gray-100 block font-medium h-7 leading-7 m-0 mr-1 mb-1 px-2 shadow-inner text-sm text-gray-500 truncate dark:bg-gray-800 dark:text-gray-400 dark:hover:text-gray-200;
384
441
  }
385
442
 
386
- .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice .select2-selection__choice__remove {
443
+ .select2-container--admin-autocomplete
444
+ .select2-selection--multiple
445
+ li.select2-selection__choice
446
+ .select2-selection__choice__remove {
387
447
  @apply align-top text-0 hover:text-gray-600 dark:hover:text-gray-200;
388
448
  }
389
449
 
390
- .select2-container--admin-autocomplete .select2-selection--multiple li.select2-selection__choice .select2-selection__choice__remove:after {
450
+ .select2-container--admin-autocomplete
451
+ .select2-selection--multiple
452
+ li.select2-selection__choice
453
+ .select2-selection__choice__remove:after {
391
454
  @apply h-7 !leading-7 material-symbols-outlined;
392
455
 
393
456
  content: "close";
394
457
  font-size: 14px;
395
458
  }
396
459
 
397
- .select2-container--admin-autocomplete .select2-selection--multiple li.select2-search--inline .select2-search__field {
460
+ .select2-container--admin-autocomplete
461
+ .select2-selection--multiple
462
+ li.select2-search--inline
463
+ .select2-search__field {
398
464
  @apply m-0 h-7 text-gray-500 text-sm;
399
465
  }
400
466
 
@@ -406,25 +472,27 @@ h3 span:nth-child(3) {
406
472
  Collapsed
407
473
  *******************************************************/
408
474
  fieldset.collapsed > div {
409
- display: none;
475
+ display: none;
410
476
  }
411
477
 
412
478
  fieldset.collapse {
413
- @apply visible;
479
+ @apply visible;
414
480
  }
415
481
 
416
- fieldset.collapsed h2, fieldset.collapsed {
417
- @apply block;
482
+ fieldset.collapsed h2,
483
+ fieldset.collapsed {
484
+ @apply block;
418
485
  }
419
486
 
420
487
  fieldset.collapsed .collapse-toggle {
421
- @apply inline;
488
+ @apply inline;
422
489
  }
423
490
 
424
491
  /*******************************************************
425
492
  Calendar
426
493
  *******************************************************/
427
- .calendarbox, .clockbox {
494
+ .calendarbox,
495
+ .clockbox {
428
496
  @apply bg-white border rounded-md shadow-sm text-gray-500 text-sm w-80 z-50 dark:bg-gray-800 dark:border-gray-700 !fixed !left-1/2 !top-1/2 -translate-x-1/2 -translate-y-1/2;
429
497
  }
430
498
 
@@ -476,7 +544,7 @@ fieldset.collapsed .collapse-toggle {
476
544
  .calendarnav-previous:after {
477
545
  @apply border flex h-7 items-center justify-center material-symbols-outlined rounded-full text-gray-400 transition-all w-7 hover:border-primary-600 hover:text-primary-500 dark:bg-gray-800 dark:border-gray-700 dark:hover:border-gray-800;
478
546
 
479
- content: 'navigate_before';
547
+ content: "navigate_before";
480
548
  display: flex;
481
549
  }
482
550
 
@@ -490,7 +558,7 @@ fieldset.collapsed .collapse-toggle {
490
558
  }
491
559
 
492
560
  .calendarnav-next:after {
493
- content: 'navigate_next';
561
+ content: "navigate_next";
494
562
  display: flex;
495
563
  }
496
564
 
@@ -520,31 +588,31 @@ fieldset.collapsed .collapse-toggle {
520
588
  *******************************************************/
521
589
  .htmx-swapping:before {
522
590
  @apply absolute bg-white bottom-0 left-0 opacity-80 transition-all right-0 top-0;
523
- content: '';
591
+ content: "";
524
592
  }
525
593
 
526
594
  .htmx-swapping:after {
527
595
  @apply absolute animate-spin h-4 inset-1/2 material-symbols-outlined md-16 text-gray-400 w-4;
528
- content: 'sync';
596
+ content: "sync";
529
597
  }
530
598
 
531
599
  /*******************************************************
532
600
  Filters
533
601
  *******************************************************/
534
602
  #changelist-filter .admin-numeric-filter-slider .noUi-handle {
535
- @apply bg-white border border-gray-200 cursor-pointer h-4 -right-4 rounded-full shadow-sm w-4 dark:bg-gray-200 dark:border-gray-200;
603
+ @apply bg-white border border-gray-200 cursor-pointer h-4 -right-4 rounded-full shadow-sm w-4 dark:bg-gray-200 dark:border-gray-200;
536
604
  }
537
605
 
538
606
  #changelist-filter .admin-numeric-filter-slider .noUi-handle-upper {
539
- @apply right-0;
607
+ @apply right-0;
540
608
  }
541
609
 
542
610
  #changelist-filter .admin-numeric-filter-slider .noUi-handle:after {
543
- content: none;
611
+ content: none;
544
612
  }
545
613
 
546
614
  #changelist-filter .admin-numeric-filter-slider .noUi-handle:before {
547
- content: none;
615
+ content: none;
548
616
  }
549
617
 
550
618
  #changelist-filter .admin-numeric-filter-slider.noUi-target {
@@ -556,7 +624,7 @@ fieldset.collapsed .collapse-toggle {
556
624
  }
557
625
 
558
626
  #changelist-filter .admin-numeric-filter-slider-tooltips {
559
- @apply flex flex-row font-medium mb-5 space-x-4 text-gray-500 text-sm;
627
+ @apply flex flex-row font-medium mb-5 space-x-4 text-gray-500 text-sm;
560
628
  }
561
629
 
562
630
  /*******************************************************
@@ -111,7 +111,7 @@
111
111
  {% if field.is_readonly or not field.field.is_hidden %}
112
112
  <td{% if field.field.name %} class="field-{{ field.field.name }}{% if field.field.errors|length > 0 %} errors{% endif %}{% if inline_admin_form.original %} p-3 lg:py-3{% else %} py-3{% endif %}{% if field.is_checkbox %} align-middle{% else %} align-top{% endif %} {% if is_last_row and not inline_admin_formset.has_add_permission %}{% if is_last_col %}border-0 {% else %}border-b lg:border-0{% endif %}{% else %}border-b{% endif %} border-gray-200 flex items-center before:capitalize before:content-[attr(data-label)] before:mr-auto before:text-gray-500 before:w-72 lg:before:hidden font-normal px-3 text-left text-sm lg:table-cell dark:border-gray-800"{% endif %} data-label="{{ field.field.label }}">
113
113
  {% if field.is_readonly %}
114
- <p class="bg-gray-50 border font-medium px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm dark:bg-gray-900 dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800">
114
+ <p class="bg-gray-50 border font-medium max-w-lg px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm truncate whitespace-nowrap dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800">
115
115
  {{ field.contents }}
116
116
  </p>
117
117
  {% else %}
@@ -1,3 +1,5 @@
1
+ {% load unfold %}
2
+
1
3
  <fieldset class="module {{ fieldset.classes }}">
2
4
  {% if fieldset.name %}
3
5
  <h2 class="bg-gray-100 border border-transparent font-semibold mb-6 px-4 py-3 rounded-md text-gray-900 text-sm lg:-mx-4 dark:bg-white/[.02] dark:border dark:border-gray-800 dark:text-gray-200">
@@ -26,13 +28,7 @@
26
28
  </div>
27
29
 
28
30
  {% if field.is_readonly %}
29
- <div class="readonly bg-gray-50 border font-medium max-w-2xl px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800">
30
- {% if field.contents %}
31
- {{ field.contents }}
32
- {% else %}
33
- -
34
- {% endif %}
35
- </div>
31
+ <div class="readonly bg-gray-50 border font-medium max-w-2xl px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm dark:border-gray-700 dark:text-gray-400 dark:bg-gray-800 {% if field.is_json %}whitespace-pre{% endif %}">{% if field.contents %}{{ field.contents }}{% else %}-{% endif %}</div>
36
32
  {% else %}
37
33
  {{ field.field }}
38
34
  {% endif %}
@@ -0,0 +1,20 @@
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 %}">
3
+ {% for group, options, index in widget.optgroups %}
4
+ {% if group %}
5
+ <div>
6
+ <label>{{ group }}</label>
7
+ {% endif %}
8
+
9
+ {% for option in options %}
10
+ <div>
11
+ {% include option.template_name with widget=option %}
12
+ </div>
13
+ {% endfor %}
14
+
15
+ {% if group %}
16
+ </div>
17
+ {% endif %}
18
+ {% endfor %}
19
+ </div>
20
+ {% endwith %}
@@ -0,0 +1,12 @@
1
+ {% if widget.wrap_label %}
2
+ <label{% if widget.attrs.id %} for="{{ widget.attrs.id }}"{% endif %} class="flex flex-row items-center gap-2">
3
+ {% endif %}
4
+
5
+ {% include "django/forms/widgets/input.html" %}
6
+
7
+ {% if widget.wrap_label %}
8
+ <span class="text-sm text-gray-900 dark:text-gray-200">
9
+ {{ widget.label }}
10
+ </span>
11
+ </label>
12
+ {% endif %}
@@ -0,0 +1,9 @@
1
+ <div class="flex group mb-6 flex-col last:mb-4">
2
+ <label class="block font-medium mb-2 text-gray-900 text-sm dark:text-gray-200">
3
+ {{ title }}
4
+ </label>
5
+
6
+ <div class="readonly bg-gray-50 border font-medium max-w-2xl px-3 py-2 rounded-md shadow-sm text-gray-500 text-sm dark:border-gray-700 dark:bg-gray-800 dark:text-gray-400">
7
+ {{ value }}
8
+ </div>
9
+ </div>
@@ -0,0 +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">
2
+ {{ title }}
3
+ </button>
@@ -1,5 +1,6 @@
1
1
  from typing import Any, Dict, Mapping, Union
2
2
 
3
+ from django.forms import Field
3
4
  from django.template import Library, Node, TemplateSyntaxError
4
5
  from django.template.base import NodeList, Parser, Token
5
6
  from django.template.loader import render_to_string
@@ -107,3 +108,16 @@ def do_capture(parser: Parser, token: Token) -> CaptureNode:
107
108
  nodelist = parser.parse(("endcapture",))
108
109
  parser.delete_first_token()
109
110
  return CaptureNode(nodelist, var, silent)
111
+
112
+
113
+ @register.filter
114
+ def add_css_class(field: Field, classes: Union[list, tuple]) -> Field:
115
+ if type(classes) in (list, tuple):
116
+ classes = " ".join(classes)
117
+
118
+ if "class" in field.field.widget.attrs:
119
+ field.field.widget.attrs["class"] += f" {classes}"
120
+ else:
121
+ field.field.widget.attrs["class"] = classes
122
+
123
+ return field
unfold/widgets.py CHANGED
@@ -1,11 +1,13 @@
1
1
  from typing import Any, Callable, Dict, Optional, Tuple, Union
2
2
 
3
+ from django.contrib.admin.options import VERTICAL
3
4
  from django.contrib.admin.widgets import (
4
5
  AdminBigIntegerFieldWidget,
5
6
  AdminDateWidget,
6
7
  AdminEmailInputWidget,
7
8
  AdminFileWidget,
8
9
  AdminIntegerFieldWidget,
10
+ AdminRadioSelect,
9
11
  AdminSplitDateTime,
10
12
  AdminTextareaWidget,
11
13
  AdminTextInputWidget,
@@ -319,6 +321,23 @@ class UnfoldAdminSelect(Select):
319
321
  super().__init__(attrs, choices)
320
322
 
321
323
 
324
+ class UnfoldAdminRadioSelectWidget(AdminRadioSelect):
325
+ option_template_name = "admin/widgets/radio_option.html"
326
+
327
+ def __init__(self, radio_style: Optional[int] = None, *args, **kwargs):
328
+ super().__init__(*args, **kwargs)
329
+
330
+ if radio_style is None:
331
+ radio_style = VERTICAL
332
+
333
+ self.radio_style = radio_style
334
+
335
+ def get_context(self, *args, **kwargs) -> Dict[str, Any]:
336
+ context = super().get_context(*args, **kwargs)
337
+ context.update({"radio_style": self.radio_style})
338
+ return context
339
+
340
+
322
341
  try:
323
342
  from djmoney.forms.widgets import MoneyWidget
324
343
  from djmoney.settings import CURRENCY_CHOICES