vanta-admin 0.4.0__tar.gz → 0.5.0__tar.gz

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 (44) hide show
  1. {vanta_admin-0.4.0/vanta_admin.egg-info → vanta_admin-0.5.0}/PKG-INFO +3 -1
  2. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/README.md +2 -0
  3. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/pyproject.toml +1 -1
  4. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.admin.css +83 -8
  5. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.tokens.css +16 -16
  6. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/js/sidebar.js +64 -0
  7. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/nav_sidebar.html +13 -0
  8. {vanta_admin-0.4.0 → vanta_admin-0.5.0/vanta_admin.egg-info}/PKG-INFO +3 -1
  9. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/LICENSE +0 -0
  10. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/MANIFEST.in +0 -0
  11. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/setup.cfg +0 -0
  12. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/__init__.py +0 -0
  13. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/apps.py +0 -0
  14. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.base.css +0 -0
  15. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.css +0 -0
  16. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.login.css +0 -0
  17. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/theme.responsive.css +0 -0
  18. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/css/two_factor.css +0 -0
  19. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/img/favicon.png +0 -0
  20. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/js/changelist.js +0 -0
  21. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/js/forms.js +0 -0
  22. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/js/messages.js +0 -0
  23. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/static/admin/js/vanta-theme.js +0 -0
  24. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/app_index.html +0 -0
  25. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/base.html +0 -0
  26. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/base_site.html +0 -0
  27. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/change_form.html +0 -0
  28. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/change_list.html +0 -0
  29. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/filter.html +0 -0
  30. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/includes/breadcrumbs.html +0 -0
  31. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/index.html +0 -0
  32. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/admin/login.html +0 -0
  33. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/_base.html +0 -0
  34. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/_base_focus.html +0 -0
  35. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/_wizard_actions.html +0 -0
  36. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/core/login.html +0 -0
  37. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/core/setup_complete.html +0 -0
  38. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templates/two_factor/profile/profile.html +0 -0
  39. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templatetags/__init__.py +0 -0
  40. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin/templatetags/admin_theme.py +0 -0
  41. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin.egg-info/SOURCES.txt +0 -0
  42. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin.egg-info/dependency_links.txt +0 -0
  43. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin.egg-info/requires.txt +0 -0
  44. {vanta_admin-0.4.0 → vanta_admin-0.5.0}/vanta_admin.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vanta-admin
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: A sharp, dark, and portable Django admin theme forged for builders who want the admin to feel less default.
5
5
  Author: oli-dev0
6
6
  License-Expression: MIT
@@ -35,7 +35,9 @@ feels more deliberate in everyday use.
35
35
  ## What It Adds
36
36
 
37
37
  - A cleaner admin layout with a fixed sidebar that remembers how you left it.
38
+ - A sidebar navigation filter that lets users quickly narrow large admin menus by app or model name.
38
39
  - Light and dark mode, using the same calm Vanta look across the admin.
40
+ - A more settled light-mode palette with clearer search focus states and stronger changelist table headers.
39
41
  - Less visual noise on the main admin screens, login pages, cards, filters, and
40
42
  two-factor auth pages.
41
43
  - Denser dashboards, tables, filters, messages, and forms so admin work feels
@@ -10,7 +10,9 @@ feels more deliberate in everyday use.
10
10
  ## What It Adds
11
11
 
12
12
  - A cleaner admin layout with a fixed sidebar that remembers how you left it.
13
+ - A sidebar navigation filter that lets users quickly narrow large admin menus by app or model name.
13
14
  - Light and dark mode, using the same calm Vanta look across the admin.
15
+ - A more settled light-mode palette with clearer search focus states and stronger changelist table headers.
14
16
  - Less visual noise on the main admin screens, login pages, cards, filters, and
15
17
  two-factor auth pages.
