@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.
Files changed (40) hide show
  1. package/README.md +15 -27
  2. package/package.json +3 -1
  3. package/src/components/actions/MediaTrigger/MediaTrigger.astro +12 -4
  4. package/src/components/actions/MediaTrigger/MediaTrigger.css +1 -0
  5. package/src/components/content/MarkdownContent/MarkdownContent.css +0 -1
  6. package/src/components/content/MarkdownContent/MarkdownNode.astro +1 -0
  7. package/src/components/forms/Checkbox/Checkbox.astro +60 -0
  8. package/src/components/forms/Checkbox/Checkbox.css +126 -0
  9. package/src/components/forms/FieldGroup/FieldGroup.astro +34 -0
  10. package/src/components/forms/FieldGroup/FieldGroup.css +30 -0
  11. package/src/components/icons/CheckIcon.astro +22 -0
  12. package/src/components/index.ts +2 -0
  13. package/src/components/navigation/Breadcrumbs/Breadcrumbs.astro +2 -1
  14. package/src/components/navigation/SubNavigation/SubNavigation.astro +2 -1
  15. package/src/composition/Grid/Grid.astro +9 -0
  16. package/src/composition/Grid/Grid.css +52 -0
  17. package/src/composition/GridItem/GridItem.astro +9 -0
  18. package/src/composition/GridItem/GridItem.css +12 -0
  19. package/src/display/contracts.ts +1 -0
  20. package/src/display/index.ts +1 -0
  21. package/src/display/responsiveMedia.ts +38 -0
  22. package/src/i18n/LocalePreferenceBootstrap.astro +40 -0
  23. package/src/i18n/catalog.ts +203 -0
  24. package/src/i18n/config.ts +112 -0
  25. package/src/i18n/coreMessages.ts +37 -0
  26. package/src/i18n/formatters.ts +34 -0
  27. package/src/i18n/index.ts +6 -0
  28. package/src/i18n/preference.ts +58 -0
  29. package/src/index.ts +2 -0
  30. package/src/patterns/Combobox/comboboxController.ts +72 -0
  31. package/src/patterns/Table/Table.css +2 -1
  32. package/src/patterns/Table/TableBody.astro +3 -1
  33. package/src/patterns/Table/TableBody.css +6 -0
  34. package/src/patterns/Table/tableFilterController.ts +60 -2
  35. package/src/patterns/Table/tableLayout.ts +10 -3
  36. package/src/routing/index.ts +1 -0
  37. package/src/routing/localized.ts +155 -0
  38. package/src/seo/index.ts +1 -0
  39. package/src/seo/localizedMeta.ts +58 -0
  40. 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 the shared Astro foundation used by AstroNox sites. It owns
4
- reusable components, composition primitives, interaction patterns, display
5
- contracts, SEO helpers, and the complete default stylesheet.
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 stylesheet:
36
+ Load the shared visual system once from the consuming application's root
37
+ layout:
37
38
 
38
- ```css
39
- @import '@astronox/core/styles.css';
40
- @import './site-theme.css';
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
- ## Local Development
48
-
49
- `astronox-core` is the only source of truth. A consuming project may link this
50
- package locally while developing a shared change, but committed dependencies
51
- must always reference a released package version.
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.0",
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 Props = Omit<HTMLAttributes<'button'>, '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
- <button
33
+ <Root
27
34
  {...attrs}
28
35
  class:list={['media-trigger', className]}
29
- type="button"
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
- </button>
63
+ </Root>
@@ -12,6 +12,7 @@
12
12
  background: transparent;
13
13
  color: inherit;
14
14
  font: inherit;
15
+ text-decoration: none;
15
16
  cursor: pointer;
16
17
  isolation: isolate;
17
18
  }
@@ -211,7 +211,6 @@
211
211
  .markdown-content__change-label {
212
212
  min-width: 0;
213
213
  flex: none;
214
- font-weight: var(--nox-font-weight-medium);
215
214
  overflow-wrap: anywhere;
216
215
  }
217
216
 
@@ -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>
@@ -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 = "Fil d'Ariane",
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 = 'Navigation de section',
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%;
@@ -242,6 +242,7 @@ export type TableCell = {
242
242
 
243
243
  export type TableRow = {
244
244
  key?: string;
245
+ disabled?: boolean;
245
246
  href?: string;
246
247
  hidden?: boolean;
247
248
  filters?: Readonly<Record<string, readonly string[]>>;
@@ -1 +1,2 @@
1
1
  export * from './contracts';
2
+ export * from './responsiveMedia';