@astronox/core 0.1.0 → 0.2.1
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 +15 -27
- package/package.json +3 -1
- package/src/components/actions/MediaTrigger/MediaTrigger.astro +12 -4
- package/src/components/actions/MediaTrigger/MediaTrigger.css +1 -0
- package/src/components/content/MarkdownContent/MarkdownContent.css +0 -1
- package/src/components/content/MarkdownContent/MarkdownNode.astro +1 -0
- package/src/components/forms/Checkbox/Checkbox.astro +60 -0
- package/src/components/forms/Checkbox/Checkbox.css +126 -0
- package/src/components/forms/FieldGroup/FieldGroup.astro +34 -0
- package/src/components/forms/FieldGroup/FieldGroup.css +30 -0
- package/src/components/icons/CheckIcon.astro +22 -0
- package/src/components/index.ts +2 -0
- package/src/components/navigation/Breadcrumbs/Breadcrumbs.astro +2 -1
- package/src/components/navigation/SubNavigation/SubNavigation.astro +2 -1
- package/src/composition/Grid/Grid.astro +9 -0
- package/src/composition/Grid/Grid.css +52 -0
- package/src/composition/GridItem/GridItem.astro +9 -0
- package/src/composition/GridItem/GridItem.css +12 -0
- package/src/display/contracts.ts +1 -0
- package/src/display/index.ts +1 -0
- package/src/display/responsiveMedia.ts +38 -0
- package/src/i18n/LocalePreferenceBootstrap.astro +40 -0
- package/src/i18n/catalog.ts +203 -0
- package/src/i18n/config.ts +112 -0
- package/src/i18n/coreMessages.ts +37 -0
- package/src/i18n/formatters.ts +34 -0
- package/src/i18n/index.ts +6 -0
- package/src/i18n/preference.ts +58 -0
- package/src/index.ts +2 -0
- package/src/patterns/Combobox/comboboxController.ts +72 -0
- package/src/patterns/Table/Table.css +2 -1
- package/src/patterns/Table/TableBody.astro +3 -1
- package/src/patterns/Table/TableBody.css +6 -0
- package/src/patterns/Table/tableFilterController.ts +60 -2
- package/src/patterns/Table/tableLayout.ts +10 -3
- package/src/routing/index.ts +1 -0
- package/src/routing/localized.ts +155 -0
- package/src/seo/index.ts +1 -0
- package/src/seo/localizedMeta.ts +58 -0
- package/src/styles/style.css +2 -0
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# AstroNox Core
|
|
2
2
|
|
|
3
|
-
AstroNox Core is
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
AstroNox Core is a reusable foundation for Astro applications. It provides
|
|
4
|
+
components, composition primitives, interaction patterns, display contracts,
|
|
5
|
+
internationalization and SEO infrastructure, and a complete shared stylesheet.
|
|
6
6
|
|
|
7
7
|
Product data, product routes, branding, integrations, and business rules stay
|
|
8
8
|
in the consuming site.
|
|
@@ -33,34 +33,22 @@ import { Stack, SurfaceGroup } from '@astronox/core/composition';
|
|
|
33
33
|
</Stack>
|
|
34
34
|
```
|
|
35
35
|
|
|
36
|
-
Load the shared visual system once from the consuming application's
|
|
36
|
+
Load the shared visual system once from the consuming application's root
|
|
37
|
+
layout:
|
|
37
38
|
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
```astro
|
|
40
|
+
---
|
|
41
|
+
import '@astronox/core/styles.css';
|
|
42
|
+
---
|
|
41
43
|
```
|
|
42
44
|
|
|
43
45
|
Use the remaining entry points for layouts, patterns, primitives, display
|
|
44
46
|
contracts, configuration, theme, client behavior, data validation, and SEO.
|
|
45
47
|
Deep imports into the physical `src` tree are not part of the public API.
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
`
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
The expected workflow is:
|
|
54
|
-
|
|
55
|
-
1. Implement and commit the generic change in this repository.
|
|
56
|
-
2. Validate it from the relevant linked consumer.
|
|
57
|
-
3. Publish a prerelease or stable package version.
|
|
58
|
-
4. Update consumers through their dependency management workflow.
|
|
59
|
-
|
|
60
|
-
Do not edit installed package files or copy `src` folders between projects.
|
|
61
|
-
|
|
62
|
-
## Releases
|
|
63
|
-
|
|
64
|
-
AstroNox Core follows semantic versioning. Public entry points are compatibility
|
|
65
|
-
boundaries; internal files may change without notice. The initial `0.x` series
|
|
66
|
-
is reserved for stabilizing the API with the first production consumers.
|
|
49
|
+
Locale catalogs, localized routing, preference persistence, localized metadata,
|
|
50
|
+
and responsive media presentation are available through the `i18n`, `routing`,
|
|
51
|
+
`seo`, and `display` entry points. Consuming sites provide their own locale
|
|
52
|
+
definitions, translations, route names, product metadata, and assets. Generic
|
|
53
|
+
component labels can extend `defaultCoreMessages` through
|
|
54
|
+
`resolveCoreMessages()` while retaining the English fallback.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@astronox/core",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"description": "Reusable Astro components, patterns, styles, and infrastructure for AstroNox sites.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -35,9 +35,11 @@
|
|
|
35
35
|
"./config": "./src/config/index.ts",
|
|
36
36
|
"./data": "./src/data/index.ts",
|
|
37
37
|
"./display": "./src/display/index.ts",
|
|
38
|
+
"./i18n": "./src/i18n/index.ts",
|
|
38
39
|
"./layouts": "./src/layouts/index.ts",
|
|
39
40
|
"./patterns": "./src/patterns/index.ts",
|
|
40
41
|
"./primitives": "./src/primitives/index.ts",
|
|
42
|
+
"./routing": "./src/routing/index.ts",
|
|
41
43
|
"./seo": "./src/seo/index.ts",
|
|
42
44
|
"./theme": "./src/theme/index.ts",
|
|
43
45
|
"./styles.css": "./src/styles/style.css",
|
|
@@ -4,29 +4,37 @@ import type { DisplayMedia } from '../../../display/contracts';
|
|
|
4
4
|
import type { Tone } from '../../../theme/contracts';
|
|
5
5
|
import Media from '../../../primitives/media/Media/Media.astro';
|
|
6
6
|
|
|
7
|
-
type
|
|
7
|
+
type SharedProps = {
|
|
8
8
|
accentTone?: Tone;
|
|
9
9
|
label: string;
|
|
10
10
|
media: DisplayMedia;
|
|
11
11
|
tone?: Tone;
|
|
12
12
|
};
|
|
13
13
|
|
|
14
|
+
type Props = SharedProps &
|
|
15
|
+
Omit<HTMLAttributes<'a'>, 'href' | 'type'> & {
|
|
16
|
+
href?: string;
|
|
17
|
+
};
|
|
18
|
+
|
|
14
19
|
const {
|
|
15
20
|
accentTone,
|
|
16
21
|
class: className,
|
|
17
22
|
'data-tone': dataTone,
|
|
23
|
+
href,
|
|
18
24
|
label,
|
|
19
25
|
media,
|
|
20
26
|
tone,
|
|
21
27
|
...attrs
|
|
22
28
|
}: Props = Astro.props;
|
|
23
29
|
const resolvedTone = tone ?? dataTone;
|
|
30
|
+
const Root = href ? 'a' : 'button';
|
|
24
31
|
---
|
|
25
32
|
|
|
26
|
-
<
|
|
33
|
+
<Root
|
|
27
34
|
{...attrs}
|
|
28
35
|
class:list={['media-trigger', className]}
|
|
29
|
-
|
|
36
|
+
href={href}
|
|
37
|
+
type={href ? undefined : 'button'}
|
|
30
38
|
aria-label={label}
|
|
31
39
|
data-tone={resolvedTone}
|
|
32
40
|
data-widget="media-trigger"
|
|
@@ -52,4 +60,4 @@ const resolvedTone = tone ?? dataTone;
|
|
|
52
60
|
</span>
|
|
53
61
|
) : null
|
|
54
62
|
}
|
|
55
|
-
</
|
|
63
|
+
</Root>
|
|
@@ -112,6 +112,7 @@ const listItems =
|
|
|
112
112
|
<div class="markdown-content__change">
|
|
113
113
|
<span class="markdown-content__change-label">
|
|
114
114
|
{node.label.map((child) => <MarkdownInline node={child} />)}
|
|
115
|
+
<span>:</span>
|
|
115
116
|
</span>
|
|
116
117
|
{node.presentation === 'statement' ? (
|
|
117
118
|
<span class="markdown-content__change-values">
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
+
import type { Tone } from '../../../theme/contracts';
|
|
4
|
+
import CheckIcon from '../../icons/CheckIcon.astro';
|
|
5
|
+
import CloseIcon from '../../icons/CloseIcon.astro';
|
|
6
|
+
|
|
7
|
+
type Props = Omit<HTMLAttributes<'input'>, 'class' | 'id' | 'type'> & {
|
|
8
|
+
id: string;
|
|
9
|
+
label: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
invalid?: boolean;
|
|
12
|
+
tone?: Tone;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const {
|
|
16
|
+
'aria-invalid': ariaInvalid,
|
|
17
|
+
class: className,
|
|
18
|
+
'data-tone': dataTone,
|
|
19
|
+
disabled = false,
|
|
20
|
+
id,
|
|
21
|
+
invalid = false,
|
|
22
|
+
label,
|
|
23
|
+
tone,
|
|
24
|
+
...attrs
|
|
25
|
+
}: Props = Astro.props;
|
|
26
|
+
const resolvedInvalid =
|
|
27
|
+
invalid || ariaInvalid === true || ariaInvalid === 'true';
|
|
28
|
+
const resolvedTone = tone ?? dataTone;
|
|
29
|
+
---
|
|
30
|
+
|
|
31
|
+
<label
|
|
32
|
+
class:list={['checkbox-field', className]}
|
|
33
|
+
for={id}
|
|
34
|
+
data-disabled={disabled ? true : undefined}
|
|
35
|
+
data-invalid={resolvedInvalid ? true : undefined}
|
|
36
|
+
data-tone={resolvedTone}
|
|
37
|
+
data-widget="checkbox"
|
|
38
|
+
>
|
|
39
|
+
<input
|
|
40
|
+
{...attrs}
|
|
41
|
+
id={id}
|
|
42
|
+
class="checkbox"
|
|
43
|
+
type="checkbox"
|
|
44
|
+
disabled={disabled}
|
|
45
|
+
aria-invalid={resolvedInvalid ? 'true' : ariaInvalid}
|
|
46
|
+
/>
|
|
47
|
+
<span class="checkbox__label">
|
|
48
|
+
<span class="checkbox__label-text">{label}</span>
|
|
49
|
+
<span class="checkbox__state" aria-hidden="true">
|
|
50
|
+
<CheckIcon
|
|
51
|
+
class="checkbox__icon checkbox__icon--checked"
|
|
52
|
+
data-tone="success"
|
|
53
|
+
/>
|
|
54
|
+
<CloseIcon
|
|
55
|
+
class="checkbox__icon checkbox__icon--unchecked"
|
|
56
|
+
data-tone="danger"
|
|
57
|
+
/>
|
|
58
|
+
</span>
|
|
59
|
+
</span>
|
|
60
|
+
</label>
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
.checkbox-field {
|
|
2
|
+
position: relative;
|
|
3
|
+
display: grid;
|
|
4
|
+
box-sizing: border-box;
|
|
5
|
+
min-inline-size: 0;
|
|
6
|
+
inline-size: 100%;
|
|
7
|
+
block-size: var(--nox-field-control-block-size);
|
|
8
|
+
place-items: center;
|
|
9
|
+
padding: var(--nox-space-2);
|
|
10
|
+
overflow: clip;
|
|
11
|
+
border: var(--nox-border-width) solid var(--nox-field-border);
|
|
12
|
+
border-radius: var(--nox-radius-sm);
|
|
13
|
+
background: var(--nox-field-background-disabled);
|
|
14
|
+
color: var(--nox-text-disabled);
|
|
15
|
+
cursor: pointer;
|
|
16
|
+
transition:
|
|
17
|
+
border-color var(--nox-motion-duration-sm) var(--nox-motion-easing-standard),
|
|
18
|
+
box-shadow var(--nox-motion-duration-sm) var(--nox-motion-easing-standard),
|
|
19
|
+
background-color var(--nox-motion-duration-sm)
|
|
20
|
+
var(--nox-motion-easing-standard),
|
|
21
|
+
color var(--nox-motion-duration-sm) var(--nox-motion-easing-standard);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
.checkbox {
|
|
25
|
+
position: absolute;
|
|
26
|
+
z-index: 1;
|
|
27
|
+
inset: 0;
|
|
28
|
+
inline-size: 100%;
|
|
29
|
+
block-size: 100%;
|
|
30
|
+
margin: 0;
|
|
31
|
+
opacity: 0;
|
|
32
|
+
cursor: pointer;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
.checkbox__label {
|
|
36
|
+
display: inline-grid;
|
|
37
|
+
min-inline-size: 0;
|
|
38
|
+
max-inline-size: 100%;
|
|
39
|
+
grid-template-columns: 0.75rem minmax(0, auto) 0.75rem;
|
|
40
|
+
align-items: center;
|
|
41
|
+
gap: var(--nox-space-1);
|
|
42
|
+
color: inherit;
|
|
43
|
+
font-size: var(--nox-font-size-xs);
|
|
44
|
+
font-weight: var(--nox-font-weight-strong);
|
|
45
|
+
letter-spacing: var(--nox-letter-spacing-wide);
|
|
46
|
+
line-height: 1;
|
|
47
|
+
overflow-wrap: anywhere;
|
|
48
|
+
text-align: center;
|
|
49
|
+
text-transform: uppercase;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
.checkbox__label::before {
|
|
53
|
+
content: '';
|
|
54
|
+
inline-size: 0.75rem;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
.checkbox__label-text {
|
|
58
|
+
min-inline-size: 0;
|
|
59
|
+
overflow: hidden;
|
|
60
|
+
text-overflow: ellipsis;
|
|
61
|
+
white-space: nowrap;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.checkbox__state {
|
|
65
|
+
display: grid;
|
|
66
|
+
inline-size: 0.75rem;
|
|
67
|
+
block-size: 0.75rem;
|
|
68
|
+
place-items: center;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.checkbox__icon {
|
|
72
|
+
grid-area: 1 / 1;
|
|
73
|
+
inline-size: 100%;
|
|
74
|
+
block-size: 100%;
|
|
75
|
+
transition: opacity var(--nox-motion-duration-sm)
|
|
76
|
+
var(--nox-motion-easing-standard);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.checkbox__icon--checked {
|
|
80
|
+
color: var(--nox-tone-color);
|
|
81
|
+
opacity: 0;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
.checkbox__icon--unchecked {
|
|
85
|
+
color: var(--nox-text-disabled);
|
|
86
|
+
opacity: 1;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
.checkbox-field:has(.checkbox:checked) {
|
|
90
|
+
background: var(--nox-field-background);
|
|
91
|
+
color: var(--nox-tone-text);
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.checkbox:checked ~ .checkbox__label .checkbox__icon--checked {
|
|
95
|
+
opacity: 1;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
.checkbox:checked ~ .checkbox__label .checkbox__icon--unchecked {
|
|
99
|
+
opacity: 0;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
.checkbox-field:has(.checkbox:focus-visible) {
|
|
103
|
+
border-color: var(--nox-field-border-active);
|
|
104
|
+
box-shadow: var(--nox-field-focus-shadow);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.checkbox-field[data-invalid] {
|
|
108
|
+
border-color: var(--nox-field-border-invalid);
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
.checkbox-field[data-disabled] {
|
|
112
|
+
border-color: var(--nox-field-border);
|
|
113
|
+
background: var(--nox-field-background-disabled);
|
|
114
|
+
color: var(--nox-text-disabled);
|
|
115
|
+
cursor: not-allowed;
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.checkbox-field[data-disabled] .checkbox {
|
|
119
|
+
cursor: not-allowed;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
@media (hover: hover) and (pointer: fine) {
|
|
123
|
+
.checkbox-field:not([data-disabled]):hover {
|
|
124
|
+
border-color: var(--nox-field-border-hover);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
+
import type { Tone } from '../../../theme/contracts';
|
|
4
|
+
|
|
5
|
+
type Props = Omit<HTMLAttributes<'fieldset'>, 'disabled'> & {
|
|
6
|
+
label: string;
|
|
7
|
+
disabled?: boolean;
|
|
8
|
+
tone?: Tone;
|
|
9
|
+
};
|
|
10
|
+
|
|
11
|
+
const {
|
|
12
|
+
class: className,
|
|
13
|
+
'data-tone': dataTone,
|
|
14
|
+
disabled = false,
|
|
15
|
+
label,
|
|
16
|
+
tone,
|
|
17
|
+
...attrs
|
|
18
|
+
}: Props = Astro.props;
|
|
19
|
+
const resolvedTone = tone ?? dataTone;
|
|
20
|
+
---
|
|
21
|
+
|
|
22
|
+
<fieldset
|
|
23
|
+
{...attrs}
|
|
24
|
+
class:list={['field-group', className]}
|
|
25
|
+
disabled={disabled}
|
|
26
|
+
data-disabled={disabled ? true : undefined}
|
|
27
|
+
data-tone={resolvedTone}
|
|
28
|
+
data-widget="field-group"
|
|
29
|
+
>
|
|
30
|
+
<legend class="field-group__label">{label}</legend>
|
|
31
|
+
<div class="field-group__content">
|
|
32
|
+
<slot />
|
|
33
|
+
</div>
|
|
34
|
+
</fieldset>
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
.field-group {
|
|
2
|
+
min-inline-size: 0;
|
|
3
|
+
margin: 0;
|
|
4
|
+
padding: 0;
|
|
5
|
+
border: 0;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
.field-group__label {
|
|
9
|
+
display: inline-flex;
|
|
10
|
+
min-inline-size: 0;
|
|
11
|
+
margin: 0;
|
|
12
|
+
padding: 0;
|
|
13
|
+
align-items: center;
|
|
14
|
+
color: var(--nox-tone-text);
|
|
15
|
+
font-size: var(--nox-font-size-sm);
|
|
16
|
+
font-weight: var(--nox-font-weight-strong);
|
|
17
|
+
letter-spacing: var(--nox-letter-spacing-wide);
|
|
18
|
+
line-height: 1.25;
|
|
19
|
+
overflow-wrap: anywhere;
|
|
20
|
+
text-transform: uppercase;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
.field-group__content {
|
|
24
|
+
min-inline-size: 0;
|
|
25
|
+
margin-block-start: var(--nox-space-2);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.field-group[data-disabled] .field-group__label {
|
|
29
|
+
color: var(--nox-text-disabled);
|
|
30
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
---
|
|
2
|
+
import type { HTMLAttributes } from 'astro/types';
|
|
3
|
+
|
|
4
|
+
type Props = HTMLAttributes<'svg'>;
|
|
5
|
+
|
|
6
|
+
const attrs: Props = Astro.props;
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
<svg
|
|
10
|
+
{...attrs}
|
|
11
|
+
viewBox="0 0 32 32"
|
|
12
|
+
fill="none"
|
|
13
|
+
aria-hidden="true"
|
|
14
|
+
focusable="false"
|
|
15
|
+
>
|
|
16
|
+
<path
|
|
17
|
+
d="M7 16.5L13 22.5L25 9.5"
|
|
18
|
+
stroke="currentColor"
|
|
19
|
+
stroke-width="2.5"
|
|
20
|
+
stroke-linecap="round"
|
|
21
|
+
stroke-linejoin="round"></path>
|
|
22
|
+
</svg>
|
package/src/components/index.ts
CHANGED
|
@@ -15,7 +15,9 @@ export { default as IconList } from './data-display/IconList/IconList.astro';
|
|
|
15
15
|
export { default as MetricTile } from './data-display/MetricTile/MetricTile.astro';
|
|
16
16
|
export { default as Tag } from './data-display/Tag/Tag.astro';
|
|
17
17
|
export { default as TextPair } from './data-display/TextPair/TextPair.astro';
|
|
18
|
+
export { default as Checkbox } from './forms/Checkbox/Checkbox.astro';
|
|
18
19
|
export { default as FieldError } from './forms/FieldError/FieldError.astro';
|
|
20
|
+
export { default as FieldGroup } from './forms/FieldGroup/FieldGroup.astro';
|
|
19
21
|
export { default as FieldLabel } from './forms/FieldLabel/FieldLabel.astro';
|
|
20
22
|
export { default as TextInput } from './forms/TextInput/TextInput.astro';
|
|
21
23
|
export { default as Spinner } from './feedback/Spinner/Spinner.astro';
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { HTMLAttributes } from 'astro/types';
|
|
3
3
|
import type { BreadcrumbItem } from '../../../display/contracts';
|
|
4
4
|
import type { Tone } from '../../../theme/contracts';
|
|
5
|
+
import { defaultCoreMessages } from '../../../i18n/coreMessages';
|
|
5
6
|
|
|
6
7
|
type Props = HTMLAttributes<'nav'> & {
|
|
7
8
|
items: readonly BreadcrumbItem[];
|
|
@@ -13,7 +14,7 @@ const {
|
|
|
13
14
|
class: className,
|
|
14
15
|
'data-tone': dataTone,
|
|
15
16
|
items,
|
|
16
|
-
label =
|
|
17
|
+
label = defaultCoreMessages.navigation.breadcrumbs,
|
|
17
18
|
tone,
|
|
18
19
|
...attrs
|
|
19
20
|
} = Astro.props;
|
|
@@ -3,6 +3,7 @@ import type { HTMLAttributes } from 'astro/types';
|
|
|
3
3
|
import type { Tone } from '../../../theme/contracts';
|
|
4
4
|
import type { SubNavigationItem } from '../navigationTypes';
|
|
5
5
|
import Media from '../../../primitives/media/Media/Media.astro';
|
|
6
|
+
import { defaultCoreMessages } from '../../../i18n/coreMessages';
|
|
6
7
|
|
|
7
8
|
type Props = HTMLAttributes<'nav'> & {
|
|
8
9
|
items: readonly SubNavigationItem[];
|
|
@@ -14,7 +15,7 @@ const {
|
|
|
14
15
|
class: className,
|
|
15
16
|
'data-tone': dataTone,
|
|
16
17
|
items,
|
|
17
|
-
label =
|
|
18
|
+
label = defaultCoreMessages.navigation.section,
|
|
18
19
|
tone,
|
|
19
20
|
...attrs
|
|
20
21
|
} = Astro.props;
|
|
@@ -3,6 +3,7 @@ import type { HTMLAttributes } from 'astro/types';
|
|
|
3
3
|
|
|
4
4
|
type GridGap = 'none' | 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
5
5
|
type GridColumns = 1 | 2 | 3 | 4 | 'content-sidebar';
|
|
6
|
+
type GridFlow = 'row' | 'column';
|
|
6
7
|
type GridRows = 1 | 2 | 3 | 4;
|
|
7
8
|
type GridItemAlignment = 'start' | 'center' | 'end' | 'stretch';
|
|
8
9
|
type GridCollapseAt = 'none' | 'sm' | 'md' | 'lg' | 'xl';
|
|
@@ -14,8 +15,10 @@ type Props = Omit<HTMLAttributes<'div'>, 'class' | 'style'> & {
|
|
|
14
15
|
collapseAt?: GridCollapseAt;
|
|
15
16
|
class?: string;
|
|
16
17
|
compactColumns?: 1 | 2 | 3 | 4;
|
|
18
|
+
compactFlow?: GridFlow;
|
|
17
19
|
gap?: GridGap;
|
|
18
20
|
columns?: GridColumns;
|
|
21
|
+
flow?: GridFlow;
|
|
19
22
|
justifyItems?: GridItemAlignment;
|
|
20
23
|
lastRow?: GridLastRow;
|
|
21
24
|
minTrackWidth?: string;
|
|
@@ -28,8 +31,10 @@ const {
|
|
|
28
31
|
collapseAt = 'md',
|
|
29
32
|
class: className,
|
|
30
33
|
compactColumns,
|
|
34
|
+
compactFlow,
|
|
31
35
|
gap = 'md',
|
|
32
36
|
columns,
|
|
37
|
+
flow = 'row',
|
|
33
38
|
justifyItems = 'stretch',
|
|
34
39
|
lastRow = 'preserve',
|
|
35
40
|
minTrackWidth = '16rem',
|
|
@@ -52,6 +57,8 @@ const gridVariables = {
|
|
|
52
57
|
...(compactColumns
|
|
53
58
|
? { '--grid-compact-columns': String(compactColumns) }
|
|
54
59
|
: {}),
|
|
60
|
+
'--grid-compact-flow': compactFlow ?? flow,
|
|
61
|
+
'--grid-flow': flow,
|
|
55
62
|
...(rows ? { '--grid-rows': String(rows) } : {}),
|
|
56
63
|
'--grid-align-items': alignItems,
|
|
57
64
|
'--grid-justify-items': justifyItems,
|
|
@@ -69,7 +76,9 @@ const gridStyle = Object.entries(gridVariables)
|
|
|
69
76
|
data-align-items={alignItems}
|
|
70
77
|
data-collapse-at={collapseMode}
|
|
71
78
|
data-compact-columns={compactColumns}
|
|
79
|
+
data-compact-flow={compactFlow}
|
|
72
80
|
data-columns={typeof columns === 'number' ? columns : undefined}
|
|
81
|
+
data-flow={flow}
|
|
73
82
|
data-gap={gap}
|
|
74
83
|
data-justify-items={justifyItems}
|
|
75
84
|
data-layout={layout}
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
min-width: 0;
|
|
9
9
|
align-items: var(--grid-align-items);
|
|
10
10
|
gap: var(--grid-gap);
|
|
11
|
+
grid-auto-flow: var(--grid-flow);
|
|
11
12
|
justify-items: var(--grid-justify-items);
|
|
12
13
|
}
|
|
13
14
|
|
|
@@ -300,7 +301,58 @@
|
|
|
300
301
|
|
|
301
302
|
@container (width < 24rem) {
|
|
302
303
|
.grid[data-compact-columns] {
|
|
304
|
+
grid-auto-flow: var(--grid-compact-flow);
|
|
303
305
|
grid-template-columns: repeat(var(--grid-compact-columns), minmax(0, 1fr));
|
|
306
|
+
grid-template-rows: none;
|
|
307
|
+
}
|
|
308
|
+
|
|
309
|
+
.grid[data-compact-columns]
|
|
310
|
+
> [data-composition='grid-item'][data-compact-span='1'] {
|
|
311
|
+
grid-column: span 1;
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
.grid[data-compact-columns]
|
|
315
|
+
> [data-composition='grid-item'][data-compact-span='2'] {
|
|
316
|
+
grid-column: span 2;
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
.grid[data-compact-columns]
|
|
320
|
+
> [data-composition='grid-item'][data-compact-span='3'] {
|
|
321
|
+
grid-column: span 3;
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
.grid[data-compact-columns]
|
|
325
|
+
> [data-composition='grid-item'][data-compact-span='4'] {
|
|
326
|
+
grid-column: span 4;
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
.grid[data-compact-columns]
|
|
330
|
+
> [data-composition='grid-item'][data-compact-row-span='1'] {
|
|
331
|
+
grid-row: span 1;
|
|
332
|
+
}
|
|
333
|
+
|
|
334
|
+
.grid[data-compact-columns]
|
|
335
|
+
> [data-composition='grid-item'][data-compact-row-span='2'] {
|
|
336
|
+
grid-row: span 2;
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
.grid[data-compact-columns]
|
|
340
|
+
> [data-composition='grid-item'][data-compact-row-span='3'] {
|
|
341
|
+
grid-row: span 3;
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
.grid[data-compact-columns]
|
|
345
|
+
> [data-composition='grid-item'][data-compact-row-span='4'] {
|
|
346
|
+
grid-row: span 4;
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
.grid[data-compact-columns]
|
|
350
|
+
> [data-composition='grid-item'][data-sizing='fill-track'] {
|
|
351
|
+
--grid-item-fill-track-contain: none;
|
|
352
|
+
--grid-item-fill-track-content-block-size: auto;
|
|
353
|
+
--grid-item-fill-track-content-inset: auto;
|
|
354
|
+
--grid-item-fill-track-content-position: static;
|
|
355
|
+
--grid-item-fill-track-overflow: visible;
|
|
304
356
|
}
|
|
305
357
|
|
|
306
358
|
.grid[data-last-row='fill'][data-compact-columns] > * {
|
|
@@ -14,8 +14,11 @@ type Props = Omit<GridItemAttributes, 'class' | 'style'> & {
|
|
|
14
14
|
alignSelf?: GridItemAlignment;
|
|
15
15
|
class?: string;
|
|
16
16
|
collapseOrder?: GridItemCollapseOrder;
|
|
17
|
+
compactRowSpan?: GridItemSpan;
|
|
18
|
+
compactSpan?: GridItemSpan;
|
|
17
19
|
justifySelf?: GridItemAlignment;
|
|
18
20
|
position?: GridItemPosition;
|
|
21
|
+
rowSpan?: GridItemSpan;
|
|
19
22
|
sizing?: GridItemSizing;
|
|
20
23
|
span?: GridItemSpan;
|
|
21
24
|
};
|
|
@@ -25,8 +28,11 @@ const {
|
|
|
25
28
|
alignSelf = 'auto',
|
|
26
29
|
class: className,
|
|
27
30
|
collapseOrder = 'preserve',
|
|
31
|
+
compactRowSpan,
|
|
32
|
+
compactSpan,
|
|
28
33
|
justifySelf = 'auto',
|
|
29
34
|
position = 'static',
|
|
35
|
+
rowSpan = 1,
|
|
30
36
|
sizing = 'auto',
|
|
31
37
|
span = 1,
|
|
32
38
|
...attrs
|
|
@@ -39,8 +45,11 @@ const {
|
|
|
39
45
|
data-composition="grid-item"
|
|
40
46
|
data-align-self={alignSelf}
|
|
41
47
|
data-collapse-order={collapseOrder}
|
|
48
|
+
data-compact-row-span={compactRowSpan}
|
|
49
|
+
data-compact-span={compactSpan}
|
|
42
50
|
data-justify-self={justifySelf}
|
|
43
51
|
data-position={position}
|
|
52
|
+
data-row-span={rowSpan}
|
|
44
53
|
data-sizing={sizing}
|
|
45
54
|
data-span={span}
|
|
46
55
|
>
|
|
@@ -69,6 +69,18 @@
|
|
|
69
69
|
grid-column: span 4;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
+
.grid-item[data-row-span='2'] {
|
|
73
|
+
grid-row: span 2;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
.grid-item[data-row-span='3'] {
|
|
77
|
+
grid-row: span 3;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
.grid-item[data-row-span='4'] {
|
|
81
|
+
grid-row: span 4;
|
|
82
|
+
}
|
|
83
|
+
|
|
72
84
|
.grid-item[data-sizing='fill-track'] {
|
|
73
85
|
--grid-item-fill-track-contain: size layout;
|
|
74
86
|
--grid-item-fill-track-content-block-size: 100%;
|
package/src/display/contracts.ts
CHANGED
package/src/display/index.ts
CHANGED