16
18
  - Denser dashboards, tables, filters, messages, and forms so admin work feels
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "vanta-admin"
7
- version = "0.4.0"
7
+ version = "0.5.0"
8
8
  description = "A sharp, dark, and portable Django admin theme forged for builders who want the admin to feel less default."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -112,11 +112,66 @@ body.admin-sidebar-collapsed .admin-sidebar__collapse-arrow {
112
112
  white-space: nowrap;
113
113
  }
114
114
 
115
+ .admin-sidebar__filter {
116
+ position: relative;
117
+ display: flex;
118
+ align-items: center;
119
+ padding: 0.85rem 1rem 0;
120
+ }
121
+
122
+ .admin-sidebar__filter::before {
123
+ content: "";
124
+ position: absolute;
125
+ left: 1.72rem;
126
+ width: 0.95rem;
127
+ height: 0.95rem;
128
+ background: var(--accent);
129
+ mask: url("../img/search.svg") center / contain no-repeat;
130
+ -webkit-mask: url("../img/search.svg") center / contain no-repeat;
131
+ pointer-events: none;
132
+ }
133
+
134
+ #nav-sidebar .admin-sidebar__filter input[type="search"] {
135
+ width: 100%;
136
+ min-height: 2rem;
137
+ border: 0;
138
+ border-radius: 0.27rem;
139
+ background: var(--surface-muted);
140
+ color: var(--text);
141
+ padding: 0.32rem 0.7rem 0.32rem 2.65rem;
142
+ font-size: 0.82rem;
143
+ font-weight: 650;
144
+ outline: none;
145
+ transition:
146
+ background-color var(--admin-transition),
147
+ color var(--admin-transition);
148
+ }
149
+
150
+ #nav-sidebar .admin-sidebar__filter input[type="search"]::placeholder {
151
+ color: var(--admin-muted);
152
+ opacity: 0.82;
153
+ }
154
+
155
+ #nav-sidebar .admin-sidebar__filter input[type="search"]:focus,
156
+ #nav-sidebar .admin-sidebar__filter input[type="search"]:focus-visible {
157
+ background: var(--surface);
158
+ box-shadow: none;
159
+ }
160
+
161
+ #nav-sidebar .admin-sidebar__filter input[type="search"]::-webkit-search-decoration {
162
+ appearance: none;
163
+ }
164
+
165
+ html[data-theme="light"] #nav-sidebar .admin-sidebar__filter input[type="search"]:focus,
166
+ html[data-theme="light"] #nav-sidebar .admin-sidebar__filter input[type="search"]:focus-visible {
167
+ background: #e8f1fa;
168
+ }
169
+
115
170
  .admin-sidebar__groups {
116
171
  flex: 1 1 auto;
117
172
  min-height: 0;
118
173
  overflow-y: auto;
119
- padding: 0.9rem 1rem 8.25rem;
174
+ padding: 0.65rem 1rem 8.25rem;
120
175
  scrollbar-color: var(--border-strong) transparent;
121
176
  scrollbar-width: thin;
122
177
  }
@@ -350,7 +405,7 @@ body.admin-sidebar-collapsed .admin-sidebar__collapse-arrow {
350
405
  }
351
406
 
