@xaroth.nl/design 0.1.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.
Files changed (193) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +62 -0
  3. package/dist/all.css +2536 -0
  4. package/dist/astro.d.ts +41 -0
  5. package/dist/astro.js +41 -0
  6. package/dist/bem.d.ts +12 -0
  7. package/dist/bem.js +19 -0
  8. package/dist/components/alert/alert.astro +46 -0
  9. package/dist/components/alert/alert.css +68 -0
  10. package/dist/components/alert/alert.d.ts +11 -0
  11. package/dist/components/alert/alert.js +6 -0
  12. package/dist/components/alert/index.d.ts +14 -0
  13. package/dist/components/alert/index.js +27 -0
  14. package/dist/components/avatar/avatar.astro +23 -0
  15. package/dist/components/avatar/avatar.css +35 -0
  16. package/dist/components/avatar/avatar.d.ts +5 -0
  17. package/dist/components/avatar/avatar.js +7 -0
  18. package/dist/components/avatar/index.d.ts +32 -0
  19. package/dist/components/avatar/index.js +24 -0
  20. package/dist/components/badge/badge.astro +11 -0
  21. package/dist/components/badge/badge.css +46 -0
  22. package/dist/components/badge/badge.d.ts +5 -0
  23. package/dist/components/badge/badge.js +6 -0
  24. package/dist/components/badge/index.d.ts +6 -0
  25. package/dist/components/badge/index.js +3 -0
  26. package/dist/components/breadcrumbs/breadcrumbs.astro +27 -0
  27. package/dist/components/breadcrumbs/breadcrumbs.css +33 -0
  28. package/dist/components/breadcrumbs/breadcrumbs.d.ts +9 -0
  29. package/dist/components/breadcrumbs/breadcrumbs.js +11 -0
  30. package/dist/components/breadcrumbs/index.d.ts +37 -0
  31. package/dist/components/breadcrumbs/index.js +16 -0
  32. package/dist/components/button/button.astro +36 -0
  33. package/dist/components/button/button.css +117 -0
  34. package/dist/components/button/button.d.ts +18 -0
  35. package/dist/components/button/button.js +23 -0
  36. package/dist/components/button/index.d.ts +59 -0
  37. package/dist/components/button/index.js +26 -0
  38. package/dist/components/card/card.astro +98 -0
  39. package/dist/components/card/card.css +91 -0
  40. package/dist/components/card/card.d.ts +19 -0
  41. package/dist/components/card/card.js +7 -0
  42. package/dist/components/card/index.d.ts +11 -0
  43. package/dist/components/card/index.js +7 -0
  44. package/dist/components/description-list/description-list.astro +39 -0
  45. package/dist/components/description-list/description-list.css +72 -0
  46. package/dist/components/description-list/description-list.d.ts +7 -0
  47. package/dist/components/description-list/description-list.js +6 -0
  48. package/dist/components/description-list/index.d.ts +12 -0
  49. package/dist/components/description-list/index.js +5 -0
  50. package/dist/components/divider/divider.astro +27 -0
  51. package/dist/components/divider/divider.css +40 -0
  52. package/dist/components/divider/divider.d.ts +5 -0
  53. package/dist/components/divider/divider.js +11 -0
  54. package/dist/components/divider/index.d.ts +22 -0
  55. package/dist/components/divider/index.js +11 -0
  56. package/dist/components/empty-state/empty-state.astro +47 -0
  57. package/dist/components/empty-state/empty-state.css +38 -0
  58. package/dist/components/empty-state/empty-state.d.ts +12 -0
  59. package/dist/components/empty-state/empty-state.js +7 -0
  60. package/dist/components/empty-state/index.d.ts +5 -0
  61. package/dist/components/empty-state/index.js +3 -0
  62. package/dist/components/field/checkbox-group.astro +58 -0
  63. package/dist/components/field/checkbox.astro +17 -0
  64. package/dist/components/field/field.astro +51 -0
  65. package/dist/components/field/field.css +336 -0
  66. package/dist/components/field/field.d.ts +47 -0
  67. package/dist/components/field/field.js +51 -0
  68. package/dist/components/field/index.d.ts +53 -0
  69. package/dist/components/field/index.js +54 -0
  70. package/dist/components/field/input.astro +27 -0
  71. package/dist/components/field/radio-group.astro +58 -0
  72. package/dist/components/field/radio.astro +17 -0
  73. package/dist/components/field/select.astro +13 -0
  74. package/dist/components/field/switch.astro +17 -0
  75. package/dist/components/field/textarea.astro +24 -0
  76. package/dist/components/filters/filter-layout.astro +72 -0
  77. package/dist/components/filters/filter-panel.astro +13 -0
  78. package/dist/components/filters/filters.css +230 -0
  79. package/dist/components/filters/filters.d.ts +20 -0
  80. package/dist/components/filters/filters.js +24 -0
  81. package/dist/components/filters/index.d.ts +27 -0
  82. package/dist/components/filters/index.js +25 -0
  83. package/dist/components/footer/footer.astro +70 -0
  84. package/dist/components/footer/footer.css +128 -0
  85. package/dist/components/footer/footer.d.ts +16 -0
  86. package/dist/components/footer/footer.js +7 -0
  87. package/dist/components/footer/index.d.ts +35 -0
  88. package/dist/components/footer/index.js +18 -0
  89. package/dist/components/header/header.astro +89 -0
  90. package/dist/components/header/header.css +163 -0
  91. package/dist/components/header/header.d.ts +18 -0
  92. package/dist/components/header/header.js +9 -0
  93. package/dist/components/header/index.d.ts +39 -0
  94. package/dist/components/header/index.js +25 -0
  95. package/dist/components/icon/icon.astro +21 -0
  96. package/dist/components/icon/icon.css +15 -0
  97. package/dist/components/icon/icon.d.ts +5 -0
  98. package/dist/components/icon/icon.js +6 -0
  99. package/dist/components/icon/index.d.ts +57 -0
  100. package/dist/components/icon/index.js +72 -0
  101. package/dist/components/layout/container.astro +15 -0
  102. package/dist/components/layout/grid.astro +14 -0
  103. package/dist/components/layout/index.d.ts +33 -0
  104. package/dist/components/layout/index.js +13 -0
  105. package/dist/components/layout/layout.css +262 -0
  106. package/dist/components/layout/layout.d.ts +24 -0
  107. package/dist/components/layout/layout.js +17 -0
  108. package/dist/components/layout/section-head.astro +42 -0
  109. package/dist/components/layout/section.astro +15 -0
  110. package/dist/components/page-head/index.d.ts +18 -0
  111. package/dist/components/page-head/index.js +14 -0
  112. package/dist/components/page-head/page-head.astro +60 -0
  113. package/dist/components/page-head/page-head.css +79 -0
  114. package/dist/components/page-head/page-head.d.ts +18 -0
  115. package/dist/components/page-head/page-head.js +8 -0
  116. package/dist/components/pagination/index.d.ts +73 -0
  117. package/dist/components/pagination/index.js +87 -0
  118. package/dist/components/pagination/pagination.astro +81 -0
  119. package/dist/components/pagination/pagination.css +70 -0
  120. package/dist/components/pagination/pagination.d.ts +8 -0
  121. package/dist/components/pagination/pagination.js +19 -0
  122. package/dist/components/panel/index.d.ts +11 -0
  123. package/dist/components/panel/index.js +3 -0
  124. package/dist/components/panel/panel.astro +15 -0
  125. package/dist/components/panel/panel.css +48 -0
  126. package/dist/components/panel/panel.d.ts +7 -0
  127. package/dist/components/panel/panel.js +6 -0
  128. package/dist/components/progress/index.d.ts +37 -0
  129. package/dist/components/progress/index.js +44 -0
  130. package/dist/components/progress/progress.astro +18 -0
  131. package/dist/components/progress/progress.css +115 -0
  132. package/dist/components/progress/progress.d.ts +5 -0
  133. package/dist/components/progress/progress.js +7 -0
  134. package/dist/components/prose/code-block.astro +26 -0
  135. package/dist/components/prose/index.d.ts +14 -0
  136. package/dist/components/prose/index.js +67 -0
  137. package/dist/components/prose/prose.astro +14 -0
  138. package/dist/components/prose/prose.css +156 -0
  139. package/dist/components/prose/prose.d.ts +12 -0
  140. package/dist/components/prose/prose.js +11 -0
  141. package/dist/components/stat/index.d.ts +15 -0
  142. package/dist/components/stat/index.js +5 -0
  143. package/dist/components/stat/stat-group.astro +11 -0
  144. package/dist/components/stat/stat.astro +43 -0
  145. package/dist/components/stat/stat.css +51 -0
  146. package/dist/components/stat/stat.d.ts +15 -0
  147. package/dist/components/stat/stat.js +10 -0
  148. package/dist/components/table/index.d.ts +38 -0
  149. package/dist/components/table/index.js +18 -0
  150. package/dist/components/table/table.astro +111 -0
  151. package/dist/components/table/table.css +78 -0
  152. package/dist/components/table/table.d.ts +11 -0
  153. package/dist/components/table/table.js +10 -0
  154. package/dist/components/tabs/index.d.ts +21 -0
  155. package/dist/components/tabs/index.js +13 -0
  156. package/dist/components/tabs/tabs.astro +30 -0
  157. package/dist/components/tabs/tabs.css +59 -0
  158. package/dist/components/tabs/tabs.d.ts +9 -0
  159. package/dist/components/tabs/tabs.js +6 -0
  160. package/dist/components/tag/index.d.ts +19 -0
  161. package/dist/components/tag/index.js +7 -0
  162. package/dist/components/tag/tag.astro +17 -0
  163. package/dist/components/tag/tag.css +30 -0
  164. package/dist/components/tag/tag.d.ts +9 -0
  165. package/dist/components/tag/tag.js +12 -0
  166. package/dist/components/timeline/index.d.ts +22 -0
  167. package/dist/components/timeline/index.js +5 -0
  168. package/dist/components/timeline/timeline.astro +40 -0
  169. package/dist/components/timeline/timeline.css +92 -0
  170. package/dist/components/timeline/timeline.d.ts +9 -0
  171. package/dist/components/timeline/timeline.js +7 -0
  172. package/dist/components/tooltip/index.d.ts +15 -0
  173. package/dist/components/tooltip/index.js +41 -0
  174. package/dist/components/tooltip/tooltip.astro +25 -0
  175. package/dist/components/tooltip/tooltip.css +84 -0
  176. package/dist/components/tooltip/tooltip.d.ts +12 -0
  177. package/dist/components/tooltip/tooltip.js +34 -0
  178. package/dist/config.d.ts +9 -0
  179. package/dist/config.js +6 -0
  180. package/dist/env.d.ts +2 -0
  181. package/dist/html.d.ts +37 -0
  182. package/dist/html.js +126 -0
  183. package/dist/parts.d.ts +27 -0
  184. package/dist/parts.js +28 -0
  185. package/dist/react.d.ts +27 -0
  186. package/dist/react.js +28 -0
  187. package/dist/scss/_chamfer.scss +37 -0
  188. package/dist/scss/_layers.scss +2 -0
  189. package/dist/scss/_theme.scss +15 -0
  190. package/dist/themes/eve-online.css +1945 -0
  191. package/dist/themes/xaroth.css +1974 -0
  192. package/dist/themes.css +3919 -0
  193. package/package.json +80 -0
