@abreen/tada 1.16.6 → 1.16.8

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/README.md CHANGED
@@ -243,6 +243,7 @@ fontOverrides:
243
243
  features:
244
244
  search: true
245
245
  favicon: true
246
+ pickers: true
246
247
  base: https://example.edu
247
248
  basePath: /cs0
248
249
  internalDomains:
@@ -274,6 +275,7 @@ vars:
274
275
  | `features.search` | Enable search UI and Pagefind index generation |
275
276
  | `features.favicon` | Enable automatically generated favicons |
276
277
  | `features.footer` | Show the Tada footer at the bottom of every page |
278
+ | `features.pickers` | Show the font and contrast pickers at the bottom of every page (default `true`) |
277
279
  | `base` | Full base URL of the deployed site, used for metadata and URL generation |
278
280
  | `basePath` | URL prefix for deployment under a subpath (e.g., `"/cs101"`), use `"/"` at root |
279
281
  | `internalDomains` | Domain names treated as internal by link processing (not marked external) |
package/bin/validators.ts CHANGED
@@ -49,8 +49,8 @@ export function validateUrl(value: string): string | null {
49
49
  }
50
50
 
51
51
  export function validateBasePath(value: string): string | null {
52
- if (!/^\/[-a-zA-Z0-9]*$/.test(value)) {
53
- return 'Must start with / and contain only letters, digits, and hyphens';
52
+ if (!/^\/(?:[-a-zA-Z0-9]+(?:\/[-a-zA-Z0-9]+)*)?$/.test(value)) {
53
+ return 'Must start with / and contain path segments made of letters, digits, and hyphens';
54
54
  }
55
55
  return null;
56
56
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@abreen/tada",
3
- "version": "1.16.6",
3
+ "version": "1.16.8",
4
4
  "type": "module",
5
5
  "description": "A static site generator",
6
6
  "license": "MIT",
@@ -22,7 +22,7 @@
22
22
  "basePath": {
23
23
  "type": "string",
24
24
  "default": "/",
25
- "pattern": "^\\/[-a-zA-Z0-9]*?$"
25
+ "pattern": "^\\/(?:[-a-zA-Z0-9]+(?:\\/[-a-zA-Z0-9]+)*)?$"
26
26
  },
27
27
  "internalDomains": {
28
28
  "type": "array",
@@ -5,6 +5,9 @@
5
5
  }
6
6
 
7
7
  header {
8
+ --header-search-reservation: 0px;
9
+ --header-to-top-reservation: 0px;
10
+
8
11
  position: fixed;
9
12
  top: 0;
10
13
  z-index: 1000;
@@ -14,19 +17,36 @@ header {
14
17
  background: var(--bg-color-translucent);
15
18
  backdrop-filter: var(--backdrop-filter);
16
19
  view-transition-name: site-header;
20
+
21
+ &:has(.search-controls) {
22
+ --header-search-reservation: 200px;
23
+
24
+ @media (width <= 400px) {
25
+ --header-search-reservation: 0px;
26
+ }
27
+ }
28
+
29
+ &:has(.to-top-container .is-visible) {
30
+ --header-to-top-reservation: 120px;
31
+ }
17
32
  }
18
33
 
19
34
  :root[data-contrast-preference='high'] header {
20
35
  background: var(--bg-color);
21
36
  }
22
37
 
38
+ header > details {
39
+ min-width: 0;
40
+ }
41
+
23
42
  header details summary {
24
43
  position: relative;
25
44
  display: flex;
26
45
  align-items: center;
27
46
  height: var(--header-collapsed-height);
28
- padding: 0 200px 0 0;
29
- container-type: inline-size;
47
+ padding: 0
48
+ calc(var(--header-search-reservation) + var(--header-to-top-reservation)) 0
49
+ 0;
30
50
  cursor: pointer;
31
51
  list-style-type: none;
32
52
 
@@ -47,10 +67,6 @@ header details summary {
47
67
  }
48
68
  }
49
69
 
50
- header:has(.to-top-container .is-visible) details summary {
51
- padding-right: 320px;
52
- }
53
-
54
70
  header details summary::-webkit-details-marker {
55
71
  display: none;
56
72
  }
@@ -105,12 +121,6 @@ header summary .site-title {
105
121
  pointer-events: none;
106
122
  }
107
123
 
108
- @container (max-width: 200px) {
109
- header summary .site-title {
110
- display: none;
111
- }
112
- }
113
-
114
124
  header > .header-controls {
115
125
  position: absolute;
116
126
  top: 0;
@@ -220,7 +220,7 @@
220
220
  }
221
221
 
222
222
  @media print {
223
- .question-a-body {
223
+ .js .question-a-body {
224
224
  cursor: default;
225
225
 
226
226
  @include user-select(text);
package/src/style.scss CHANGED
@@ -93,14 +93,28 @@ a.disabled {
93
93
  }
94
94
 
95
95
  .external-link-tail::after,
96
+ a.external:not(:has(.external-link-tail))::after {
97
+ vertical-align: text-top;
98
+
99
+ @include contained-mask(var(--icon-external-link));
100
+ }
101
+
102
+ .external-link-tail::after {
103
+ display: inline;
104
+
105
+ // With zero font metrics, block-end padding paints down from text-top.
106
+ padding-block-end: var(--icon-external-link-size);
107
+ padding-inline-start: var(--icon-external-link-size);
108
+ font-size: 0;
109
+ line-height: 0;
110
+ content: '\2060' / '';
111
+ }
112
+
96
113
  a.external:not(:has(.external-link-tail))::after {
97
114
  display: inline-block;
98
115
  width: var(--icon-external-link-size);
99
116
  height: var(--icon-external-link-size);
100
- vertical-align: text-top;
101
117
  content: '';
102
-
103
- @include contained-mask(var(--icon-external-link));
104
118
  }
105
119
 
106
120
  .footnotes {