@iyulab/modern-app 0.36.0 → 0.37.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 +13 -0
- package/dist/components/MasterDetailLayout.js +1 -1
- package/dist/components/Timeline.d.ts +63 -0
- package/dist/components/Timeline.js +68 -0
- package/dist/components/Timeline.styles.d.ts +2 -0
- package/dist/components/Timeline.styles.js +125 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +7 -6
- package/dist/layouts/SidebarLayout.js +1 -1
- package/dist/react/Timeline.d.ts +14 -0
- package/dist/react/Timeline.js +10 -0
- package/dist/react/index.d.ts +1 -0
- package/dist/react/index.js +1 -0
- package/dist/react.d.ts +9 -0
- package/package.json +1 -1
- package/skills/modern-app/SKILL.md +1 -0
- package/skills/modern-app/references/components/timeline.md +57 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## [0.37.0] - 2026-10-06
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- **`u-timeline` and `u-timeline-item` — a status or activity history** for detail screens ("what
|
|
8
|
+
happened, and when"). Each entry is a marker on a rail, a `heading`, a `datetime` rendered as
|
|
9
|
+
`<time datetime>` and formatted for the active locale (a date alone as that calendar day, a
|
|
10
|
+
date-time with its time; the `time` slot replaces the text), and an optional body. `color` takes the
|
|
11
|
+
role colours of `u-tag`/`u-badge` — the marker is drawn with the role's fill, the colour on it and its
|
|
12
|
+
strong step as an edge, so a warning marker still shows on the page — and `icon` draws inside it. The
|
|
13
|
+
list is announced as a list. Parts: `rail` · `marker` · `line` · `content` · `header` · `heading` ·
|
|
14
|
+
`time` · `body`; knobs `--app-timeline-rail-width` and `--app-timeline-marker-size`.
|
|
15
|
+
|
|
3
16
|
## [0.36.0] - 2026-10-06
|
|
4
17
|
|
|
5
18
|
### Added
|
|
@@ -6,8 +6,8 @@ import { slotHasContent as i } from "../internals/slotted.js";
|
|
|
6
6
|
import { styles as a } from "./MasterDetailLayout.styles.js";
|
|
7
7
|
import { html as o } from "lit";
|
|
8
8
|
import { customElement as s, property as c, state as l } from "lit/decorators.js";
|
|
9
|
-
import "@iyulab/components/dist/components/button/UButton.js";
|
|
10
9
|
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
10
|
+
import "@iyulab/components/dist/components/button/UButton.js";
|
|
11
11
|
//#region src/components/MasterDetailLayout.ts
|
|
12
12
|
var u = class extends n {
|
|
13
13
|
constructor(...e) {
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { StyledElement } from '../internals/StyledElement.js';
|
|
2
|
+
type TimelineParts = 'host';
|
|
3
|
+
type TimelineItemParts = 'host' | 'rail' | 'marker' | 'line' | 'content' | 'header' | 'heading' | 'time' | 'body';
|
|
4
|
+
/** The role colours `u-tag`/`u-badge` use — the marker's colour. */
|
|
5
|
+
export type TimelineItemColor = 'neutral' | 'primary' | 'info' | 'success' | 'warning' | 'danger';
|
|
6
|
+
/**
|
|
7
|
+
* A status or activity history — "what happened, and when" on a detail screen (order, ticket,
|
|
8
|
+
* approval). An ordered list of {@link TimelineItem}s, each a marker on a rail, a heading, a time
|
|
9
|
+
* and an optional body.
|
|
10
|
+
*
|
|
11
|
+
* ```html
|
|
12
|
+
* <u-timeline>
|
|
13
|
+
* <u-timeline-item heading="Paid" datetime="2026-10-06T09:30" color="success" icon="check">
|
|
14
|
+
* Bank transfer received.
|
|
15
|
+
* </u-timeline-item>
|
|
16
|
+
* <u-timeline-item heading="Ordered" datetime="2026-10-05T14:02"></u-timeline-item>
|
|
17
|
+
* </u-timeline>
|
|
18
|
+
* ```
|
|
19
|
+
*
|
|
20
|
+
* The items are shown in DOM order — put the newest first or last as your screen reads. The host is
|
|
21
|
+
* a list and each item a list item, so assistive technology announces how many entries there are.
|
|
22
|
+
*/
|
|
23
|
+
export declare class Timeline extends StyledElement<TimelineParts> {
|
|
24
|
+
static styles: import('lit').CSSResultGroup[];
|
|
25
|
+
connectedCallback(): void;
|
|
26
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* One entry of a {@link Timeline}.
|
|
30
|
+
*
|
|
31
|
+
* - `heading` names the event ("Shipped"); the `heading` slot takes richer content.
|
|
32
|
+
* - `datetime` is an ISO date or date-time. It is rendered as `<time datetime>` and formatted for the
|
|
33
|
+
* active locale (`Locale`) — a date alone as a date, a date-time with its time. The `time` slot
|
|
34
|
+
* replaces the text (a relative "2 hours ago", say); `datetime` still annotates it.
|
|
35
|
+
* - `color` tints the marker. ⚠Colour is never the only carrier — say the status in `heading` too
|
|
36
|
+
* (WCAG 1.4.1). `icon` (and `lib`) draws inside the marker.
|
|
37
|
+
*/
|
|
38
|
+
export declare class TimelineItem extends StyledElement<TimelineItemParts> {
|
|
39
|
+
static styles: import('lit').CSSResultGroup[];
|
|
40
|
+
/** What happened. */
|
|
41
|
+
heading: string;
|
|
42
|
+
/** When — ISO `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm[:ss]`. */
|
|
43
|
+
datetime: string;
|
|
44
|
+
/** Marker colour. Default `neutral`. */
|
|
45
|
+
color: TimelineItemColor;
|
|
46
|
+
/** Icon drawn inside the marker. */
|
|
47
|
+
icon?: string;
|
|
48
|
+
/** Icon library for `icon`. */
|
|
49
|
+
lib?: string;
|
|
50
|
+
/** Body slot assignment — CSS `:has()` cannot see slotted content (`internals/slotted.ts`). */
|
|
51
|
+
private hasBody;
|
|
52
|
+
connectedCallback(): void;
|
|
53
|
+
/** Locale text for `datetime` — the raw value when it is not a date the formatter can read. */
|
|
54
|
+
private get timeText();
|
|
55
|
+
render(): import('lit-html').TemplateResult<1>;
|
|
56
|
+
}
|
|
57
|
+
declare global {
|
|
58
|
+
interface HTMLElementTagNameMap {
|
|
59
|
+
'u-timeline': Timeline;
|
|
60
|
+
'u-timeline-item': TimelineItem;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
export {};
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import e from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js";
|
|
2
|
+
import t from "../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorate.js";
|
|
3
|
+
import { StyledElement as n } from "../internals/StyledElement.js";
|
|
4
|
+
import { slotHasContent as r } from "../internals/slotted.js";
|
|
5
|
+
import { itemStyles as i, styles as a } from "./Timeline.styles.js";
|
|
6
|
+
import { html as o, nothing as s } from "lit";
|
|
7
|
+
import { customElement as c, property as l, state as u } from "lit/decorators.js";
|
|
8
|
+
import { formatDate as d } from "@iyulab/components/dist/utilities/format.js";
|
|
9
|
+
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
10
|
+
//#region src/components/Timeline.ts
|
|
11
|
+
var f = class extends n {
|
|
12
|
+
static {
|
|
13
|
+
this.styles = [super.styles, a];
|
|
14
|
+
}
|
|
15
|
+
connectedCallback() {
|
|
16
|
+
super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "list");
|
|
17
|
+
}
|
|
18
|
+
render() {
|
|
19
|
+
return o`<slot></slot>`;
|
|
20
|
+
}
|
|
21
|
+
};
|
|
22
|
+
f = t([c("u-timeline")], f);
|
|
23
|
+
var p = class extends n {
|
|
24
|
+
constructor(...e) {
|
|
25
|
+
super(...e), this.heading = "", this.datetime = "", this.color = "neutral", this.hasBody = !1;
|
|
26
|
+
}
|
|
27
|
+
static {
|
|
28
|
+
this.styles = [super.styles, i];
|
|
29
|
+
}
|
|
30
|
+
connectedCallback() {
|
|
31
|
+
super.connectedCallback(), this.hasAttribute("role") || this.setAttribute("role", "listitem");
|
|
32
|
+
}
|
|
33
|
+
get timeText() {
|
|
34
|
+
let e = this.datetime.trim();
|
|
35
|
+
if (!e) return "";
|
|
36
|
+
if (!e.includes("T")) return d(e, { dateStyle: "medium" });
|
|
37
|
+
let t = new Date(e);
|
|
38
|
+
return Number.isNaN(t.getTime()) ? e : d(t, {
|
|
39
|
+
dateStyle: "medium",
|
|
40
|
+
timeStyle: "short"
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
render() {
|
|
44
|
+
return o`
|
|
45
|
+
<div class="rail" part="rail" aria-hidden="true">
|
|
46
|
+
<span class="marker ${this.icon ? "with-icon" : ""}" part="marker">
|
|
47
|
+
${this.icon ? o`<u-icon .lib=${this.lib} .name=${this.icon}></u-icon>` : s}
|
|
48
|
+
</span>
|
|
49
|
+
<span class="line" part="line"></span>
|
|
50
|
+
</div>
|
|
51
|
+
<div class="content" part="content">
|
|
52
|
+
<div class="header" part="header">
|
|
53
|
+
<span class="heading" part="heading"><slot name="heading">${this.heading}</slot></span>
|
|
54
|
+
${this.datetime ? o`<time class="time" part="time" datetime=${this.datetime}><slot name="time">${this.timeText}</slot></time>` : o`<span class="time" part="time"><slot name="time"></slot></span>`}
|
|
55
|
+
</div>
|
|
56
|
+
<div class="body ${this.hasBody ? "" : "empty"}" part="body">
|
|
57
|
+
<slot @slotchange=${(e) => this.hasBody = r(e.target)}></slot>
|
|
58
|
+
</div>
|
|
59
|
+
</div>
|
|
60
|
+
`;
|
|
61
|
+
}
|
|
62
|
+
};
|
|
63
|
+
t([l({ type: String }), e("design:type", Object)], p.prototype, "heading", void 0), t([l({ type: String }), e("design:type", Object)], p.prototype, "datetime", void 0), t([l({
|
|
64
|
+
type: String,
|
|
65
|
+
reflect: !0
|
|
66
|
+
}), e("design:type", Object)], p.prototype, "color", void 0), t([l({ type: String }), e("design:type", String)], p.prototype, "icon", void 0), t([l({ type: String }), e("design:type", String)], p.prototype, "lib", void 0), t([u(), e("design:type", Object)], p.prototype, "hasBody", void 0), p = t([c("u-timeline-item")], p);
|
|
67
|
+
//#endregion
|
|
68
|
+
export { f as Timeline, p as TimelineItem };
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import { css as e } from "lit";
|
|
2
|
+
//#region src/components/Timeline.styles.ts
|
|
3
|
+
var t = e`
|
|
4
|
+
:host {
|
|
5
|
+
display: block;
|
|
6
|
+
}
|
|
7
|
+
`, n = e`
|
|
8
|
+
:host {
|
|
9
|
+
display: grid;
|
|
10
|
+
grid-template-columns: var(--app-timeline-rail-width, 24px) minmax(0, 1fr);
|
|
11
|
+
column-gap: var(--u-space-md, 12px);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
/* The rail: a marker, then a line down to the next entry's marker. */
|
|
15
|
+
.rail {
|
|
16
|
+
display: flex;
|
|
17
|
+
flex-direction: column;
|
|
18
|
+
align-items: center;
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
.marker {
|
|
22
|
+
flex: none;
|
|
23
|
+
display: inline-flex;
|
|
24
|
+
align-items: center;
|
|
25
|
+
justify-content: center;
|
|
26
|
+
box-sizing: border-box;
|
|
27
|
+
width: var(--app-timeline-marker-size, 12px);
|
|
28
|
+
height: var(--app-timeline-marker-size, 12px);
|
|
29
|
+
/* Centred on the heading's first line (label size × leading). */
|
|
30
|
+
margin-top: calc((var(--u-text-label-size, 13px) * var(--u-text-label-leading, 1.5) - var(--app-timeline-marker-size, 12px)) / 2);
|
|
31
|
+
border-radius: 50%;
|
|
32
|
+
/* Fill and the colour on it come as a pair (the components contract — warning carries dark text,
|
|
33
|
+
not white). The edge is the strong step: a yellow fill alone is about 1.4:1 against the page. */
|
|
34
|
+
background-color: var(--_marker, var(--u-border-color-strong, #BDBDBD));
|
|
35
|
+
color: var(--_on-marker, var(--u-txt-color, #212121));
|
|
36
|
+
border: 1px solid var(--_edge, var(--u-border-color-strong, #BDBDBD));
|
|
37
|
+
}
|
|
38
|
+
.marker.with-icon {
|
|
39
|
+
width: var(--app-timeline-rail-width, 24px);
|
|
40
|
+
height: var(--app-timeline-rail-width, 24px);
|
|
41
|
+
margin-top: calc((var(--u-text-label-size, 13px) * var(--u-text-label-leading, 1.5) - var(--app-timeline-rail-width, 24px)) / 2);
|
|
42
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
:host([color="primary"]) {
|
|
46
|
+
--_marker: var(--u-primary-color, #1976D2);
|
|
47
|
+
--_on-marker: var(--u-primary-txt-color, #FFFFFF);
|
|
48
|
+
--_edge: var(--u-primary-color-strong, #1565C0);
|
|
49
|
+
}
|
|
50
|
+
:host([color="info"]) {
|
|
51
|
+
--_marker: var(--u-info-color, #1976D2);
|
|
52
|
+
--_on-marker: var(--u-info-txt-color, #FFFFFF);
|
|
53
|
+
--_edge: var(--u-info-color-strong, #1565C0);
|
|
54
|
+
}
|
|
55
|
+
:host([color="success"]) {
|
|
56
|
+
--_marker: var(--u-success-color, #2E7D32);
|
|
57
|
+
--_on-marker: var(--u-success-txt-color, #FFFFFF);
|
|
58
|
+
--_edge: var(--u-success-color-strong, #1B5E20);
|
|
59
|
+
}
|
|
60
|
+
:host([color="warning"]) {
|
|
61
|
+
--_marker: var(--u-warning-color, #FDD835);
|
|
62
|
+
--_on-marker: var(--u-warning-txt-color, #000000);
|
|
63
|
+
--_edge: var(--u-warning-color-strong, #8A4A00);
|
|
64
|
+
}
|
|
65
|
+
:host([color="danger"]) {
|
|
66
|
+
--_marker: var(--u-danger-color, #D32F2F);
|
|
67
|
+
--_on-marker: var(--u-danger-txt-color, #FFFFFF);
|
|
68
|
+
--_edge: var(--u-danger-color-strong, #C62828);
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
.line {
|
|
72
|
+
flex: 1 1 auto;
|
|
73
|
+
min-height: var(--u-space-md, 12px);
|
|
74
|
+
margin-top: var(--u-space-2xs, 4px);
|
|
75
|
+
border-left: 1px solid var(--u-border-color, #E0E0E0);
|
|
76
|
+
}
|
|
77
|
+
/* The last entry has no next marker to reach. */
|
|
78
|
+
:host(:last-child) .line {
|
|
79
|
+
display: none;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.content {
|
|
83
|
+
min-width: 0;
|
|
84
|
+
padding-bottom: var(--u-space-lg, 16px);
|
|
85
|
+
}
|
|
86
|
+
:host(:last-child) .content {
|
|
87
|
+
padding-bottom: 0;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.header {
|
|
91
|
+
display: flex;
|
|
92
|
+
flex-wrap: wrap;
|
|
93
|
+
align-items: baseline;
|
|
94
|
+
column-gap: var(--u-space-sm, 8px);
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
.heading {
|
|
98
|
+
font-size: var(--u-text-label-size, 13px);
|
|
99
|
+
line-height: var(--u-text-label-leading, 1.5);
|
|
100
|
+
font-weight: var(--u-text-label-weight, 600);
|
|
101
|
+
color: var(--u-txt-color, #212121);
|
|
102
|
+
overflow-wrap: anywhere;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
.time {
|
|
106
|
+
font-size: var(--u-text-caption-size, 12px);
|
|
107
|
+
color: var(--u-txt-color-weak, #616161);
|
|
108
|
+
font-variant-numeric: tabular-nums;
|
|
109
|
+
white-space: nowrap;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
.body {
|
|
113
|
+
margin-top: var(--u-space-2xs, 4px);
|
|
114
|
+
font-size: var(--u-text-body-size, 14px);
|
|
115
|
+
line-height: var(--u-text-body-leading, 1.6);
|
|
116
|
+
color: var(--u-txt-color-weak, #616161);
|
|
117
|
+
overflow-wrap: anywhere;
|
|
118
|
+
}
|
|
119
|
+
/* No body content — no gap under the header. */
|
|
120
|
+
.body.empty {
|
|
121
|
+
display: none;
|
|
122
|
+
}
|
|
123
|
+
`;
|
|
124
|
+
//#endregion
|
|
125
|
+
export { n as itemStyles, t as styles };
|
package/dist/index.d.ts
CHANGED
|
@@ -11,6 +11,8 @@ export { GroupBox } from './components/GroupBox.js';
|
|
|
11
11
|
export { InfoSection } from './components/InfoSection.js';
|
|
12
12
|
export { InfoField, isBlank } from './components/InfoField.js';
|
|
13
13
|
export { EmptyState } from './components/EmptyState.js';
|
|
14
|
+
export { Timeline, TimelineItem } from './components/Timeline.js';
|
|
15
|
+
export type { TimelineItemColor } from './components/Timeline.js';
|
|
14
16
|
export { ActionBar } from './components/ActionBar.js';
|
|
15
17
|
export { MasterDetailLayout } from './components/MasterDetailLayout.js';
|
|
16
18
|
export type { MasterDetailLayoutEventMap } from './components/MasterDetailLayout.js';
|
package/dist/index.js
CHANGED
|
@@ -7,11 +7,12 @@ import { GroupBox as l } from "./components/GroupBox.js";
|
|
|
7
7
|
import { InfoSection as u } from "./components/InfoSection.js";
|
|
8
8
|
import { InfoField as d, isBlank as f } from "./components/InfoField.js";
|
|
9
9
|
import { EmptyState as p } from "./components/EmptyState.js";
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import {
|
|
10
|
+
import { Timeline as m, TimelineItem as h } from "./components/Timeline.js";
|
|
11
|
+
import { ActionBar as g } from "./components/ActionBar.js";
|
|
12
|
+
import { MasterDetailLayout as _ } from "./components/MasterDetailLayout.js";
|
|
13
|
+
import { Wizard as v } from "./components/Wizard.js";
|
|
14
|
+
import { translate as y } from "./translate.js";
|
|
14
15
|
//#region src/index.ts
|
|
15
|
-
var
|
|
16
|
+
var b = t;
|
|
16
17
|
//#endregion
|
|
17
|
-
export {
|
|
18
|
+
export { g as ActionBar, p as EmptyState, l as GroupBox, d as InfoField, u as InfoSection, _ as MasterDetailLayout, c as PageHeader, e as ScreenObserver, m as Timeline, h as TimelineItem, v as Wizard, t as app, b as default, n as filterSidebarItems, r as getDefaultLocale, i as getLocaleStrings, f as isBlank, a as modernAppLocale, o as registerLocale, s as setDefaultLocale, y as translate };
|
|
@@ -13,8 +13,8 @@ import "../components/SidebarButton.js";
|
|
|
13
13
|
import { styles as c } from "./SidebarLayout.styles.js";
|
|
14
14
|
import { html as l, nothing as u } from "lit";
|
|
15
15
|
import { customElement as d, property as f, query as p, state as m } from "lit/decorators.js";
|
|
16
|
-
import "@iyulab/components/dist/components/button/UButton.js";
|
|
17
16
|
import "@iyulab/components/dist/components/icon/UIcon.js";
|
|
17
|
+
import "@iyulab/components/dist/components/button/UButton.js";
|
|
18
18
|
import { unsafeHTML as h } from "lit/directives/unsafe-html.js";
|
|
19
19
|
import { repeat as g } from "lit/directives/repeat.js";
|
|
20
20
|
import "@iyulab/components/dist/components/popover/UPopover.js";
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { Timeline as TimelineElement } from '@iyulab/modern-app/dist/components/Timeline.js';
|
|
3
|
+
|
|
4
|
+
type TimelineOwnProps = Omit<TimelineElement, keyof HTMLElement>;
|
|
5
|
+
|
|
6
|
+
export declare const Timeline: React.ForwardRefExoticComponent<
|
|
7
|
+
Partial<Omit<TimelineElement, Exclude<keyof React.HTMLAttributes<TimelineElement>, keyof TimelineOwnProps>>>
|
|
8
|
+
& Omit<React.HTMLAttributes<TimelineElement>, keyof TimelineOwnProps | never>
|
|
9
|
+
& React.RefAttributes<TimelineElement>
|
|
10
|
+
& {
|
|
11
|
+
}
|
|
12
|
+
>;
|
|
13
|
+
|
|
14
|
+
export type TimelineProps = React.ComponentProps<typeof Timeline>;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { createComponent } from '@lit/react';
|
|
3
|
+
import { Timeline as TimelineElement } from '@iyulab/modern-app/dist/components/Timeline.js';
|
|
4
|
+
|
|
5
|
+
export const Timeline = createComponent({
|
|
6
|
+
react: React,
|
|
7
|
+
tagName: 'u-timeline',
|
|
8
|
+
elementClass: TimelineElement,
|
|
9
|
+
events: {},
|
|
10
|
+
});
|
package/dist/react/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
export * from '@iyulab/modern-app/dist/react.js';
|
|
2
|
+
export { Timeline, TimelineProps } from './Timeline';
|
|
2
3
|
export { SidebarButton, SidebarButtonProps } from './SidebarButton';
|
|
3
4
|
export { PageHeader, PageHeaderProps } from './PageHeader';
|
|
4
5
|
export { MasterDetailLayout, MasterDetailLayoutProps } from './MasterDetailLayout';
|
package/dist/react/index.js
CHANGED
package/dist/react.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ import { EventName } from '@lit/react';
|
|
|
3
3
|
import { SidebarLayout as SidebarLayoutElement, SidebarLayoutEventMap } from './layouts/SidebarLayout.js';
|
|
4
4
|
import { Wizard as WizardElement, WizardEventMap } from './components/Wizard.js';
|
|
5
5
|
import { GroupBoxLevel } from './components/GroupBox.js';
|
|
6
|
+
import { TimelineItemColor } from './components/Timeline.js';
|
|
6
7
|
import { InfoFieldFormat, InfoFieldSize, InfoFieldTrend, InfoFieldTone } from './components/InfoField.js';
|
|
7
8
|
export { ScreenObserver } from './internals/ScreenObserver.js';
|
|
8
9
|
export type { ScreenSize, ScreenObserverConfig, ScreenResizeEvent } from './internals/ScreenObserver.js';
|
|
@@ -69,6 +70,14 @@ declare module 'react' {
|
|
|
69
70
|
'u-info-section': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
70
71
|
min?: number | string;
|
|
71
72
|
};
|
|
73
|
+
'u-timeline': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement>;
|
|
74
|
+
'u-timeline-item': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
75
|
+
heading?: string;
|
|
76
|
+
datetime?: string;
|
|
77
|
+
color?: TimelineItemColor;
|
|
78
|
+
icon?: string;
|
|
79
|
+
lib?: string;
|
|
80
|
+
};
|
|
72
81
|
'u-master-detail-layout': React.DetailedHTMLProps<React.HTMLAttributes<HTMLElement>, HTMLElement> & {
|
|
73
82
|
'master-size'?: string;
|
|
74
83
|
'overlay-breakpoint'?: number | string;
|
package/package.json
CHANGED
|
@@ -261,6 +261,7 @@ re-assembled per screen — that is where a product stops looking like one produ
|
|
|
261
261
|
- [`u-info-field`](./references/components/info-field.md) — Read-only label/value pair that keeps "not set" and "zero" distinct
|
|
262
262
|
- [`u-empty-state`](./references/components/empty-state.md) — Empty list or empty search, worded differently because they are different facts
|
|
263
263
|
- [`u-action-bar`](./references/components/action-bar.md) — Closing action row with a separated destructive group
|
|
264
|
+
- [`u-timeline`](./references/components/timeline.md) — Status or activity history: what happened, and when
|
|
264
265
|
|
|
265
266
|
---
|
|
266
267
|
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# u-timeline
|
|
2
|
+
|
|
3
|
+
**Tags:** `u-timeline` · `u-timeline-item`
|
|
4
|
+
|
|
5
|
+
A status or activity history on a detail screen — "what happened, and when" (an order moving
|
|
6
|
+
through its states, a ticket's activity, an approval chain). Each entry is a marker on a rail, a
|
|
7
|
+
heading, a time and an optional body.
|
|
8
|
+
|
|
9
|
+
```html
|
|
10
|
+
<u-timeline>
|
|
11
|
+
<u-timeline-item heading="Paid" datetime="2026-10-06T09:30" color="success" icon="check">
|
|
12
|
+
Bank transfer received.
|
|
13
|
+
</u-timeline-item>
|
|
14
|
+
<u-timeline-item heading="Shipped" datetime="2026-10-06T15:10" color="primary"></u-timeline-item>
|
|
15
|
+
<u-timeline-item heading="Ordered" datetime="2026-10-05"></u-timeline-item>
|
|
16
|
+
</u-timeline>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
Entries are shown in DOM order — put the newest first or last, as your screen reads. `u-timeline` is
|
|
20
|
+
a list and each entry a list item, so assistive technology announces the count.
|
|
21
|
+
|
|
22
|
+
⚠ **Colour is never the only carrier.** Say the status in `heading` ("Rejected"), not only with
|
|
23
|
+
`color="danger"` (WCAG 1.4.1). The marker is decorative to assistive technology.
|
|
24
|
+
|
|
25
|
+
## `u-timeline-item` — Slots
|
|
26
|
+
|
|
27
|
+
| Name | Description |
|
|
28
|
+
|------|-------------|
|
|
29
|
+
| (default) | Body — detail under the heading (who, a note, a link) |
|
|
30
|
+
| `heading` | Replaces the `heading` text with richer content |
|
|
31
|
+
| `time` | Replaces the formatted time text (e.g. a relative "2 hours ago"); `datetime` still annotates it |
|
|
32
|
+
|
|
33
|
+
## `u-timeline-item` — Properties
|
|
34
|
+
|
|
35
|
+
| Property | Type | Default | Reflect | Description |
|
|
36
|
+
|----------|------|---------|---------|-------------|
|
|
37
|
+
| `heading` | `string` | `''` | | What happened |
|
|
38
|
+
| `datetime` | `string` | `''` | | ISO `YYYY-MM-DD` or `YYYY-MM-DDTHH:mm[:ss]`. Rendered as `<time datetime>`, formatted for the active locale — a date alone as a date (never shifted by a time zone), a date-time with its time |
|
|
39
|
+
| `color` | `'neutral'\|'primary'\|'info'\|'success'\|'warning'\|'danger'` | `'neutral'` | ✓ | Marker colour — the role colours of `u-tag`/`u-badge` |
|
|
40
|
+
| `icon` | `string` | — | | Icon drawn inside the marker (the marker grows to hold it) |
|
|
41
|
+
| `lib` | `string` | — | | Icon library for `icon` |
|
|
42
|
+
|
|
43
|
+
## CSS Parts
|
|
44
|
+
|
|
45
|
+
| Element | Parts |
|
|
46
|
+
|---------|-------|
|
|
47
|
+
| `u-timeline` | `host` |
|
|
48
|
+
| `u-timeline-item` | `host` · `rail` · `marker` · `line` · `content` · `header` · `heading` · `time` · `body` |
|
|
49
|
+
|
|
50
|
+
## CSS Custom Properties
|
|
51
|
+
|
|
52
|
+
| Property | Description |
|
|
53
|
+
|----------|-------------|
|
|
54
|
+
| `--app-timeline-rail-width` | Rail column width; also the marker size when it holds an icon (default 24px) |
|
|
55
|
+
| `--app-timeline-marker-size` | Plain marker size (default 12px) |
|
|
56
|
+
| `--u-{role}-color` / `-txt-color` / `-color-strong` | Marker fill, the icon colour on it, and its edge |
|
|
57
|
+
| `--u-text-label-*` · `--u-text-caption-*` · `--u-text-body-*` | Heading, time and body typography |
|