@@ -0,0 +1,13 @@
1
+ import { clsx } from 'clsx';
2
+ import { bem } from "../../bem.js";
3
+ const container = bem('x-container', { defaults: { width: 'page' } });
4
+ const grid = bem('x-grid');
5
+ const section = bem('x-section');
6
+ const sectionHead = bem('x-section-head');
7
+ export const containerClass = ({ width = 'page', className } = {}) => container({ width }, className);
8
+ export const gridClass = ({ className } = {}) => grid({}, className);
9
+ // Grid children are plain elements, so spans are a class helper rather than a component.
10
+ export const colClass = ({ span, stack = 'md', className }) => clsx(`x-col-${span}`, stack === 'sm' && 'x-col--stack-sm', stack === 'never' && 'x-col--keep', className);
11
+ export const sectionClass = ({ tight, className } = {}) => section({ tight }, className);
12
+ export const sectionHeadClass = ({ className } = {}) => sectionHead({}, className);
13
+ export const sectionHeadTag = (level = 2) => `h${level}`;
@@ -0,0 +1,262 @@
1
+ @layer x.reset, x.core, x.theme, x.utility;
2
+ @layer x.core {
3
+ .x-container {
4
+ width: 100%;
5
+ max-width: calc(var(--x-page) + 2 * var(--x-gutter));
6
+ padding-inline: var(--x-gutter);
7
+ margin-inline: auto;
8
+ }
9
+ .x-container--prose {
10
+ max-width: calc(var(--x-prose) + 2 * var(--x-gutter));
11
+ }
12
+ .x-grid {
13
+ display: grid;
14
+ grid-template-columns: repeat(12, minmax(0, 1fr));
15
+ gap: var(--x-gap);
16
+ }
17
+ .x-col-1 {
18
+ grid-column: 1/-1;
19
+ min-width: 0;
20
+ }
21
+ .x-col-1.x-col--keep {
22
+ grid-column: span 1;
23
+ }
24
+ @media (min-width: 640px) {
25
+ .x-col-1.x-col--stack-sm {
26
+ grid-column: span 1;
27
+ }
28
+ }
29
+ @media (min-width: 1024px) {
30
+ .x-col-1 {
31
+ grid-column: span 1;
32
+ }
33
+ }
34
+ .x-col-2 {
35
+ grid-column: 1/-1;
36
+ min-width: 0;
37
+ }
38
+ .x-col-2.x-col--keep {
39
+ grid-column: span 2;
40
+ }
41
+ @media (min-width: 640px) {
42
+ .x-col-2.x-col--stack-sm {
43
+ grid-column: span 2;
44
+ }
45
+ }
46
+ @media (min-width: 1024px) {
47
+ .x-col-2 {
48
+ grid-column: span 2;
49
+ }
50
+ }
51
+ .x-col-3 {
52
+ grid-column: 1/-1;
53
+ min-width: 0;
54
+ }
55
+ .x-col-3.x-col--keep {
56
+ grid-column: span 3;
57
+ }
58
+ @media (min-width: 640px) {
59
+ .x-col-3.x-col--stack-sm {
60
+ grid-column: span 3;
61
+ }
62
+ }
63
+ @media (min-width: 1024px) {
64
+ .x-col-3 {
65
+ grid-column: span 3;
66
+ }
67
+ }
68
+ .x-col-4 {
69
+ grid-column: 1/-1;
70
+ min-width: 0;
71
+ }
72
+ .x-col-4.x-col--keep {
73
+ grid-column: span 4;
74
+ }
75
+ @media (min-width: 640px) {
76
+ .x-col-4.x-col--stack-sm {
77
+ grid-column: span 4;
78
+ }
79
+ }
80
+ @media (min-width: 1024px) {
81
+ .x-col-4 {
82
+ grid-column: span 4;
83
+ }
84
+ }
85
+ .x-col-5 {
86
+ grid-column: 1/-1;
87
+ min-width: 0;
88
+ }
89
+ .x-col-5.x-col--keep {
90
+ grid-column: span 5;
91
+ }
92
+ @media (min-width: 640px) {
93
+ .x-col-5.x-col--stack-sm {
94
+ grid-column: span 5;
95
+ }
96
+ }
97
+ @media (min-width: 1024px) {
98
+ .x-col-5 {
99
+ grid-column: span 5;
100
+ }
101
+ }
102
+ .x-col-6 {
103
+ grid-column: 1/-1;
104
+ min-width: 0;
105
+ }
106
+ .x-col-6.x-col--keep {
107
+ grid-column: span 6;
108
+ }
109
+ @media (min-width: 640px) {
110
+ .x-col-6.x-col--stack-sm {
111
+ grid-column: span 6;
112
+ }
113
+ }
114
+ @media (min-width: 1024px) {
115
+ .x-col-6 {
116
+ grid-column: span 6;
117
+ }
118
+ }
119
+ .x-col-7 {
120
+ grid-column: 1/-1;
121
+ min-width: 0;
122
+ }
123
+ .x-col-7.x-col--keep {
124
+ grid-column: span 7;
125
+ }
126
+ @media (min-width: 640px) {
127
+ .x-col-7.x-col--stack-sm {
128
+ grid-column: span 7;
129
+ }
130
+ }
131
+ @media (min-width: 1024px) {
132
+ .x-col-7 {
133
+ grid-column: span 7;
134
+ }
135
+ }
136
+ .x-col-8 {
137
+ grid-column: 1/-1;
138
+ min-width: 0;
139
+ }
140
+ .x-col-8.x-col--keep {
141
+ grid-column: span 8;
142
+ }
143
+ @media (min-width: 640px) {
144
+ .x-col-8.x-col--stack-sm {
145
+ grid-column: span 8;
146
+ }
147
+ }
148
+ @media (min-width: 1024px) {
149
+ .x-col-8 {
150
+ grid-column: span 8;
151
+ }
152
+ }
153
+ .x-col-9 {
154
+ grid-column: 1/-1;
155
+ min-width: 0;
156
+ }
157
+ .x-col-9.x-col--keep {
158
+ grid-column: span 9;
159
+ }
160
+ @media (min-width: 640px) {
161
+ .x-col-9.x-col--stack-sm {
162
+ grid-column: span 9;
163
+ }
164
+ }
165
+ @media (min-width: 1024px) {
166
+ .x-col-9 {
167
+ grid-column: span 9;
168
+ }
169
+ }
170
+ .x-col-10 {
171
+ grid-column: 1/-1;
172
+ min-width: 0;
173
+ }
174
+ .x-col-10.x-col--keep {
175
+ grid-column: span 10;
176
+ }
177
+ @media (min-width: 640px) {
178
+ .x-col-10.x-col--stack-sm {
179
+ grid-column: span 10;
180
+ }
181
+ }
182
+ @media (min-width: 1024px) {
183
+ .x-col-10 {
184
+ grid-column: span 10;
185
+ }
186
+ }
187
+ .x-col-11 {
188
+ grid-column: 1/-1;
189
+ min-width: 0;
190
+ }
191
+ .x-col-11.x-col--keep {
192
+ grid-column: span 11;
193
+ }
194
+ @media (min-width: 640px) {
195
+ .x-col-11.x-col--stack-sm {
196
+ grid-column: span 11;
197
+ }
198
+ }
199
+ @media (min-width: 1024px) {
200
+ .x-col-11 {
201
+ grid-column: span 11;
202
+ }
203
+ }
204
+ .x-col-12 {
205
+ grid-column: 1/-1;
206
+ min-width: 0;
207
+ }
208
+ .x-col-12.x-col--keep {
209
+ grid-column: span 12;
210
+ }
211
+ @media (min-width: 640px) {
212
+ .x-col-12.x-col--stack-sm {
213
+ grid-column: span 12;
214
+ }
215
+ }
216
+ @media (min-width: 1024px) {
217
+ .x-col-12 {
218
+ grid-column: span 12;
219
+ }
220
+ }
221
+ .x-section {
222
+ padding-block: var(--x-section);
223
+ }
224
+ .x-section + .x-section {
225
+ padding-top: 0;
226
+ }
227
+ .x-section--tight {
228
+ padding-block: calc(var(--x-section) / 2);
229
+ }
230
+ .x-section-head {
231
+ display: flex;
232
+ flex-wrap: wrap;
233
+ gap: var(--x-space-3) var(--x-space-5);
234
+ align-items: end;
235
+ justify-content: space-between;
236
+ margin-bottom: var(--x-space-7);
237
+ }
238
+ .x-section-head__titles {
239
+ display: grid;
240
+ gap: var(--x-space-2);
241
+ min-width: 0;
242
+ }
243
+ .x-section-head__eyebrow {
244
+ font-family: var(--x-font-display);
245
+ font-size: var(--x-fs-label);
246
+ font-weight: 600;
247
+ line-height: 1.3;
248
+ letter-spacing: var(--x-track-label);
249
+ text-transform: uppercase;
250
+ color: var(--x-color-accent);
251
+ }
252
+ .x-section-head__title {
253
+ font-size: var(--x-fs-h2);
254
+ }
255
+ .x-section-head__sub {
256
+ max-width: var(--x-prose);
257
+ color: var(--x-color-text-muted);
258
+ }
259
+ .x-section-head__link {
260
+ flex: none;
261
+ }
262
+ }
@@ -0,0 +1,24 @@
1
+ import './layout.scss';
2
+ import { type HTMLAttributes, type ReactNode } from 'react';
3
+ import { type ContainerOptions, type SectionHeadLevel, type SectionHeadLink, type SectionOptions } from './index.ts';
4
+ export type ContainerProps = HTMLAttributes<HTMLElement> & Omit<ContainerOptions, 'className'> & {
5
+ as?: 'div' | 'main' | 'header' | 'footer' | 'article' | 'nav';
6
+ };
7
+ export declare function Container({ width, as: Tag, className, ...rest }: ContainerProps): import("react").JSX.Element;
8
+ export type GridProps = HTMLAttributes<HTMLElement> & {
9
+ as?: 'div' | 'main' | 'section' | 'article' | 'ul' | 'ol';
10
+ };
11
+ export declare function Grid({ as: Tag, className, ...rest }: GridProps): import("react").JSX.Element;
12
+ export type SectionProps = HTMLAttributes<HTMLElement> & Omit<SectionOptions, 'className'> & {
13
+ as?: 'section' | 'div' | 'article' | 'aside';
14
+ };
15
+ export declare function Section({ tight, as: Tag, className, ...rest }: SectionProps): import("react").JSX.Element;
16
+ export type SectionHeadProps = Omit<HTMLAttributes<HTMLElement>, 'title'> & {
17
+ title: ReactNode;
18
+ eyebrow?: ReactNode;
19
+ sub?: ReactNode;
20
+ link?: SectionHeadLink;
21
+ level?: SectionHeadLevel;
22
+ titleId?: string;
23
+ };
24
+ export declare function SectionHead({ title, eyebrow, sub, link, level, titleId, className, ...rest }: SectionHeadProps): import("react").JSX.Element;
@@ -0,0 +1,17 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './layout.css';
3
+ import { createElement } from 'react';
4
+ import { Button } from "../button/button.js";
5
+ import { containerClass, gridClass, sectionClass, sectionHeadClass, sectionHeadTag, } from "./index.js";
6
+ export function Container({ width, as: Tag = 'div', className, ...rest }) {
7
+ return (_jsx(Tag, { ...rest, className: containerClass({ width, className }) }));
8
+ }
9
+ export function Grid({ as: Tag = 'div', className, ...rest }) {
10
+ return (_jsx(Tag, { ...rest, className: gridClass({ className }) }));
11
+ }
12
+ export function Section({ tight, as: Tag = 'section', className, ...rest }) {
13
+ return (_jsx(Tag, { ...rest, className: sectionClass({ tight, className }) }));
14
+ }
15
+ export function SectionHead({ title, eyebrow, sub, link, level, titleId, className, ...rest }) {
16
+ return (_jsxs("header", { ...rest, className: sectionHeadClass({ className }), children: [_jsxs("div", { className: "x-section-head__titles", children: [eyebrow != null && eyebrow !== '' && _jsx("p", { className: "x-section-head__eyebrow", children: eyebrow }), createElement(sectionHeadTag(level), { className: 'x-section-head__title', id: titleId }, title), sub != null && sub !== '' && _jsx("p", { className: "x-section-head__sub", children: sub })] }), link && (_jsx(Button, { className: "x-section-head__link", variant: "tertiary", size: "sm", href: link.href, end: _jsx("span", { "aria-hidden": "true", children: "\u2192" }), children: link.label }))] }));
17
+ }
@@ -0,0 +1,42 @@
1
+ ---
2
+ import './layout.css'
3
+ import type { HTMLAttributes } from 'astro/types'
4
+ import Button from '../button/button.astro'
5
+ import {
6
+ sectionHeadClass,
7
+ sectionHeadTag,
8
+ type SectionHeadLevel,
9
+ type SectionHeadLink,
10
+ } from './index.js'
11
+
12
+ type Props = Omit<HTMLAttributes<'header'>, 'class' | 'title'> & {
13
+ class?: string
14
+ title: string
15
+ eyebrow?: string
16
+ sub?: string
17
+ link?: SectionHeadLink
18
+ level?: SectionHeadLevel
19
+ titleId?: string
20
+ }
21
+
22
+ const { title, eyebrow, sub, link, level, titleId, class: className, slot: _slot, ...rest } = Astro.props
23
+ const Heading = sectionHeadTag(level)
24
+ ---
25
+
26
+ <header {...rest} class={sectionHeadClass({ className })}>
27
+ <div class="x-section-head__titles">
28
+ {eyebrow && <p class="x-section-head__eyebrow">{eyebrow}</p>}
29
+ <Heading class="x-section-head__title" id={titleId}>{title}</Heading>
30
+ {sub && <p class="x-section-head__sub">{sub}</p>}
31
+ </div>
32
+ {
33
+ link && (
34
+ <Button class="x-section-head__link" variant="tertiary" size="sm" href={link.href}>
35
+ {link.label}
36
+ <span slot="end" aria-hidden="true">
37
+ →
38
+ </span>
39
+ </Button>
40
+ )
41
+ }
42
+ </header>
@@ -0,0 +1,15 @@
1
+ ---
2
+ import './layout.css'
3
+ import type { HTMLAttributes } from 'astro/types'
4
+ import { sectionClass, type SectionOptions } from './index.js'
5
+
6
+ type Props = Omit<HTMLAttributes<'section'>, 'class'> &
7
+ Omit<SectionOptions, 'className'> & {
8
+ class?: string
9
+ as?: 'section' | 'div' | 'article' | 'aside'
10
+ }
11
+
12
+ const { tight, as: Tag = 'section', class: className, slot: _slot, ...rest } = Astro.props
13
+ ---
14
+
15
+ <Tag {...rest} class={sectionClass({ tight, className })}><slot /></Tag>
@@ -0,0 +1,18 @@
1
+ export type PageHeadAlign = 'start' | 'center';
2
+ export type PageHeadLevel = 1 | 2;
3
+ export type PageHeadOptions = {
4
+ align?: PageHeadAlign;
5
+ className?: string;
6
+ };
7
+ export declare const pageHeadClass: ({ align, className }?: PageHeadOptions) => string;
8
+ export declare const pageHeadClasses: {
9
+ readonly crumbs: string;
10
+ readonly body: string;
11
+ readonly titles: string;
12
+ readonly eyebrow: string;
13
+ readonly title: string;
14
+ readonly lead: string;
15
+ readonly meta: string;
16
+ readonly actions: string;
17
+ };
18
+ export declare const pageHeadTag: (level?: PageHeadLevel) => "h2" | "h1";
@@ -0,0 +1,14 @@
1
+ import { bem } from "../../bem.js";
2
+ const pageHead = bem('x-page-head', { defaults: { align: 'start' } });
3
+ export const pageHeadClass = ({ align = 'start', className } = {}) => pageHead({ align }, className);
4
+ export const pageHeadClasses = {
5
+ crumbs: pageHead.el('crumbs'),
6
+ body: pageHead.el('body'),
7
+ titles: pageHead.el('titles'),
8
+ eyebrow: pageHead.el('eyebrow'),
9
+ title: pageHead.el('title'),
10
+ lead: pageHead.el('lead'),
11
+ meta: pageHead.el('meta'),
12
+ actions: pageHead.el('actions'),
13
+ };
14
+ export const pageHeadTag = (level = 1) => `h${level}`;
@@ -0,0 +1,60 @@
1
+ ---
2
+ import './page-head.css'
3
+ import type { HTMLAttributes } from 'astro/types'
4
+ import { pageHeadClass, pageHeadClasses as c, pageHeadTag, type PageHeadAlign, type PageHeadLevel } from './index.js'
5
+
6
+ type Props = Omit<HTMLAttributes<'header'>, 'class' | 'title'> & {
7
+ class?: string
8
+ /** Plain-text title; the `title` slot takes markup. */
9
+ title?: string
10
+ eyebrow?: string
11
+ /** Plain-text lead; the `lead` slot takes markup. */
12
+ lead?: string
13
+ level?: PageHeadLevel
14
+ titleId?: string
15
+ align?: PageHeadAlign
16
+ }
17
+
18
+ const { title, eyebrow, lead, level, titleId, align, class: className, slot: _slot, ...rest } = Astro.props
19
+ const Heading = pageHeadTag(level)
20
+ const hasLead = (lead !== undefined && lead !== '') || Astro.slots.has('lead')
21
+ ---
22
+
23
+ <header class={pageHeadClass({ align, className })} {...rest}>
24
+ {
25
+ Astro.slots.has('breadcrumbs') && (
26
+ <div class={c.crumbs}>
27
+ <slot name="breadcrumbs" />
28
+ </div>
29
+ )
30
+ }
31
+ <div class={c.body}>
32
+ <div class={c.titles}>
33
+ {eyebrow && <p class={c.eyebrow}>{eyebrow}</p>}
34
+ <Heading class={c.title} id={titleId}>
35
+ <slot name="title">{title}</slot>
36
+ </Heading>
37
+ {
38
+ hasLead && (
39
+ <p class={c.lead}>
40
+ <slot name="lead">{lead}</slot>
41
+ </p>
42
+ )
43
+ }
44
+ {
45
+ Astro.slots.has('meta') && (
46
+ <div class={c.meta}>
47
+ <slot name="meta" />
48
+ </div>
49
+ )
50
+ }
51
+ </div>
52
+ {
53
+ Astro.slots.has('actions') && (
54
+ <div class={c.actions}>
55
+ <slot name="actions" />
56
+ </div>
57
+ )
58
+ }
59
+ </div>
60
+ </header>
@@ -0,0 +1,79 @@
1
+ @layer x.reset, x.core, x.theme, x.utility;
2
+ @layer x.core {
3
+ .x-page-head {
4
+ display: grid;
5
+ gap: var(--x-space-5);
6
+ margin-bottom: var(--x-space-7);
7
+ }
8
+ .x-page-head__crumbs {
9
+ display: flex;
10
+ min-width: 0;
11
+ }
12
+ .x-page-head__body {
13
+ display: flex;
14
+ flex-wrap: wrap;
15
+ gap: var(--x-space-5);
16
+ align-items: end;
17
+ justify-content: space-between;
18
+ }
19
+ .x-page-head__titles {
20
+ display: grid;
21
+ flex: 1 1 30rem;
22
+ gap: var(--x-space-3);
23
+ min-width: 0;
24
+ }
25
+ .x-page-head__eyebrow {
26
+ font-family: var(--x-font-display);
27
+ font-size: var(--x-fs-label);
28
+ font-weight: 600;
29
+ line-height: 1.3;
30
+ letter-spacing: var(--x-track-label);
31
+ text-transform: uppercase;
32
+ color: var(--x-color-accent);
33
+ }
34
+ .x-page-head__title {
35
+ font-family: var(--x-font-display);
36
+ font-size: var(--x-fs-h1);
37
+ line-height: 1.15;
38
+ }
39
+ .x-page-head__lead {
40
+ max-width: var(--x-prose);
41
+ font-size: var(--x-fs-lead);
42
+ line-height: 1.55;
43
+ color: var(--x-color-text-muted);
44
+ }
45
+ .x-page-head__meta {
46
+ display: flex;
47
+ flex-wrap: wrap;
48
+ gap: var(--x-space-2) var(--x-space-3);
49
+ align-items: center;
50
+ margin-top: var(--x-space-1);
51
+ font-size: var(--x-fs-small);
52
+ line-height: 1.5;
53
+ color: var(--x-color-text-muted);
54
+ }
55
+ .x-page-head__actions {
56
+ display: flex;
57
+ flex-wrap: wrap;
58
+ gap: var(--x-space-3);
59
+ align-items: center;
60
+ min-width: 0;
61
+ }
62
+ .x-page-head--center {
63
+ text-align: center;
64
+ }
65
+ .x-page-head--center .x-page-head__crumbs,
66
+ .x-page-head--center .x-page-head__meta,
67
+ .x-page-head--center .x-page-head__actions {
68
+ justify-content: center;
69
+ }
70
+ .x-page-head--center .x-page-head__body {
71
+ flex-direction: column;
72
+ align-items: center;
73
+ }
74
+ .x-page-head--center .x-page-head__titles {
75
+ flex: none;
76
+ justify-items: center;
77
+ width: 100%;
78
+ }
79
+ }
@@ -0,0 +1,18 @@
1
+ import './page-head.scss';
2
+ import { type HTMLAttributes, type ReactNode } from 'react';
3
+ import { type PageHeadAlign, type PageHeadLevel } from './index.ts';
4
+ export type PageHeadProps = Omit<HTMLAttributes<HTMLElement>, 'title'> & {
5
+ title: ReactNode;
6
+ /** Usually a Breadcrumbs part. */
7
+ breadcrumbs?: ReactNode;
8
+ eyebrow?: ReactNode;
9
+ lead?: ReactNode;
10
+ /** Badges, date, tags. */
11
+ meta?: ReactNode;
12
+ /** Buttons; right of the titles on wide screens, below them on narrow ones. */
13
+ actions?: ReactNode;
14
+ level?: PageHeadLevel;
15
+ titleId?: string;
16
+ align?: PageHeadAlign;
17
+ };
18
+ export declare function PageHead({ title, breadcrumbs, eyebrow, lead, meta, actions, level, titleId, align, className, ...rest }: PageHeadProps): import("react").JSX.Element;
@@ -0,0 +1,8 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import './page-head.css';
3
+ import { createElement } from 'react';
4
+ import { pageHeadClass, pageHeadClasses as c, pageHeadTag } from "./index.js";
5
+ const has = (node) => node != null && node !== '' && node !== false;
6
+ export function PageHead({ title, breadcrumbs, eyebrow, lead, meta, actions, level, titleId, align, className, ...rest }) {
7
+ return (_jsxs("header", { ...rest, className: pageHeadClass({ align, className }), children: [has(breadcrumbs) && _jsx("div", { className: c.crumbs, children: breadcrumbs }), _jsxs("div", { className: c.body, children: [_jsxs("div", { className: c.titles, children: [has(eyebrow) && _jsx("p", { className: c.eyebrow, children: eyebrow }), createElement(pageHeadTag(level), { className: c.title, id: titleId }, title), has(lead) && _jsx("p", { className: c.lead, children: lead }), has(meta) && _jsx("div", { className: c.meta, children: meta })] }), has(actions) && _jsx("div", { className: c.actions, children: actions })] })] }));
8
+ }
@@ -0,0 +1,73 @@
1
+ export type PaginationHref = string | ((page: number) => string);
2
+ export type PaginationAlign = 'center' | 'start';
3
+ export type PaginationOptions = {
4
+ align?: PaginationAlign;
5
+ className?: string;
6
+ };
7
+ export type PaginationInput = {
8
+ page: number;
9
+ pages: number;
10
+ href: PaginationHref;
11
+ /** URL of page 1 when it differs from the pattern, for example '/blog'. */
12
+ firstHref?: string;
13
+ /** Pages shown on each side of the current one. */
14
+ siblings?: number;
15
+ /** Adds First and Last links. */
16
+ ends?: boolean;
17
+ prevLabel?: string;
18
+ nextLabel?: string;
19
+ firstLabel?: string;
20
+ lastLabel?: string;
21
+ /** Screen reader text of the compact summary shown on narrow screens. {page} and {pages} are replaced. */
22
+ summaryLabel?: string;
23
+ };
24
+ type Edge = 'first' | 'prev' | 'next' | 'last';
25
+ export type PaginationEntry = {
26
+ kind: 'page';
27
+ key: string;
28
+ label: string;
29
+ href: string;
30
+ current: boolean;
31
+ } | {
32
+ kind: 'gap';
33
+ key: string;
34
+ } | {
35
+ kind: 'edge';
36
+ key: Edge;
37
+ label: string;
38
+ href?: string;
39
+ rel?: 'prev' | 'next';
40
+ } | {
41
+ kind: 'summary';
42
+ key: 'summary';
43
+ text: string;
44
+ label: string;
45
+ };
46
+ export declare const paginationClass: ({ align, className }?: PaginationOptions) => string;
47
+ export declare const paginationClasses: {
48
+ readonly list: string;
49
+ readonly item: string;
50
+ readonly itemPage: string;
51
+ readonly itemEnd: string;
52
+ readonly itemSummary: string;
53
+ readonly summary: string;
54
+ readonly link: string;
55
+ readonly edge: string;
56
+ readonly disabled: string;
57
+ readonly gap: string;
58
+ };
59
+ export declare const paginationHref: (href: PaginationHref, page: number, firstHref?: string) => string;
60
+ export declare const paginationClamp: (page: number, pages: number) => {
61
+ page: number;
62
+ pages: number;
63
+ };
64
+ export declare const paginationPages: (requested: number, total: number, siblings?: number) => (number | "gap")[];
65
+ export declare const paginationEntries: ({ href, firstHref, siblings, ends, prevLabel, nextLabel, firstLabel, lastLabel, summaryLabel, ...input }: PaginationInput) => PaginationEntry[];
66
+ export declare const paginationItemClass: (entry: PaginationEntry) => string;
67
+ export declare const paginationPageAttrs: (entry: Extract<PaginationEntry, {
68
+ kind: "page";
69
+ }>) => {
70
+ href: string;
71
+ 'aria-current': "page" | undefined;
72
+ };
73
+ export {};