@pienter/ui 0.9.0 → 0.10.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
|
@@ -2,6 +2,30 @@
|
|
|
2
2
|
|
|
3
3
|
## Unreleased
|
|
4
4
|
|
|
5
|
+
## 0.10.0 - 2026-09-15
|
|
6
|
+
|
|
7
|
+
### Changed
|
|
8
|
+
|
|
9
|
+
- Index renders its title, description and actions through the new
|
|
10
|
+
`PageHeader`, so the `pui-index__header`, `pui-index__heading`,
|
|
11
|
+
`pui-index__title`, `pui-index__description` and `pui-index__actions`
|
|
12
|
+
classes are gone. They were never documented as public API; a consumer
|
|
13
|
+
style that targeted them moves to `pui-page-header` and its
|
|
14
|
+
`__heading`, `__title`, `__description` and `__actions` elements. Markup,
|
|
15
|
+
spacing and type are unchanged in both placements.
|
|
16
|
+
|
|
17
|
+
### Added
|
|
18
|
+
|
|
19
|
+
- `PageHeader` at `@pienter/ui/components/PageHeader.vue`: the title,
|
|
20
|
+
description and actions band above a module index or a record page,
|
|
21
|
+
extracted from Index so detail and form pages no longer hand-roll the same
|
|
22
|
+
header. `title` and `description` are plain strings, `level` (`1` | `2` |
|
|
23
|
+
`3`, default `1`) picks the heading element and sizes levels 2 and 3 as
|
|
24
|
+
section headings, `title-id` sets the title's `id` for `aria-labelledby`,
|
|
25
|
+
and `#actions` fills the trailing row. It renders nothing when it has no
|
|
26
|
+
title, description or actions. Index uses it at level 1 in module placement
|
|
27
|
+
and level 2 in related placement.
|
|
28
|
+
|
|
5
29
|
## 0.9.0 - 2026-09-15
|
|
6
30
|
|
|
7
31
|
### Added
|
|
@@ -4,26 +4,16 @@
|
|
|
4
4
|
:data-placement="placement"
|
|
5
5
|
:data-state="loading ? 'loading' : undefined"
|
|
6
6
|
>
|
|
7
|
-
<
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
<PageHeader
|
|
8
|
+
:title="title"
|
|
9
|
+
:description="description"
|
|
10
|
+
:level="placement === 'related' ? 2 : 1"
|
|
11
|
+
:title-id="titleId"
|
|
10
12
|
>
|
|
11
|
-
<
|
|
12
|
-
<component
|
|
13
|
-
:is="placement === 'related' ? 'h2' : 'h1'"
|
|
14
|
-
v-if="title"
|
|
15
|
-
:id="titleId"
|
|
16
|
-
class="pui-index__title"
|
|
17
|
-
>{{ title }}</component
|
|
18
|
-
>
|
|
19
|
-
<p v-if="description" class="pui-index__description">
|
|
20
|
-
{{ description }}
|
|
21
|
-
</p>
|
|
22
|
-
</div>
|
|
23
|
-
<div v-if="$slots.actions" class="pui-index__actions">
|
|
13
|
+
<template v-if="$slots.actions" #actions>
|
|
24
14
|
<slot name="actions" :reload="reload" :loading="loading" />
|
|
25
|
-
</
|
|
26
|
-
</
|
|
15
|
+
</template>
|
|
16
|
+
</PageHeader>
|
|
27
17
|
|
|
28
18
|
<div class="pui-index__body">
|
|
29
19
|
<div
|
|
@@ -172,6 +162,7 @@
|
|
|
172
162
|
<script setup lang="ts" generic="T extends object">
|
|
173
163
|
import { computed, watch } from 'vue';
|
|
174
164
|
import DataTable from '../table/DataTable.vue';
|
|
165
|
+
import PageHeader from '../page-header/PageHeader.vue';
|
|
175
166
|
import type { Column } from '../table/types.js';
|
|
176
167
|
import TextInput from '../../form/text-input/TextInput.vue';
|
|
177
168
|
import Select from '../../form/select/Select.vue';
|
|
@@ -6,37 +6,6 @@
|
|
|
6
6
|
color: var(--text-clr-base);
|
|
7
7
|
}
|
|
8
8
|
|
|
9
|
-
.pui-index__header {
|
|
10
|
-
display: grid;
|
|
11
|
-
grid-template-columns: minmax(0, 1fr) auto;
|
|
12
|
-
align-items: center;
|
|
13
|
-
justify-content: space-between;
|
|
14
|
-
gap: var(--space-s);
|
|
15
|
-
padding-block-end: var(--space-s);
|
|
16
|
-
border-block-end: var(--stroke-sm) solid var(--border-clr-subtle);
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
.pui-index__heading {
|
|
20
|
-
display: grid;
|
|
21
|
-
gap: var(--space-3xs);
|
|
22
|
-
min-inline-size: 0;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
.pui-index__title {
|
|
26
|
-
margin: 0;
|
|
27
|
-
font-family: var(--ff-display);
|
|
28
|
-
font-size: var(--step-2);
|
|
29
|
-
font-weight: var(--fw-display);
|
|
30
|
-
letter-spacing: var(--ls-display);
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
.pui-index__description {
|
|
34
|
-
margin: 0;
|
|
35
|
-
font-size: var(--step--1);
|
|
36
|
-
color: var(--text-clr-muted);
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
.pui-index__actions,
|
|
40
9
|
.pui-index__selection {
|
|
41
10
|
display: flex;
|
|
42
11
|
flex-wrap: wrap;
|
|
@@ -123,16 +92,10 @@
|
|
|
123
92
|
border: var(--stroke-sm) solid var(--border-clr-subtle);
|
|
124
93
|
border-radius: var(--radius-md);
|
|
125
94
|
|
|
126
|
-
& > .pui-
|
|
95
|
+
& > .pui-page-header {
|
|
127
96
|
padding: var(--space-s);
|
|
128
97
|
}
|
|
129
98
|
|
|
130
|
-
& .pui-index__title {
|
|
131
|
-
font-size: var(--step-1);
|
|
132
|
-
font-weight: var(--fw-semibold);
|
|
133
|
-
letter-spacing: normal;
|
|
134
|
-
}
|
|
135
|
-
|
|
136
99
|
& .pui-index__toolbar {
|
|
137
100
|
padding: var(--space-s);
|
|
138
101
|
border-block-end: var(--stroke-sm) solid var(--border-clr-subtle);
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<header
|
|
3
|
+
v-if="title || description || $slots.actions"
|
|
4
|
+
class="pui-page-header"
|
|
5
|
+
>
|
|
6
|
+
<div v-if="title || description" class="pui-page-header__heading">
|
|
7
|
+
<component
|
|
8
|
+
:is="`h${level}`"
|
|
9
|
+
v-if="title"
|
|
10
|
+
:id="titleId"
|
|
11
|
+
class="pui-page-header__title"
|
|
12
|
+
>{{ title }}</component
|
|
13
|
+
>
|
|
14
|
+
<p v-if="description" class="pui-page-header__description">
|
|
15
|
+
{{ description }}
|
|
16
|
+
</p>
|
|
17
|
+
</div>
|
|
18
|
+
<div v-if="$slots.actions" class="pui-page-header__actions">
|
|
19
|
+
<slot name="actions" />
|
|
20
|
+
</div>
|
|
21
|
+
</header>
|
|
22
|
+
</template>
|
|
23
|
+
|
|
24
|
+
<script setup lang="ts">
|
|
25
|
+
withDefaults(
|
|
26
|
+
defineProps<{
|
|
27
|
+
title?: string;
|
|
28
|
+
description?: string;
|
|
29
|
+
/** Heading level of the title: `1` for a page, `2` or `3` for a band inside one. */
|
|
30
|
+
level?: 1 | 2 | 3;
|
|
31
|
+
/** `id` for the title element, so a region can reference it through `aria-labelledby`. */
|
|
32
|
+
titleId?: string;
|
|
33
|
+
}>(),
|
|
34
|
+
{
|
|
35
|
+
title: undefined,
|
|
36
|
+
description: undefined,
|
|
37
|
+
level: 1,
|
|
38
|
+
titleId: undefined,
|
|
39
|
+
},
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
defineSlots<{
|
|
43
|
+
actions?: () => unknown;
|
|
44
|
+
}>();
|
|
45
|
+
</script>
|
|
46
|
+
|
|
47
|
+
<style>
|
|
48
|
+
@import './page-header.css';
|
|
49
|
+
</style>
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
@layer components {
|
|
2
|
+
.pui-page-header {
|
|
3
|
+
display: grid;
|
|
4
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: space-between;
|
|
7
|
+
gap: var(--space-s);
|
|
8
|
+
padding-block-end: var(--space-s);
|
|
9
|
+
border-block-end: var(--stroke-sm) solid var(--border-clr-subtle);
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
.pui-page-header__heading {
|
|
13
|
+
display: grid;
|
|
14
|
+
gap: var(--space-3xs);
|
|
15
|
+
min-inline-size: 0;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
.pui-page-header__title {
|
|
19
|
+
margin: 0;
|
|
20
|
+
font-family: var(--ff-display);
|
|
21
|
+
font-size: var(--step-2);
|
|
22
|
+
font-weight: var(--fw-display);
|
|
23
|
+
letter-spacing: var(--ls-display);
|
|
24
|
+
|
|
25
|
+
&:is(h2, h3) {
|
|
26
|
+
font-size: var(--step-1);
|
|
27
|
+
font-weight: var(--fw-semibold);
|
|
28
|
+
letter-spacing: normal;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
.pui-page-header__description {
|
|
33
|
+
margin: 0;
|
|
34
|
+
font-size: var(--step--1);
|
|
35
|
+
color: var(--text-clr-muted);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
.pui-page-header__actions {
|
|
39
|
+
display: flex;
|
|
40
|
+
flex-wrap: wrap;
|
|
41
|
+
align-items: center;
|
|
42
|
+
gap: var(--space-xs);
|
|
43
|
+
}
|
|
44
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pienter/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"description": "Shared Pienter UI components, styles, icons, and browser utilities.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|
|
@@ -63,6 +63,7 @@
|
|
|
63
63
|
"./components/Card.vue": "./components/layout/card/Card.vue",
|
|
64
64
|
"./components/Collapsible.vue": "./components/layout/collapsible/Collapsible.vue",
|
|
65
65
|
"./components/AppLayout.vue": "./components/layout/app-layout/AppLayout.vue",
|
|
66
|
+
"./components/PageHeader.vue": "./components/layout/page-header/PageHeader.vue",
|
|
66
67
|
"./components/Separator.vue": "./components/layout/separator/Separator.vue",
|
|
67
68
|
"./components/Table.vue": "./components/layout/table/Table.vue",
|
|
68
69
|
"./components/TableRow.vue": "./components/layout/table/TableRow.vue",
|