@asd20/ui-next 2.27.1 → 2.28.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ # [2.28.0](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.27.2...ui-next-v2.28.0) (2026-10-02)
4
+
5
+
6
+ ### Features
7
+
8
+ * add handbook template ([ceef718](https://github.com/academydistrict20/asd20-ui-next/commit/ceef718735afda7dac57b80f4bf9f2e7e868c604))
9
+
10
+ ## [2.27.2](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.27.1...ui-next-v2.27.2) (2026-10-01)
11
+
12
+
13
+ ### Bug Fixes
14
+
15
+ * neutralize public form focus outlines ([ec90f2d](https://github.com/academydistrict20/asd20-ui-next/commit/ec90f2defd18effaf09fb0e8edf954565ce37612))
16
+
3
17
  ## [2.27.1](https://github.com/academydistrict20/asd20-ui-next/compare/ui-next-v2.27.0...ui-next-v2.27.1) (2026-10-01)
4
18
 
5
19
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@asd20/ui-next",
3
- "version": "2.27.1",
3
+ "version": "2.28.0",
4
4
  "private": false,
5
5
  "description": "ASD20 UI component library for Vue 3.",
6
6
  "license": "MIT",
@@ -217,7 +217,9 @@ export default {
217
217
  // Public intake controls must stay legible on every school theme. Limit the
218
218
  // neutral overrides to this wrapper so other site components keep their colors.
219
219
  --color__accent: #3d3d3d;
220
+ --color__accent-s10: #262626;
220
221
  --color__accent-t50: #9e9e9e;
222
+ --color__accent-t90: #efefef;
221
223
  --color__primary-t50: #666;
222
224
  --color__secondary-t50: #666;
223
225
  --website-card__reverse-background-color: #333;
@@ -0,0 +1,309 @@
1
+ <template>
2
+ <div class="asd20-template-handbook">
3
+ <asd20-skip-to to="#handbook-content" />
4
+
5
+ <asd20-site-navigation
6
+ v-bind="siteNavigationSearchProps"
7
+ :navigation="navigation"
8
+ :action-items="actionItems"
9
+ :menu-open="menuOpen"
10
+ :search-open="searchOpen"
11
+ :organization="organization"
12
+ :organization-options="organizationOptions"
13
+ @update:menuOpen="$emit('update:menuOpen', $event)"
14
+ @update:searchOpen="$emit('update:searchOpen', $event)"
15
+ />
16
+
17
+ <asd20-notification-group
18
+ :notifications="activeNotificationsByType.banner"
19
+ group-type="banner"
20
+ @dismiss="$emit('dismiss-notification', $event)"
21
+ @toggle-all="$emit('toggle-all')"
22
+ />
23
+
24
+ <asd20-page-header
25
+ :heading="title"
26
+ :lead="metaDescription"
27
+ :organization="organization"
28
+ :organization-options="organizationOptions"
29
+ :breadcrumb-links="breadcrumbLinks"
30
+ :language-code="languageCode"
31
+ @update:languageCode="$emit('update:languageCode', $event)"
32
+ >
33
+ <template #top>
34
+ <asd20-notification-group
35
+ class="asd20-notification-group--floating"
36
+ :notifications="activeNotificationsByType.floating"
37
+ :total-dismissed-notifications="totalDismissedNotifications"
38
+ group-type="floating"
39
+ @dismiss="$emit('dismiss-notification', $event)"
40
+ @toggle-all="$emit('toggle-all')"
41
+ />
42
+ </template>
43
+ </asd20-page-header>
44
+
45
+ <asd20-notification-group
46
+ :notifications="activeNotificationsByType.inline"
47
+ group-type="inline"
48
+ @dismiss="$emit('dismiss-notification', $event)"
49
+ @toggle-all="$emit('toggle-all')"
50
+ />
51
+
52
+ <main
53
+ id="handbook-content"
54
+ class="asd20-template-handbook__layout"
55
+ tabindex="-1"
56
+ >
57
+ <nav
58
+ class="asd20-template-handbook__index"
59
+ aria-label="Handbook topics"
60
+ >
61
+ <button
62
+ class="asd20-template-handbook__index-toggle"
63
+ type="button"
64
+ :aria-expanded="topicsOpen"
65
+ aria-controls="handbook-topics"
66
+ @click="topicsOpen = !topicsOpen"
67
+ >
68
+ Topics
69
+ </button>
70
+ <h2 class="asd20-template-handbook__index-heading">
71
+ Topics
72
+ </h2>
73
+ <ol
74
+ id="handbook-topics"
75
+ :class="{ 'is-open': topicsOpen }"
76
+ >
77
+ <li
78
+ v-for="message in messages"
79
+ :key="message.id"
80
+ >
81
+ <button
82
+ type="button"
83
+ :aria-current="activeMessage && activeMessage.id === message.id ? 'true' : null"
84
+ @click="selectTopic(message.id)"
85
+ >
86
+ {{ message.heading || message.title }}
87
+ </button>
88
+ </li>
89
+ </ol>
90
+ </nav>
91
+
92
+ <article
93
+ v-for="message in messages"
94
+ :key="message.id"
95
+ class="asd20-template-handbook__topic"
96
+ :class="{ 'is-active': activeMessage && activeMessage.id === message.id }"
97
+ >
98
+ <h2
99
+ tabindex="-1"
100
+ >
101
+ {{ message.heading || message.title }}
102
+ </h2>
103
+ <asd20-messaging
104
+ v-bind="message"
105
+ heading=""
106
+ detail-link=""
107
+ />
108
+ </article>
109
+ <p v-if="!messages.length">
110
+ No handbook topics are available yet.
111
+ </p>
112
+ </main>
113
+
114
+ <asd20-quicklinks-menu :quick-links="quickLinks" />
115
+ <asd20-page-footer
116
+ :organization="organization"
117
+ :social-links="socialLinks"
118
+ :disclosure-links="disclosureLinks"
119
+ :website-logo-props="websiteLogoProps"
120
+ :website-logo-props2="websiteLogoProps2"
121
+ />
122
+ </div>
123
+ </template>
124
+
125
+ <script>
126
+ import { nextTick } from 'vue'
127
+ import Asd20SkipTo from '../../../components/atoms/Asd20SkipTo'
128
+ import Asd20Messaging from '../../../components/atoms/Asd20Messaging'
129
+ import Asd20PageHeader from '../../../components/organisms/Asd20PageHeader'
130
+ import Asd20SiteNavigation from '../../../components/organisms/Asd20SiteNavigation'
131
+ import Asd20NotificationGroup from '../../../components/organisms/Asd20NotificationGroup'
132
+ import Asd20QuicklinksMenu from '../../../components/organisms/Asd20QuicklinksMenu'
133
+ import Asd20PageFooter from '../../../components/organisms/Asd20PageFooter'
134
+ import pageTemplateMixin from '../../../mixins/pageTemplateMixin'
135
+
136
+ export default {
137
+ name: 'Asd20HandbookTemplate',
138
+ components: {
139
+ Asd20SkipTo,
140
+ Asd20Messaging,
141
+ Asd20PageHeader,
142
+ Asd20SiteNavigation,
143
+ Asd20NotificationGroup,
144
+ Asd20QuicklinksMenu,
145
+ Asd20PageFooter,
146
+ },
147
+ mixins: [pageTemplateMixin],
148
+ data: () => ({
149
+ selectedMessageId: null,
150
+ topicsOpen: false,
151
+ }),
152
+ computed: {
153
+ activeMessage() {
154
+ return this.messages.find(message => message.id === this.selectedMessageId)
155
+ || this.messages[0]
156
+ || null
157
+ },
158
+ },
159
+ methods: {
160
+ async selectTopic(messageId) {
161
+ this.selectedMessageId = messageId
162
+ this.topicsOpen = false
163
+ await nextTick()
164
+ this.$el.querySelector('.asd20-template-handbook__topic.is-active h2')?.focus()
165
+ },
166
+ },
167
+ }
168
+ </script>
169
+
170
+ <style src="../../../design/tokens.css"></style>
171
+
172
+ <style lang="scss">
173
+ @use '../../../design/template-stack' as *;
174
+
175
+ .asd20-template-handbook {
176
+ @include typography;
177
+ @include template;
178
+ display: flex;
179
+ flex-direction: column;
180
+ flex-grow: 1;
181
+ min-width: 0;
182
+ margin-top: space(2.25);
183
+
184
+ &__layout {
185
+ display: grid;
186
+ grid-template-columns: minmax(0, 1fr);
187
+ gap: space(2);
188
+ min-width: 0;
189
+ padding: space(2) space(1);
190
+ }
191
+
192
+ &__index ol {
193
+ display: none;
194
+ list-style: none;
195
+ margin: 0;
196
+ padding: 0;
197
+ }
198
+
199
+ &__index ol.is-open {
200
+ display: block;
201
+ }
202
+
203
+ &__index-heading {
204
+ display: none;
205
+ }
206
+
207
+ &__index button {
208
+ font: inherit;
209
+ text-align: start;
210
+ cursor: pointer;
211
+ }
212
+
213
+ &__index li button {
214
+ display: block;
215
+ width: 100%;
216
+ min-height: 44px;
217
+ padding: space(0.5);
218
+ border: 0;
219
+ border-left: 3px solid transparent;
220
+ background: transparent;
221
+ color: inherit;
222
+ }
223
+
224
+ &__index li button:hover,
225
+ &__index li button:focus-visible {
226
+ background: var(--color__tertiary-t50);
227
+ }
228
+
229
+ &__index li button[aria-current='true'] {
230
+ border-left-color: var(--color__primary);
231
+ background: var(--color__tertiary-t50);
232
+ font-weight: bold;
233
+ }
234
+
235
+ &__index-toggle {
236
+ width: 100%;
237
+ min-height: 44px;
238
+ padding: space(0.5);
239
+ border: 1px solid var(--color__primary);
240
+ border-radius: 0.25rem;
241
+ background: var(--color__tertiary-t50);
242
+ color: var(--color__primary);
243
+ font-weight: bold;
244
+ }
245
+
246
+ &__topic {
247
+ min-width: 0;
248
+ }
249
+
250
+ &__topic:not(.is-active) {
251
+ display: none;
252
+ }
253
+ }
254
+
255
+ @media (min-width: 768px) {
256
+ .asd20-template-handbook {
257
+ &__layout {
258
+ grid-template-columns: minmax(12rem, 16rem) minmax(0, 1fr);
259
+ gap: space(3);
260
+ padding: space(3);
261
+ }
262
+
263
+ &__index {
264
+ position: sticky;
265
+ top: space(2);
266
+ align-self: start;
267
+ max-height: calc(100vh - 4rem);
268
+ overflow-y: auto;
269
+ }
270
+
271
+ &__index-heading,
272
+ &__index ol {
273
+ display: block;
274
+ }
275
+
276
+ &__index-toggle {
277
+ display: none;
278
+ }
279
+ }
280
+ }
281
+
282
+ @media (min-width: 1024px) {
283
+ .asd20-template-handbook {
284
+ margin-left: space(3);
285
+ margin-top: 0;
286
+ }
287
+ }
288
+
289
+ @media print {
290
+ .asd20-template-handbook {
291
+ &__index {
292
+ display: none;
293
+ }
294
+
295
+ &__layout {
296
+ display: block;
297
+ }
298
+
299
+ &__topic,
300
+ &__topic:not(.is-active) {
301
+ display: block;
302
+ }
303
+
304
+ &__topic {
305
+ break-inside: avoid-page;
306
+ }
307
+ }
308
+ }
309
+ </style>
package/templates.js CHANGED
@@ -16,6 +16,7 @@ export { default as Asd20DistrictHomeTemplate } from './src/components/templates
16
16
  export { default as Asd20DistrictVideoTemplate } from './src/components/templates/Asd20DistrictVideoTemplate/index.vue'
17
17
  export { default as Asd20FileListPageTemplate } from './src/components/templates/Asd20FileListPageTemplate/index.vue'
18
18
  export { default as Asd20GroupFeatureTemplate } from './src/components/templates/Asd20GroupFeatureTemplate/index.vue'
19
+ export { default as Asd20HandbookTemplate } from './src/components/templates/Asd20HandbookTemplate/index.vue'
19
20
  export { default as Asd20LoginsTemplate } from './src/components/templates/Asd20LoginsTemplate/index.vue'
20
21
  export { default as Asd20PeopleFeatureTemplate } from './src/components/templates/Asd20PeopleFeatureTemplate/index.vue'
21
22
  export { default as Asd20ProfileTemplate } from './src/components/templates/Asd20ProfileTemplate/index.vue'