352
407
  .admin-sidebar__section-title {
353
- margin: 0 0 0.48rem;
408
+ margin: 0 0 0.24rem;
354
409
  color: var(--subtle);
355
410
  font-size: 0.72rem;
356
411
  font-weight: 760;
@@ -358,7 +413,7 @@ body.admin-sidebar-collapsed .admin-sidebar__collapse-arrow {
358
413
 
359
414
  .admin-sidebar__display-section {
360
415
  display: grid;
361
- gap: 0.38rem;
416
+ gap: 0.16rem;
362
417
  }
363
418
 
364
419
  .admin-sidebar__display-row {
@@ -391,9 +446,9 @@ body.admin-sidebar-collapsed .admin-sidebar__collapse-arrow {
391
446
  .admin-sidebar__time-controls {
392
447
  display: grid;
393
448
  grid-template-columns: 1fr 1fr;
394
- gap: 0.32rem;
395
- padding: 0.25rem;
396
- width: 5.4rem;
449
+ gap: 0.24rem;
450
+ padding: 0.18rem;
451
+ width: 4.75rem;
397
452
  border-radius: 0.34rem;
398
453
  background: var(--surface-muted);
399
454
  }
@@ -404,8 +459,8 @@ body.admin-sidebar-collapsed .admin-sidebar__collapse-arrow {
404
459
  align-items: center;
405
460
  justify-content: center;
406
461
  gap: 0.42rem;
407
- min-height: 2.05rem;
408
- padding: 0 0.58rem;
462
+ min-height: 1.62rem;
463
+ padding: 0 0.38rem;
409
464
  border: 0;
410
465
  border-radius: 0.27rem;
411
466
  background: transparent;
@@ -591,6 +646,7 @@ body.admin-sidebar-collapsed .admin-sidebar {
591
646
  }
592
647
 
593
648
  body.admin-sidebar-collapsed .admin-sidebar__brand,
649
+ body.admin-sidebar-collapsed .admin-sidebar__filter,
594
650
  body.admin-sidebar-collapsed .admin-sidebar__groups,
595
651
  body.admin-sidebar-collapsed .admin-sidebar__account {
596
652
  display: none;
@@ -1132,6 +1188,11 @@ select,
1132
1188
  max-width: 16.8rem;
1133
1189
  }
1134
1190
 
1191
+ html[data-theme="light"] #changelist-search input[type="text"]:focus,
1192
+ html[data-theme="light"] #changelist input[type="search"]:focus {
1193
+ background: #e8f1fa;
1194
+ }
1195
+
1135
1196
  #changelist .actions select {
1136
1197
  appearance: none;
1137
1198
  min-height: 1.5rem;
@@ -1576,6 +1637,10 @@ input[type="checkbox"]:focus-visible {
1576
1637
  vertical-align: middle;
1577
1638
  }
1578
1639
 
1640
+ html[data-theme="light"] #changelist table thead th {
1641
+ background: #d5e3f1;
1642
+ }
1643
+
1579
1644
  #changelist table thead th:first-child {
1580
1645
  border-radius: var(--admin-radius-sm) 0 0 var(--admin-radius-sm);
1581
1646
  }
@@ -1620,6 +1685,11 @@ input[type="checkbox"]:focus-visible {
1620
1685
  transform: translateY(-2px);
1621
1686
  }
1622
1687
 
1688
+ html[data-theme="light"] #changelist table thead th a:hover,
1689
+ html[data-theme="light"] #changelist table thead th a:focus {
1690
+ background: #c7d9eb;
1691
+ }
1692
+
1623
1693
  #changelist table thead th a:focus-visible {
1624
1694
  outline: 2px solid var(--admin-accent);
1625
1695
  outline-offset: 2px;
@@ -1638,6 +1708,11 @@ input[type="checkbox"]:focus-visible {
1638
1708
  vertical-align: middle;
1639
1709
  }
1640
1710
 
1711
+ html[data-theme="light"] #changelist table thead th.sorted .text,
1712
+ html[data-theme="light"] #changelist table thead th.sorted .sortoptions {
1713
+ background: #c7d9eb !important;
1714
+ }
1715
+
1641
1716
  #changelist table thead th.sorted .text {
1642
1717
  float: none !important;
1643
1718
  padding: 0 !important;
@@ -93,15 +93,15 @@ body[data-theme="light"],
93
93
  body.theme-light,
