@deepfuture/dui-templates 1.0.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/README.md +214 -0
- package/all.d.ts +10 -0
- package/all.js +20 -0
- package/content/briefing-block.d.ts +36 -0
- package/content/briefing-block.js +281 -0
- package/content/empty-state.d.ts +24 -0
- package/content/empty-state.js +187 -0
- package/content/index.d.ts +5 -0
- package/content/index.js +5 -0
- package/content/numbered-insight.d.ts +30 -0
- package/content/numbered-insight.js +242 -0
- package/dashboard/index.d.ts +5 -0
- package/dashboard/index.js +5 -0
- package/dashboard/page-header.d.ts +29 -0
- package/dashboard/page-header.js +218 -0
- package/dashboard/section-panel.d.ts +41 -0
- package/dashboard/section-panel.js +393 -0
- package/data/index.d.ts +5 -0
- package/data/index.js +4 -0
- package/data/key-value.d.ts +27 -0
- package/data/key-value.js +165 -0
- package/data/market-table.d.ts +40 -0
- package/data/market-table.js +270 -0
- package/feed/activity-item.d.ts +35 -0
- package/feed/activity-item.js +278 -0
- package/feed/feed-item.d.ts +32 -0
- package/feed/feed-item.js +260 -0
- package/feed/headline-item.d.ts +27 -0
- package/feed/headline-item.js +187 -0
- package/feed/index.d.ts +6 -0
- package/feed/index.js +6 -0
- package/feed/social-post.d.ts +31 -0
- package/feed/social-post.js +268 -0
- package/media/avatar-row.d.ts +31 -0
- package/media/avatar-row.js +164 -0
- package/media/index.d.ts +7 -0
- package/media/index.js +5 -0
- package/media/media-grid.d.ts +32 -0
- package/media/media-grid.js +199 -0
- package/metrics/index.d.ts +6 -0
- package/metrics/index.js +6 -0
- package/metrics/progress-bar.d.ts +31 -0
- package/metrics/progress-bar.js +212 -0
- package/metrics/risk-gauge.d.ts +31 -0
- package/metrics/risk-gauge.js +289 -0
- package/metrics/score-item.d.ts +33 -0
- package/metrics/score-item.js +253 -0
- package/metrics/stat-card.d.ts +29 -0
- package/metrics/stat-card.js +230 -0
- package/package.json +61 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { css, html, LitElement, nothing } from "lit";
|
|
36
|
+
import { property } from "lit/decorators.js";
|
|
37
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
38
|
+
const styles = css `
|
|
39
|
+
:host {
|
|
40
|
+
display: block;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
article {
|
|
44
|
+
display: flex;
|
|
45
|
+
flex-direction: column;
|
|
46
|
+
gap: var(--space-0_5);
|
|
47
|
+
padding: var(--space-1_5) var(--space-2);
|
|
48
|
+
border-radius: var(--radius-sm);
|
|
49
|
+
transition: background var(--duration-fast) ease;
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
article:hover {
|
|
53
|
+
background: var(--surface-1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
.title {
|
|
57
|
+
font-family: var(--font-sans);
|
|
58
|
+
font-size: var(--text-sm);
|
|
59
|
+
font-weight: var(--font-weight-medium);
|
|
60
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
61
|
+
line-height: var(--line-height-snug);
|
|
62
|
+
color: var(--foreground);
|
|
63
|
+
text-decoration: none;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
.meta {
|
|
67
|
+
display: flex;
|
|
68
|
+
align-items: center;
|
|
69
|
+
gap: var(--space-1_5);
|
|
70
|
+
font-family: var(--font-sans);
|
|
71
|
+
font-size: var(--text-xs);
|
|
72
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
73
|
+
line-height: var(--line-height-normal);
|
|
74
|
+
color: var(--text-3);
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.separator {
|
|
78
|
+
color: var(--text-3);
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
.actions {
|
|
82
|
+
display: flex;
|
|
83
|
+
align-items: center;
|
|
84
|
+
flex-shrink: 0;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
.actions[hidden] {
|
|
88
|
+
display: none;
|
|
89
|
+
}
|
|
90
|
+
`;
|
|
91
|
+
/**
|
|
92
|
+
* `<dui-headline-item>` — A minimal headline row: title, source, and timestamp.
|
|
93
|
+
*
|
|
94
|
+
* Designed for dense headline lists and news tickers where space is at a premium.
|
|
95
|
+
* Renders as a single horizontal row with the title taking available space and
|
|
96
|
+
* source + timestamp right-aligned.
|
|
97
|
+
*
|
|
98
|
+
* @slot actions - Optional trailing action buttons or links.
|
|
99
|
+
* @csspart article - The outer article container.
|
|
100
|
+
* @csspart title - The headline title text.
|
|
101
|
+
* @csspart meta - The source + timestamp row.
|
|
102
|
+
*/
|
|
103
|
+
let DuiHeadlineItem = (() => {
|
|
104
|
+
let _classSuper = LitElement;
|
|
105
|
+
let _title_decorators;
|
|
106
|
+
let _title_initializers = [];
|
|
107
|
+
let _title_extraInitializers = [];
|
|
108
|
+
let _source_decorators;
|
|
109
|
+
let _source_initializers = [];
|
|
110
|
+
let _source_extraInitializers = [];
|
|
111
|
+
let _timestamp_decorators;
|
|
112
|
+
let _timestamp_initializers = [];
|
|
113
|
+
let _timestamp_extraInitializers = [];
|
|
114
|
+
let _href_decorators;
|
|
115
|
+
let _href_initializers = [];
|
|
116
|
+
let _href_extraInitializers = [];
|
|
117
|
+
return class DuiHeadlineItem extends _classSuper {
|
|
118
|
+
static {
|
|
119
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
120
|
+
_title_decorators = [property()];
|
|
121
|
+
_source_decorators = [property()];
|
|
122
|
+
_timestamp_decorators = [property()];
|
|
123
|
+
_href_decorators = [property()];
|
|
124
|
+
__esDecorate(this, null, _title_decorators, { kind: "accessor", name: "title", static: false, private: false, access: { has: obj => "title" in obj, get: obj => obj.title, set: (obj, value) => { obj.title = value; } }, metadata: _metadata }, _title_initializers, _title_extraInitializers);
|
|
125
|
+
__esDecorate(this, null, _source_decorators, { kind: "accessor", name: "source", static: false, private: false, access: { has: obj => "source" in obj, get: obj => obj.source, set: (obj, value) => { obj.source = value; } }, metadata: _metadata }, _source_initializers, _source_extraInitializers);
|
|
126
|
+
__esDecorate(this, null, _timestamp_decorators, { kind: "accessor", name: "timestamp", static: false, private: false, access: { has: obj => "timestamp" in obj, get: obj => obj.timestamp, set: (obj, value) => { obj.timestamp = value; } }, metadata: _metadata }, _timestamp_initializers, _timestamp_extraInitializers);
|
|
127
|
+
__esDecorate(this, null, _href_decorators, { kind: "accessor", name: "href", static: false, private: false, access: { has: obj => "href" in obj, get: obj => obj.href, set: (obj, value) => { obj.href = value; } }, metadata: _metadata }, _href_initializers, _href_extraInitializers);
|
|
128
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
129
|
+
}
|
|
130
|
+
static tagName = "dui-headline-item";
|
|
131
|
+
static styles = [base, styles];
|
|
132
|
+
#title_accessor_storage = __runInitializers(this, _title_initializers, "");
|
|
133
|
+
/** Primary headline text. */
|
|
134
|
+
get title() { return this.#title_accessor_storage; }
|
|
135
|
+
set title(value) { this.#title_accessor_storage = value; }
|
|
136
|
+
#source_accessor_storage = (__runInitializers(this, _title_extraInitializers), __runInitializers(this, _source_initializers, ""));
|
|
137
|
+
/** Source or publication name. */
|
|
138
|
+
get source() { return this.#source_accessor_storage; }
|
|
139
|
+
set source(value) { this.#source_accessor_storage = value; }
|
|
140
|
+
#timestamp_accessor_storage = (__runInitializers(this, _source_extraInitializers), __runInitializers(this, _timestamp_initializers, ""));
|
|
141
|
+
/** Display timestamp (e.g. "2 min ago", "14:23 UTC"). */
|
|
142
|
+
get timestamp() { return this.#timestamp_accessor_storage; }
|
|
143
|
+
set timestamp(value) { this.#timestamp_accessor_storage = value; }
|
|
144
|
+
#href_accessor_storage = (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _href_initializers, ""));
|
|
145
|
+
/** Optional URL — when set, the title renders as a link. */
|
|
146
|
+
get href() { return this.#href_accessor_storage; }
|
|
147
|
+
set href(value) { this.#href_accessor_storage = value; }
|
|
148
|
+
/** Toggle hidden on slot wrapper when slotted content changes. */
|
|
149
|
+
#onSlotChange(e) {
|
|
150
|
+
const slot = e.target;
|
|
151
|
+
slot.parentElement.hidden = slot.assignedElements().length === 0;
|
|
152
|
+
}
|
|
153
|
+
render() {
|
|
154
|
+
const titleContent = this.href
|
|
155
|
+
? html `<a href=${this.href} class="title" part="title">${this.title}</a>`
|
|
156
|
+
: html `<span class="title" part="title">${this.title}</span>`;
|
|
157
|
+
return html `
|
|
158
|
+
<article part="article">
|
|
159
|
+
${titleContent}
|
|
160
|
+
|
|
161
|
+
${this.source || this.timestamp
|
|
162
|
+
? html `
|
|
163
|
+
<div class="meta" part="meta">
|
|
164
|
+
${this.source ? html `<span>${this.source}</span>` : nothing}
|
|
165
|
+
${this.source && this.timestamp
|
|
166
|
+
? html `<span class="separator">·</span>`
|
|
167
|
+
: nothing}
|
|
168
|
+
${this.timestamp
|
|
169
|
+
? html `<time>${this.timestamp}</time>`
|
|
170
|
+
: nothing}
|
|
171
|
+
</div>`
|
|
172
|
+
: nothing}
|
|
173
|
+
|
|
174
|
+
<div class="actions" hidden>
|
|
175
|
+
<slot name="actions" @slotchange=${this.#onSlotChange}></slot>
|
|
176
|
+
</div>
|
|
177
|
+
</article>
|
|
178
|
+
`;
|
|
179
|
+
}
|
|
180
|
+
constructor() {
|
|
181
|
+
super(...arguments);
|
|
182
|
+
__runInitializers(this, _href_extraInitializers);
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
})();
|
|
186
|
+
export { DuiHeadlineItem };
|
|
187
|
+
customElements.define(DuiHeadlineItem.tagName, DuiHeadlineItem);
|
package/feed/index.d.ts
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DuiFeedItem } from "./feed-item.js";
|
|
2
|
+
import { DuiActivityItem } from "./activity-item.js";
|
|
3
|
+
import { DuiSocialPost } from "./social-post.js";
|
|
4
|
+
import { DuiHeadlineItem } from "./headline-item.js";
|
|
5
|
+
export { DuiFeedItem, DuiActivityItem, DuiSocialPost, DuiHeadlineItem };
|
|
6
|
+
export declare const feedFamily: (typeof DuiFeedItem | typeof DuiActivityItem | typeof DuiSocialPost | typeof DuiHeadlineItem)[];
|
package/feed/index.js
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { DuiFeedItem } from "./feed-item.js";
|
|
2
|
+
import { DuiActivityItem } from "./activity-item.js";
|
|
3
|
+
import { DuiSocialPost } from "./social-post.js";
|
|
4
|
+
import { DuiHeadlineItem } from "./headline-item.js";
|
|
5
|
+
export { DuiFeedItem, DuiActivityItem, DuiSocialPost, DuiHeadlineItem };
|
|
6
|
+
export const feedFamily = [DuiFeedItem, DuiActivityItem, DuiSocialPost, DuiHeadlineItem];
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/avatar";
|
|
3
|
+
import "@deepfuture/dui-components/badge";
|
|
4
|
+
/**
|
|
5
|
+
* `<dui-social-post>` — A social signal card for monitoring dashboards.
|
|
6
|
+
*
|
|
7
|
+
* Displays an author, handle, timestamp, body text, and optional source
|
|
8
|
+
* badge and avatar. Useful for social media monitoring feeds.
|
|
9
|
+
*
|
|
10
|
+
* @slot avatar - Profile picture (dui-avatar recommended).
|
|
11
|
+
* @slot actions - Optional action buttons or links.
|
|
12
|
+
* @csspart article - The outer article container.
|
|
13
|
+
* @csspart header - The author/handle/timestamp + source badge row.
|
|
14
|
+
* @csspart body - The post body text.
|
|
15
|
+
*/
|
|
16
|
+
export declare class DuiSocialPost extends LitElement {
|
|
17
|
+
#private;
|
|
18
|
+
static tagName: "dui-social-post";
|
|
19
|
+
static styles: import("lit").CSSResult[];
|
|
20
|
+
/** Display name of the post author. */
|
|
21
|
+
accessor author: string;
|
|
22
|
+
/** Handle / username (e.g. "@analyst_jane"). */
|
|
23
|
+
accessor handle: string;
|
|
24
|
+
/** Display timestamp (e.g. "2 min ago", "14:23 UTC"). */
|
|
25
|
+
accessor timestamp: string;
|
|
26
|
+
/** Post body text. */
|
|
27
|
+
accessor body: string;
|
|
28
|
+
/** Source platform label (e.g. "X", "Bluesky", "Telegram"). */
|
|
29
|
+
accessor source: string;
|
|
30
|
+
render(): TemplateResult;
|
|
31
|
+
}
|
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
var __esDecorate = (this && this.__esDecorate) || function (ctor, descriptorIn, decorators, contextIn, initializers, extraInitializers) {
|
|
2
|
+
function accept(f) { if (f !== void 0 && typeof f !== "function") throw new TypeError("Function expected"); return f; }
|
|
3
|
+
var kind = contextIn.kind, key = kind === "getter" ? "get" : kind === "setter" ? "set" : "value";
|
|
4
|
+
var target = !descriptorIn && ctor ? contextIn["static"] ? ctor : ctor.prototype : null;
|
|
5
|
+
var descriptor = descriptorIn || (target ? Object.getOwnPropertyDescriptor(target, contextIn.name) : {});
|
|
6
|
+
var _, done = false;
|
|
7
|
+
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
8
|
+
var context = {};
|
|
9
|
+
for (var p in contextIn) context[p] = p === "access" ? {} : contextIn[p];
|
|
10
|
+
for (var p in contextIn.access) context.access[p] = contextIn.access[p];
|
|
11
|
+
context.addInitializer = function (f) { if (done) throw new TypeError("Cannot add initializers after decoration has completed"); extraInitializers.push(accept(f || null)); };
|
|
12
|
+
var result = (0, decorators[i])(kind === "accessor" ? { get: descriptor.get, set: descriptor.set } : descriptor[key], context);
|
|
13
|
+
if (kind === "accessor") {
|
|
14
|
+
if (result === void 0) continue;
|
|
15
|
+
if (result === null || typeof result !== "object") throw new TypeError("Object expected");
|
|
16
|
+
if (_ = accept(result.get)) descriptor.get = _;
|
|
17
|
+
if (_ = accept(result.set)) descriptor.set = _;
|
|
18
|
+
if (_ = accept(result.init)) initializers.unshift(_);
|
|
19
|
+
}
|
|
20
|
+
else if (_ = accept(result)) {
|
|
21
|
+
if (kind === "field") initializers.unshift(_);
|
|
22
|
+
else descriptor[key] = _;
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
if (target) Object.defineProperty(target, contextIn.name, descriptor);
|
|
26
|
+
done = true;
|
|
27
|
+
};
|
|
28
|
+
var __runInitializers = (this && this.__runInitializers) || function (thisArg, initializers, value) {
|
|
29
|
+
var useValue = arguments.length > 2;
|
|
30
|
+
for (var i = 0; i < initializers.length; i++) {
|
|
31
|
+
value = useValue ? initializers[i].call(thisArg, value) : initializers[i].call(thisArg);
|
|
32
|
+
}
|
|
33
|
+
return useValue ? value : void 0;
|
|
34
|
+
};
|
|
35
|
+
import { css, html, LitElement, nothing } from "lit";
|
|
36
|
+
import { property } from "lit/decorators.js";
|
|
37
|
+
import { base } from "@deepfuture/dui-core/base";
|
|
38
|
+
import "@deepfuture/dui-components/avatar";
|
|
39
|
+
import "@deepfuture/dui-components/badge";
|
|
40
|
+
const styles = css `
|
|
41
|
+
:host {
|
|
42
|
+
display: block;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
article {
|
|
46
|
+
display: flex;
|
|
47
|
+
gap: var(--space-3);
|
|
48
|
+
padding: var(--space-3);
|
|
49
|
+
border: var(--border-width-thin) solid var(--border);
|
|
50
|
+
border-radius: var(--radius-md);
|
|
51
|
+
background: var(--surface-1);
|
|
52
|
+
transition: background var(--duration-fast) ease;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
article:hover {
|
|
56
|
+
background: var(--surface-2);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/* ── Avatar ── */
|
|
60
|
+
.avatar-slot {
|
|
61
|
+
flex-shrink: 0;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.avatar-slot[hidden] {
|
|
65
|
+
display: none;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/* ── Main content ── */
|
|
69
|
+
.main {
|
|
70
|
+
display: flex;
|
|
71
|
+
flex-direction: column;
|
|
72
|
+
gap: var(--space-1);
|
|
73
|
+
min-width: 0;
|
|
74
|
+
flex: 1;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/* ── Header row ── */
|
|
78
|
+
header {
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: baseline;
|
|
81
|
+
gap: var(--space-1_5);
|
|
82
|
+
min-width: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.header-left {
|
|
86
|
+
display: flex;
|
|
87
|
+
align-items: baseline;
|
|
88
|
+
gap: var(--space-1_5);
|
|
89
|
+
min-width: 0;
|
|
90
|
+
flex: 1;
|
|
91
|
+
flex-wrap: wrap;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
.author {
|
|
95
|
+
font-family: var(--font-sans);
|
|
96
|
+
font-size: var(--text-sm);
|
|
97
|
+
font-weight: var(--font-weight-semibold);
|
|
98
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
99
|
+
line-height: var(--line-height-snug);
|
|
100
|
+
color: var(--foreground);
|
|
101
|
+
white-space: nowrap;
|
|
102
|
+
overflow: hidden;
|
|
103
|
+
text-overflow: ellipsis;
|
|
104
|
+
min-width: 0;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
.handle {
|
|
108
|
+
font-family: var(--font-sans);
|
|
109
|
+
font-size: var(--text-xs);
|
|
110
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
111
|
+
line-height: var(--line-height-snug);
|
|
112
|
+
color: var(--text-3);
|
|
113
|
+
white-space: nowrap;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
.separator {
|
|
117
|
+
color: var(--text-3);
|
|
118
|
+
font-size: var(--text-xs);
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
.timestamp {
|
|
122
|
+
font-family: var(--font-sans);
|
|
123
|
+
font-size: var(--text-xs);
|
|
124
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
125
|
+
line-height: var(--line-height-snug);
|
|
126
|
+
color: var(--text-3);
|
|
127
|
+
white-space: nowrap;
|
|
128
|
+
flex-shrink: 0;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/* ── Body ── */
|
|
132
|
+
.body {
|
|
133
|
+
font-family: var(--font-sans);
|
|
134
|
+
font-size: var(--text-sm);
|
|
135
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
136
|
+
line-height: var(--line-height-normal);
|
|
137
|
+
color: var(--text-1);
|
|
138
|
+
margin-bottom: var(--space-1);
|
|
139
|
+
white-space: pre-line;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
.actions {
|
|
143
|
+
display: flex;
|
|
144
|
+
align-items: center;
|
|
145
|
+
gap: var(--space-2);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
.actions[hidden] {
|
|
149
|
+
display: none;
|
|
150
|
+
}
|
|
151
|
+
`;
|
|
152
|
+
/**
|
|
153
|
+
* `<dui-social-post>` — A social signal card for monitoring dashboards.
|
|
154
|
+
*
|
|
155
|
+
* Displays an author, handle, timestamp, body text, and optional source
|
|
156
|
+
* badge and avatar. Useful for social media monitoring feeds.
|
|
157
|
+
*
|
|
158
|
+
* @slot avatar - Profile picture (dui-avatar recommended).
|
|
159
|
+
* @slot actions - Optional action buttons or links.
|
|
160
|
+
* @csspart article - The outer article container.
|
|
161
|
+
* @csspart header - The author/handle/timestamp + source badge row.
|
|
162
|
+
* @csspart body - The post body text.
|
|
163
|
+
*/
|
|
164
|
+
let DuiSocialPost = (() => {
|
|
165
|
+
let _classSuper = LitElement;
|
|
166
|
+
let _author_decorators;
|
|
167
|
+
let _author_initializers = [];
|
|
168
|
+
let _author_extraInitializers = [];
|
|
169
|
+
let _handle_decorators;
|
|
170
|
+
let _handle_initializers = [];
|
|
171
|
+
let _handle_extraInitializers = [];
|
|
172
|
+
let _timestamp_decorators;
|
|
173
|
+
let _timestamp_initializers = [];
|
|
174
|
+
let _timestamp_extraInitializers = [];
|
|
175
|
+
let _body_decorators;
|
|
176
|
+
let _body_initializers = [];
|
|
177
|
+
let _body_extraInitializers = [];
|
|
178
|
+
let _source_decorators;
|
|
179
|
+
let _source_initializers = [];
|
|
180
|
+
let _source_extraInitializers = [];
|
|
181
|
+
return class DuiSocialPost extends _classSuper {
|
|
182
|
+
static {
|
|
183
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
184
|
+
_author_decorators = [property()];
|
|
185
|
+
_handle_decorators = [property()];
|
|
186
|
+
_timestamp_decorators = [property()];
|
|
187
|
+
_body_decorators = [property()];
|
|
188
|
+
_source_decorators = [property()];
|
|
189
|
+
__esDecorate(this, null, _author_decorators, { kind: "accessor", name: "author", static: false, private: false, access: { has: obj => "author" in obj, get: obj => obj.author, set: (obj, value) => { obj.author = value; } }, metadata: _metadata }, _author_initializers, _author_extraInitializers);
|
|
190
|
+
__esDecorate(this, null, _handle_decorators, { kind: "accessor", name: "handle", static: false, private: false, access: { has: obj => "handle" in obj, get: obj => obj.handle, set: (obj, value) => { obj.handle = value; } }, metadata: _metadata }, _handle_initializers, _handle_extraInitializers);
|
|
191
|
+
__esDecorate(this, null, _timestamp_decorators, { kind: "accessor", name: "timestamp", static: false, private: false, access: { has: obj => "timestamp" in obj, get: obj => obj.timestamp, set: (obj, value) => { obj.timestamp = value; } }, metadata: _metadata }, _timestamp_initializers, _timestamp_extraInitializers);
|
|
192
|
+
__esDecorate(this, null, _body_decorators, { kind: "accessor", name: "body", static: false, private: false, access: { has: obj => "body" in obj, get: obj => obj.body, set: (obj, value) => { obj.body = value; } }, metadata: _metadata }, _body_initializers, _body_extraInitializers);
|
|
193
|
+
__esDecorate(this, null, _source_decorators, { kind: "accessor", name: "source", static: false, private: false, access: { has: obj => "source" in obj, get: obj => obj.source, set: (obj, value) => { obj.source = value; } }, metadata: _metadata }, _source_initializers, _source_extraInitializers);
|
|
194
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
195
|
+
}
|
|
196
|
+
static tagName = "dui-social-post";
|
|
197
|
+
static styles = [base, styles];
|
|
198
|
+
#author_accessor_storage = __runInitializers(this, _author_initializers, "");
|
|
199
|
+
/** Display name of the post author. */
|
|
200
|
+
get author() { return this.#author_accessor_storage; }
|
|
201
|
+
set author(value) { this.#author_accessor_storage = value; }
|
|
202
|
+
#handle_accessor_storage = (__runInitializers(this, _author_extraInitializers), __runInitializers(this, _handle_initializers, ""));
|
|
203
|
+
/** Handle / username (e.g. "@analyst_jane"). */
|
|
204
|
+
get handle() { return this.#handle_accessor_storage; }
|
|
205
|
+
set handle(value) { this.#handle_accessor_storage = value; }
|
|
206
|
+
#timestamp_accessor_storage = (__runInitializers(this, _handle_extraInitializers), __runInitializers(this, _timestamp_initializers, ""));
|
|
207
|
+
/** Display timestamp (e.g. "2 min ago", "14:23 UTC"). */
|
|
208
|
+
get timestamp() { return this.#timestamp_accessor_storage; }
|
|
209
|
+
set timestamp(value) { this.#timestamp_accessor_storage = value; }
|
|
210
|
+
#body_accessor_storage = (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _body_initializers, ""));
|
|
211
|
+
/** Post body text. */
|
|
212
|
+
get body() { return this.#body_accessor_storage; }
|
|
213
|
+
set body(value) { this.#body_accessor_storage = value; }
|
|
214
|
+
#source_accessor_storage = (__runInitializers(this, _body_extraInitializers), __runInitializers(this, _source_initializers, ""));
|
|
215
|
+
/** Source platform label (e.g. "X", "Bluesky", "Telegram"). */
|
|
216
|
+
get source() { return this.#source_accessor_storage; }
|
|
217
|
+
set source(value) { this.#source_accessor_storage = value; }
|
|
218
|
+
#onSlotChange(e) {
|
|
219
|
+
const slot = e.target;
|
|
220
|
+
slot.parentElement.hidden = slot.assignedElements().length === 0;
|
|
221
|
+
}
|
|
222
|
+
render() {
|
|
223
|
+
return html `
|
|
224
|
+
<article part="article">
|
|
225
|
+
<div class="avatar-slot" hidden>
|
|
226
|
+
<slot name="avatar" @slotchange=${this.#onSlotChange}></slot>
|
|
227
|
+
</div>
|
|
228
|
+
|
|
229
|
+
<div class="main">
|
|
230
|
+
<header part="header">
|
|
231
|
+
<div class="header-left">
|
|
232
|
+
${this.author
|
|
233
|
+
? html `<span class="author">${this.author}</span>`
|
|
234
|
+
: nothing}
|
|
235
|
+
${this.handle
|
|
236
|
+
? html `<span class="handle">${this.handle}</span>`
|
|
237
|
+
: nothing}
|
|
238
|
+
${(this.author || this.handle) && this.timestamp
|
|
239
|
+
? html `<span class="separator">·</span>`
|
|
240
|
+
: nothing}
|
|
241
|
+
${this.timestamp
|
|
242
|
+
? html `<time class="timestamp" part="timestamp">${this.timestamp}</time>`
|
|
243
|
+
: nothing}
|
|
244
|
+
</div>
|
|
245
|
+
${this.source
|
|
246
|
+
? html `<dui-badge variant="neutral" appearance="soft">${this.source}</dui-badge>`
|
|
247
|
+
: nothing}
|
|
248
|
+
</header>
|
|
249
|
+
|
|
250
|
+
${this.body
|
|
251
|
+
? html `<p class="body" part="body">${this.body}</p>`
|
|
252
|
+
: nothing}
|
|
253
|
+
|
|
254
|
+
<div class="actions" hidden>
|
|
255
|
+
<slot name="actions" @slotchange=${this.#onSlotChange}></slot>
|
|
256
|
+
</div>
|
|
257
|
+
</div>
|
|
258
|
+
</article>
|
|
259
|
+
`;
|
|
260
|
+
}
|
|
261
|
+
constructor() {
|
|
262
|
+
super(...arguments);
|
|
263
|
+
__runInitializers(this, _source_extraInitializers);
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
})();
|
|
267
|
+
export { DuiSocialPost };
|
|
268
|
+
customElements.define(DuiSocialPost.tagName, DuiSocialPost);
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/avatar";
|
|
3
|
+
import "@deepfuture/dui-components/scroll-area";
|
|
4
|
+
/** A single avatar entry in the row. */
|
|
5
|
+
export interface AvatarItem {
|
|
6
|
+
/** Image URL for the avatar. */
|
|
7
|
+
src?: string;
|
|
8
|
+
/** Display name — used for alt text and fallback initials. */
|
|
9
|
+
name: string;
|
|
10
|
+
/** Optional label beneath the avatar (defaults to name). */
|
|
11
|
+
label?: string;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* `<dui-avatar-row>` — A horizontal scrollable row of circular avatars with labels.
|
|
15
|
+
*
|
|
16
|
+
* Ideal for displaying teams, participants, agents, or any list of people/entities
|
|
17
|
+
* in a compact horizontal strip. Scrolls horizontally when items overflow.
|
|
18
|
+
*
|
|
19
|
+
* @slot actions - Optional trailing action (e.g. an "Add" button).
|
|
20
|
+
* @csspart row - The flex container holding avatar items.
|
|
21
|
+
*/
|
|
22
|
+
export declare class DuiAvatarRow extends LitElement {
|
|
23
|
+
#private;
|
|
24
|
+
static tagName: "dui-avatar-row";
|
|
25
|
+
static styles: import("lit").CSSResult[];
|
|
26
|
+
/** Array of avatar items to display. */
|
|
27
|
+
accessor data: AvatarItem[];
|
|
28
|
+
/** Text shown when data is empty. */
|
|
29
|
+
accessor emptyText: string;
|
|
30
|
+
render(): TemplateResult;
|
|
31
|
+
}
|