94
94
  .theme-light {
95
95
  color-scheme: light;
96
- --page-bg: #ffffff;
97
- --shell-bg: #ffffff;
98
- --sidebar-bg: #f6faff;
99
- --surface: #f6faff;
100
- --surface-strong: #ffffff;
101
- --surface-muted: #f1f7ff;
102
- --surface-hover: #eaf4ff;
103
- --row-bg: #ffffff;
104
- --row-bg-alt: #f4f9ff;
96
+ --page-bg: #f3f7fb;
97
+ --shell-bg: #f3f7fb;
98
+ --sidebar-bg: #eef5fb;
99
+ --surface: #f7fbff;
100
+ --surface-strong: #fbfdff;
101
+ --surface-muted: #dfeaf5;
102
+ --surface-hover: #e4f0fb;
103
+ --row-bg: #fbfdff;
104
+ --row-bg-alt: #f2f8fe;
105
105
  --border: #d7e6f4;
106
106
  --border-strong: #bcd3e8;
107
107
  --text: #102033;
@@ -114,12 +114,12 @@ body.theme-light,
114
114
  --accent-softer: color-mix(in srgb, var(--accent) 8%, transparent);
115
115
  --shadow: none;
116
116
  --shadow-soft: none;
117
- --input-bg: #ffffff;
118
- --admin-bg: #ffffff;
119
- --admin-sidebar-bg: #f6faff;
120
- --admin-surface: #ffffff;
121
- --admin-surface-muted: #f6faff;
122
- --admin-surface-raised: #f1f7ff;
117
+ --input-bg: #dfeaf5;
118
+ --admin-bg: #f3f7fb;
119
+ --admin-sidebar-bg: #eef5fb;
120
+ --admin-surface: #fbfdff;
121
+ --admin-surface-muted: #dfeaf5;
122
+ --admin-surface-raised: #f7fbff;
123
123
  --admin-text: #102033;
124
124
  --admin-muted: #4f647a;
125
125
  --admin-muted-soft: #71879d;
@@ -146,7 +146,7 @@ body.theme-light,
146
146
  --admin-warning-bg: color-mix(in srgb, var(--admin-warning) 14%, transparent);
147
147
  --admin-link: color-mix(in srgb, var(--admin-accent) 78%, var(--admin-muted));
148
148
  --admin-link-strong: color-mix(in srgb, var(--admin-accent) 86%, var(--admin-text));
149
- --admin-nav-item-active-bg: #eaf4ff;
149
+ --admin-nav-item-active-bg: #dbe9f7;
150
150
  --admin-nav-item-active-border: color-mix(in srgb, var(--admin-accent) 34%, var(--admin-border));
151
151
  --admin-button-text: #ffffff;
152
152
  --admin-shadow-soft: none;
@@ -10,8 +10,10 @@
10
10
  const collapseButton = document.getElementById('admin-sidebar-collapse');
11
11
  const menuButton = document.getElementById('admin-sidebar-menu-button');
12
12
  const accountDetails = document.querySelector('.admin-sidebar__account');
13
+ const navFilter = document.getElementById('admin-nav-filter');
13
14
  const mobileQuery = window.matchMedia('(max-width: 1024px)');
14
15
  const navSections = Array.from(document.querySelectorAll('[data-admin-nav-section]'));
16
+ let isFilteringNavigation = false;
15
17
 
16
18
  function setCollapsed(isCollapsed, shouldPersist) {
17
19
  body.classList.toggle('admin-sidebar-collapsed', isCollapsed);
@@ -75,6 +77,10 @@
75
77
  }
76
78
 
77
79
  function persistOpenSections() {
80
+ if (isFilteringNavigation) {
81
+ return;
82
+ }
83
+
78
84
  const openSections = navSections
79
85
  .filter(isSectionOpen)
80
86
  .map(getSectionKey)
@@ -83,6 +89,60 @@
83
89
  localStorage.setItem(navSectionsStateKey, JSON.stringify(openSections));
84
90
  }
85
91
 
92
+ function normalizeFilterValue(value) {
93
+ return value.trim().toLowerCase();
94
+ }
95
+
96
+ function getNavItemText(element) {
97
+ return element.textContent.trim().toLowerCase();
98
+ }
99
+
100
+ function filterNavigation() {
101
+ if (!navFilter) {
102
+ return;
103
+ }
104
+
105
+ const query = normalizeFilterValue(navFilter.value);
106
+ const hasQuery = query.length > 0;
107
+
108
+ isFilteringNavigation = true;
109
+
110
+ navSections.forEach((section) => {
111
+ const sectionTitle = section.querySelector('.admin-sidebar__group-title span');
112
+ const modelItems = Array.from(section.querySelectorAll('.admin-sidebar__model'));
113
+ const matchesSection = sectionTitle && getNavItemText(sectionTitle).includes(query);
114
+ let hasVisibleModel = false;
115
+
116
+ modelItems.forEach((item) => {
117
+ const matchesModel = getNavItemText(item).includes(query);
118
+ const isVisible = !hasQuery || matchesSection || matchesModel;
119
+
120
+ item.hidden = !isVisible;
121
+ hasVisibleModel = hasVisibleModel || isVisible;
122
+ });
123
+
124
+ section.hidden = hasQuery && !matchesSection && !hasVisibleModel;
125
+
126
+ if (hasQuery && !section.hidden) {
127
+ section.open = true;
128
+ }
129
+
130
+ syncSectionAria(section);
131
+ });
132
+
133
+ if (!hasQuery) {
134
+ applyStoredOpenSections();
135
+ navSections.forEach((section) => {
136
+ section.hidden = false;
137
+ section.querySelectorAll('.admin-sidebar__model').forEach((item) => {
138
+ item.hidden = false;
139
+ });
140
+ });
141
+ }
142
+
143
+ isFilteringNavigation = false;
144
+ }
145
+
86
146
  function applyStoredOpenSections() {
87
147
  const storedOpenSections = getStoredOpenSections();
88
148
 
@@ -134,6 +194,10 @@
134
194
  });
135
195
  });
136
196
 
197
+ if (navFilter) {
198
+ navFilter.addEventListener('input', filterNavigation);
199
+ }
200
+
137
201
  document.addEventListener('keydown', (event) => {
138
202
  if (event.key === 'Escape') {
139
203
  setMobileOpen(false);
@@ -52,6 +52,19 @@
52
52
  </div>
53
53
  </div>
54
54
 
55
+ {% if available_apps %}
56
+ <div class="admin-sidebar__filter">
57
+ <label class="visually-hidden" for="admin-nav-filter">Filter navigation items</label>
58
+ <input
59
+ type="search"
60
+ id="admin-nav-filter"
61
+ autocomplete="off"
62
+ spellcheck="false"
63
+ placeholder="Start typing to filter..."
64
+ >
65
+ </div>
66
+ {% endif %}
67
+
55
68
  <div class="admin-sidebar__groups">
56
69
  {% if available_apps %}
57
70
  {% grouped_admin_nav_apps available_apps as nav_apps %}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vanta-admin
3
- Version: 0.4.0
3
+ Version: 0.5.0
4
4
  Summary: A sharp, dark, and portable Django admin theme forged for builders who want the admin to feel less default.
5
5
  Author: oli-dev0
6
6
  License-Expression: MIT
@@ -35,7 +35,9 @@ feels more deliberate in everyday use.
35
35
  ## What It Adds
36
36
 
37
37
  - A cleaner admin layout with a fixed sidebar that remembers how you left it.
38
+ - A sidebar navigation filter that lets users quickly narrow large admin menus by app or model name.
38
39
  - Light and dark mode, using the same calm Vanta look across the admin.
40
+ - A more settled light-mode palette with clearer search focus states and stronger changelist table headers.
39
41
  - Less visual noise on the main admin screens, login pages, cards, filters, and
40
42
  two-factor auth pages.
41
43
  - Denser dashboards, tables, filters, messages, and forms so admin work feels
File without changes
File without changes
File without changes