@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
package/README.md
ADDED
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# DUI
|
|
2
|
+
|
|
3
|
+
[](LICENSE)
|
|
4
|
+
[](https://www.npmjs.com/package/@deepfuture/dui-components)
|
|
5
|
+
|
|
6
|
+
Styled [Lit](https://lit.dev) web component library built on [dui-primitives](https://github.com/deepfuturenow/dui-primitives).
|
|
7
|
+
|
|
8
|
+
DUI extends unstyled, accessible primitive components with a complete design system — design tokens, variant systems, and aesthetic CSS. Import a component and it's ready to use. No setup, no configuration.
|
|
9
|
+
|
|
10
|
+
**[Live Docs & Demos →](https://deepfuturenow.github.io/dui/)**
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
**npm / pnpm / yarn:**
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
npm install @deepfuture/dui-components
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
**CDN (zero setup):**
|
|
21
|
+
|
|
22
|
+
```html
|
|
23
|
+
<script type="module" src="https://cdn.jsdelivr.net/npm/@deepfuture/dui-cdn/dui.min.js"></script>
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Quick Start
|
|
27
|
+
|
|
28
|
+
Import the components you need — they self-register on import:
|
|
29
|
+
|
|
30
|
+
```typescript
|
|
31
|
+
import "@deepfuture/dui-components/button";
|
|
32
|
+
import "@deepfuture/dui-components/dialog";
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
```html
|
|
36
|
+
<dui-dialog>
|
|
37
|
+
<dui-dialog-trigger>
|
|
38
|
+
<dui-button>Open Dialog</dui-button>
|
|
39
|
+
</dui-dialog-trigger>
|
|
40
|
+
<dui-dialog-popup>
|
|
41
|
+
<h2>Hello</h2>
|
|
42
|
+
<p>This is a dialog.</p>
|
|
43
|
+
<dui-dialog-close>
|
|
44
|
+
<dui-button appearance="outline">Close</dui-button>
|
|
45
|
+
</dui-dialog-close>
|
|
46
|
+
</dui-dialog-popup>
|
|
47
|
+
</dui-dialog>
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Or register everything at once:
|
|
51
|
+
|
|
52
|
+
```typescript
|
|
53
|
+
import "@deepfuture/dui-components";
|
|
54
|
+
```
|
|
55
|
+
|
|
56
|
+
## How It Works
|
|
57
|
+
|
|
58
|
+
DUI uses a two-layer inheritance model:
|
|
59
|
+
|
|
60
|
+
1. **Primitives** (`@dui/primitives`) — unstyled base classes with accessibility, keyboard behavior, and ARIA built in
|
|
61
|
+
2. **Components** (`@dui/components`) — extend primitives with design tokens, variant systems, and aesthetic CSS
|
|
62
|
+
|
|
63
|
+
Each component self-registers via `customElements.define()` when imported. Design tokens are automatically injected into `document.adoptedStyleSheets` on first import.
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
DuiButtonPrimitive (structure, ARIA, keyboard)
|
|
67
|
+
↓ extends
|
|
68
|
+
DuiButton (tokens, variants, aesthetic CSS, customElements.define())
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
No build step, no setup function, no configuration — just import and use.
|
|
72
|
+
|
|
73
|
+
## Components
|
|
74
|
+
|
|
75
|
+
43 component families, 85+ elements total.
|
|
76
|
+
|
|
77
|
+
| Category | Components |
|
|
78
|
+
|----------|-----------|
|
|
79
|
+
| **Actions** | Button, Toggle, Toggle Group, Toolbar, Split Button |
|
|
80
|
+
| **Forms** | Input, Textarea, Select, Combobox, Checkbox, Radio, Switch, Slider, Number Field, Dropzone, Field, Fieldset |
|
|
81
|
+
| **Data Display** | Badge, Avatar, Calendar, Data Table, Progress, Spinner, Separator, Trunc |
|
|
82
|
+
| **Overlays** | Dialog, Alert Dialog, Popover, Tooltip, Menu, Menubar, Preview Card, Command |
|
|
83
|
+
| **Disclosure** | Accordion, Collapsible, Tabs |
|
|
84
|
+
| **Navigation** | Breadcrumb, Sidebar (with 12 sub-components), Stepper |
|
|
85
|
+
| **Layout** | Card, Card Grid, Scroll Area, Portal |
|
|
86
|
+
| **Utility** | Icon |
|
|
87
|
+
|
|
88
|
+
## Styling
|
|
89
|
+
|
|
90
|
+
DUI uses a two-layer approach to styling:
|
|
91
|
+
|
|
92
|
+
### CSS Variables — for the variant system
|
|
93
|
+
|
|
94
|
+
Variables control values that variants, sizes, and states toggle:
|
|
95
|
+
|
|
96
|
+
```css
|
|
97
|
+
/* Override variant colors */
|
|
98
|
+
dui-button {
|
|
99
|
+
--button-bg: linear-gradient(135deg, pink, purple);
|
|
100
|
+
--button-radius: var(--radius-full);
|
|
101
|
+
}
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
### `::part(root)` — for everything else
|
|
105
|
+
|
|
106
|
+
Every component exposes a `root` CSS part for full CSS expressiveness:
|
|
107
|
+
|
|
108
|
+
```css
|
|
109
|
+
/* Frosted glass effect */
|
|
110
|
+
dui-dialog-popup::part(root) {
|
|
111
|
+
backdrop-filter: blur(12px);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
/* Custom hover animation */
|
|
115
|
+
dui-button::part(root):hover {
|
|
116
|
+
filter: brightness(1.25);
|
|
117
|
+
transform: translateY(-1px);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/* Glow shadow */
|
|
121
|
+
dui-badge::part(root) {
|
|
122
|
+
box-shadow: 0 0 16px oklch(0.7 0.2 280 / 0.4);
|
|
123
|
+
}
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
No need for the library to anticipate every CSS property — `::part()` gives you direct access.
|
|
127
|
+
|
|
128
|
+
## Dark Mode
|
|
129
|
+
|
|
130
|
+
Toggle dark mode by setting `data-theme="dark"` on the `<html>` element:
|
|
131
|
+
|
|
132
|
+
```html
|
|
133
|
+
<html data-theme="dark">
|
|
134
|
+
<!-- All DUI components render in dark mode -->
|
|
135
|
+
</html>
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
## Templates
|
|
139
|
+
|
|
140
|
+
Pre-composed UI patterns built from DUI components — ready-to-use cards, feed items, and other building blocks. Templates adapt automatically to dark mode and token overrides.
|
|
141
|
+
|
|
142
|
+
```bash
|
|
143
|
+
npm install @deepfuture/dui-templates
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
```typescript
|
|
147
|
+
import "@deepfuture/dui-templates/feed";
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
```html
|
|
151
|
+
<dui-feed-item
|
|
152
|
+
title="Earthquake detected"
|
|
153
|
+
subtitle="USGS Pacific Northwest"
|
|
154
|
+
timestamp="2 min ago"
|
|
155
|
+
category="Seismic"
|
|
156
|
+
severity="high"
|
|
157
|
+
description="Magnitude 4.2 recorded near Portland, OR."
|
|
158
|
+
></dui-feed-item>
|
|
159
|
+
```
|
|
160
|
+
|
|
161
|
+
Templates self-register on import, just like components.
|
|
162
|
+
|
|
163
|
+
## Packages
|
|
164
|
+
|
|
165
|
+
| Package | Purpose |
|
|
166
|
+
|---------|---------|
|
|
167
|
+
| [`@deepfuture/dui-components`](https://www.npmjs.com/package/@deepfuture/dui-components) | Styled components (extends dui-primitives) |
|
|
168
|
+
| [`@deepfuture/dui-templates`](https://www.npmjs.com/package/@deepfuture/dui-templates) | Pre-composed UI patterns |
|
|
169
|
+
| [`@deepfuture/dui-cdn`](https://www.npmjs.com/package/@deepfuture/dui-cdn) | Pre-bundled CDN build (all deps inlined) |
|
|
170
|
+
| [`@deepfuture/dui-inspector`](https://www.npmjs.com/package/@deepfuture/dui-inspector) | Runtime inspector & mutation API |
|
|
171
|
+
|
|
172
|
+
**Foundation (separate repo):**
|
|
173
|
+
|
|
174
|
+
| Package | Purpose |
|
|
175
|
+
|---------|---------|
|
|
176
|
+
| [`@deepfuture/dui-core`](https://www.npmjs.com/package/@deepfuture/dui-core) | Base reset, event factory, floating UI utilities |
|
|
177
|
+
| [`@deepfuture/dui-primitives`](https://www.npmjs.com/package/@deepfuture/dui-primitives) | Unstyled accessible component classes |
|
|
178
|
+
|
|
179
|
+
## Dev Tools
|
|
180
|
+
|
|
181
|
+
### Theme Editor
|
|
182
|
+
|
|
183
|
+
A visual editor for design tokens. Edit colors with OKLCH sliders, tweak spacing and typography, and export your customized `tokens.css`.
|
|
184
|
+
|
|
185
|
+
### Inspector
|
|
186
|
+
|
|
187
|
+
A runtime inspector and mutation API for DUI components ([separate package](https://github.com/deepfuturenow/dui-inspector)). Two interfaces:
|
|
188
|
+
|
|
189
|
+
- **Visual UI** (Ctrl+Shift+I) — hover-highlight components, inspect properties/tokens/styles, edit theme CSS and design tokens live
|
|
190
|
+
- **Console API** — `window.__dui_inspect()`, `window.__dui_mutate.*`, `window.__dui_export()` for programmatic access by agents or scripts
|
|
191
|
+
|
|
192
|
+
## Documentation
|
|
193
|
+
|
|
194
|
+
- **[Live Docs](https://deepfuturenow.github.io/dui/)** — interactive demos for every component
|
|
195
|
+
- [Architecture](docs/architecture.md) — two-layer inheritance model, package responsibilities
|
|
196
|
+
- [Creating Components](docs/creating-components.md) — extending primitives into styled components
|
|
197
|
+
- [Creating Templates](docs/creating-templates.md) — building pre-composed UI patterns
|
|
198
|
+
- [Theming](docs/theming.md) — color system, design tokens, variant CSS
|
|
199
|
+
- [Styling](docs/styling.md) — customizing components with variables and `::part()`
|
|
200
|
+
- [Consuming](docs/consuming.md) — integrating DUI into an app
|
|
201
|
+
|
|
202
|
+
## Building Your Own Component Set
|
|
203
|
+
|
|
204
|
+
DUI itself is an example of extending [dui-primitives](https://github.com/deepfuturenow/dui-primitives). You can build your own styled component library the same way:
|
|
205
|
+
|
|
206
|
+
1. Install `@deepfuture/dui-core` + `@deepfuture/dui-primitives`
|
|
207
|
+
2. Extend primitives with your own aesthetic CSS
|
|
208
|
+
3. Call `customElements.define()` to self-register
|
|
209
|
+
|
|
210
|
+
See [Creating Components](docs/creating-components.md) for the full pattern.
|
|
211
|
+
|
|
212
|
+
## License
|
|
213
|
+
|
|
214
|
+
[MIT](LICENSE)
|
package/all.d.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export { DuiFeedItem, DuiActivityItem, DuiSocialPost, DuiHeadlineItem } from "./feed/index.js";
|
|
2
|
+
export { DuiSectionPanel, DuiPageHeader } from "./dashboard/index.js";
|
|
3
|
+
export { DuiStatCard, DuiScoreItem, DuiRiskGauge, DuiProgressBar } from "./metrics/index.js";
|
|
4
|
+
export { DuiKeyValue, DuiMarketTable } from "./data/index.js";
|
|
5
|
+
export type { MarketRow } from "./data/index.js";
|
|
6
|
+
export { DuiBriefingBlock, DuiEmptyState, DuiNumberedInsight } from "./content/index.js";
|
|
7
|
+
export { DuiAvatarRow, DuiMediaGrid } from "./media/index.js";
|
|
8
|
+
export type { AvatarItem } from "./media/index.js";
|
|
9
|
+
export type { MediaItem } from "./media/index.js";
|
|
10
|
+
export declare const allTemplates: (typeof import("./all.js").DuiFeedItem | typeof import("./all.js").DuiActivityItem | typeof import("./all.js").DuiSocialPost | typeof import("./all.js").DuiHeadlineItem | typeof import("./all.js").DuiSectionPanel | typeof import("./all.js").DuiPageHeader | typeof import("./all.js").DuiStatCard | typeof import("./all.js").DuiScoreItem | typeof import("./all.js").DuiRiskGauge | typeof import("./all.js").DuiProgressBar | typeof import("./all.js").DuiKeyValue | typeof import("./all.js").DuiMarketTable | typeof import("./all.js").DuiBriefingBlock | typeof import("./all.js").DuiEmptyState | typeof import("./all.js").DuiNumberedInsight | typeof import("./all.js").DuiAvatarRow | typeof import("./all.js").DuiMediaGrid)[];
|
package/all.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { feedFamily } from "./feed/index.js";
|
|
2
|
+
import { dashboardFamily } from "./dashboard/index.js";
|
|
3
|
+
import { metricsFamily } from "./metrics/index.js";
|
|
4
|
+
import { dataFamily } from "./data/index.js";
|
|
5
|
+
import { contentFamily } from "./content/index.js";
|
|
6
|
+
import { mediaFamily } from "./media/index.js";
|
|
7
|
+
export { DuiFeedItem, DuiActivityItem, DuiSocialPost, DuiHeadlineItem } from "./feed/index.js";
|
|
8
|
+
export { DuiSectionPanel, DuiPageHeader } from "./dashboard/index.js";
|
|
9
|
+
export { DuiStatCard, DuiScoreItem, DuiRiskGauge, DuiProgressBar } from "./metrics/index.js";
|
|
10
|
+
export { DuiKeyValue, DuiMarketTable } from "./data/index.js";
|
|
11
|
+
export { DuiBriefingBlock, DuiEmptyState, DuiNumberedInsight } from "./content/index.js";
|
|
12
|
+
export { DuiAvatarRow, DuiMediaGrid } from "./media/index.js";
|
|
13
|
+
export const allTemplates = [
|
|
14
|
+
...feedFamily,
|
|
15
|
+
...dashboardFamily,
|
|
16
|
+
...metricsFamily,
|
|
17
|
+
...dataFamily,
|
|
18
|
+
...contentFamily,
|
|
19
|
+
...mediaFamily,
|
|
20
|
+
];
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/badge";
|
|
3
|
+
import "@deepfuture/dui-components/separator";
|
|
4
|
+
import "@deepfuture/dui-components/icon";
|
|
5
|
+
/**
|
|
6
|
+
* `<dui-briefing-block>` — An AI-generated summary block with header, metadata, and body.
|
|
7
|
+
*
|
|
8
|
+
* Use for intelligence briefings, AI summaries, analysis blocks, or any authored
|
|
9
|
+
* content that benefits from clear attribution and source metadata.
|
|
10
|
+
*
|
|
11
|
+
* @slot body - Rich body content (overrides body prop).
|
|
12
|
+
* @slot actions - Optional action buttons or links below the body.
|
|
13
|
+
* @csspart article - The outer container.
|
|
14
|
+
* @csspart header - The icon + title + meta region.
|
|
15
|
+
* @csspart title - The title text.
|
|
16
|
+
* @csspart meta - The metadata row (source, timestamp).
|
|
17
|
+
* @csspart body - The body text.
|
|
18
|
+
*/
|
|
19
|
+
export declare class DuiBriefingBlock extends LitElement {
|
|
20
|
+
#private;
|
|
21
|
+
static tagName: "dui-briefing-block";
|
|
22
|
+
static styles: import("lit").CSSResult[];
|
|
23
|
+
/** Primary title for the briefing. */
|
|
24
|
+
accessor title: string;
|
|
25
|
+
/** Source or author attribution (e.g. "AI Analysis", "GPT-4o"). */
|
|
26
|
+
accessor source: string;
|
|
27
|
+
/** Display timestamp (e.g. "2 min ago", "14:23 UTC"). */
|
|
28
|
+
accessor timestamp: string;
|
|
29
|
+
/** Category or topic label — renders as a neutral badge. */
|
|
30
|
+
accessor category: string;
|
|
31
|
+
/** Confidence level label — renders as a badge (e.g. "High", "Medium"). */
|
|
32
|
+
accessor confidence: string;
|
|
33
|
+
/** Body text content. */
|
|
34
|
+
accessor body: string;
|
|
35
|
+
render(): TemplateResult;
|
|
36
|
+
}
|
|
@@ -0,0 +1,281 @@
|
|
|
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/badge";
|
|
39
|
+
import "@deepfuture/dui-components/separator";
|
|
40
|
+
import "@deepfuture/dui-components/icon";
|
|
41
|
+
const styles = css `
|
|
42
|
+
:host {
|
|
43
|
+
display: block;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
article {
|
|
47
|
+
display: flex;
|
|
48
|
+
flex-direction: column;
|
|
49
|
+
gap: var(--space-3);
|
|
50
|
+
padding: var(--space-4);
|
|
51
|
+
border: var(--border-width-thin) solid var(--border);
|
|
52
|
+
border-radius: var(--radius-md);
|
|
53
|
+
background: var(--surface-1);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
header {
|
|
57
|
+
display: flex;
|
|
58
|
+
align-items: flex-start;
|
|
59
|
+
gap: var(--space-2_5);
|
|
60
|
+
min-width: 0;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
.header-icon {
|
|
64
|
+
flex-shrink: 0;
|
|
65
|
+
--icon-size: 1rem;
|
|
66
|
+
--icon-color: var(--accent-text);
|
|
67
|
+
margin-top: var(--space-0_5);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
.header-content {
|
|
71
|
+
display: flex;
|
|
72
|
+
flex-direction: column;
|
|
73
|
+
gap: var(--space-0_5);
|
|
74
|
+
flex: 1;
|
|
75
|
+
min-width: 0;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.title-row {
|
|
79
|
+
display: flex;
|
|
80
|
+
align-items: center;
|
|
81
|
+
gap: var(--space-2);
|
|
82
|
+
min-width: 0;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
.title {
|
|
86
|
+
font-family: var(--font-sans);
|
|
87
|
+
font-size: var(--text-sm);
|
|
88
|
+
font-weight: var(--font-weight-semibold);
|
|
89
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
90
|
+
line-height: var(--line-height-snug);
|
|
91
|
+
color: var(--foreground);
|
|
92
|
+
flex: 1;
|
|
93
|
+
min-width: 0;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
.badges {
|
|
97
|
+
display: flex;
|
|
98
|
+
align-items: center;
|
|
99
|
+
gap: var(--space-1_5);
|
|
100
|
+
flex-shrink: 0;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
.meta {
|
|
104
|
+
display: flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: var(--space-1);
|
|
107
|
+
font-family: var(--font-sans);
|
|
108
|
+
font-size: var(--text-xs);
|
|
109
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
110
|
+
line-height: var(--line-height-normal);
|
|
111
|
+
color: var(--text-3);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
.meta-separator {
|
|
115
|
+
color: var(--text-3);
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
.body {
|
|
119
|
+
font-family: var(--font-sans);
|
|
120
|
+
font-size: var(--text-sm);
|
|
121
|
+
letter-spacing: var(--letter-spacing-wide);
|
|
122
|
+
line-height: var(--line-height-relaxed);
|
|
123
|
+
color: var(--text-1);
|
|
124
|
+
margin: 0;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
.actions {
|
|
128
|
+
display: flex;
|
|
129
|
+
align-items: center;
|
|
130
|
+
gap: var(--space-2);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
.actions[hidden] {
|
|
134
|
+
display: none;
|
|
135
|
+
}
|
|
136
|
+
`;
|
|
137
|
+
/**
|
|
138
|
+
* `<dui-briefing-block>` — An AI-generated summary block with header, metadata, and body.
|
|
139
|
+
*
|
|
140
|
+
* Use for intelligence briefings, AI summaries, analysis blocks, or any authored
|
|
141
|
+
* content that benefits from clear attribution and source metadata.
|
|
142
|
+
*
|
|
143
|
+
* @slot body - Rich body content (overrides body prop).
|
|
144
|
+
* @slot actions - Optional action buttons or links below the body.
|
|
145
|
+
* @csspart article - The outer container.
|
|
146
|
+
* @csspart header - The icon + title + meta region.
|
|
147
|
+
* @csspart title - The title text.
|
|
148
|
+
* @csspart meta - The metadata row (source, timestamp).
|
|
149
|
+
* @csspart body - The body text.
|
|
150
|
+
*/
|
|
151
|
+
let DuiBriefingBlock = (() => {
|
|
152
|
+
let _classSuper = LitElement;
|
|
153
|
+
let _title_decorators;
|
|
154
|
+
let _title_initializers = [];
|
|
155
|
+
let _title_extraInitializers = [];
|
|
156
|
+
let _source_decorators;
|
|
157
|
+
let _source_initializers = [];
|
|
158
|
+
let _source_extraInitializers = [];
|
|
159
|
+
let _timestamp_decorators;
|
|
160
|
+
let _timestamp_initializers = [];
|
|
161
|
+
let _timestamp_extraInitializers = [];
|
|
162
|
+
let _category_decorators;
|
|
163
|
+
let _category_initializers = [];
|
|
164
|
+
let _category_extraInitializers = [];
|
|
165
|
+
let _confidence_decorators;
|
|
166
|
+
let _confidence_initializers = [];
|
|
167
|
+
let _confidence_extraInitializers = [];
|
|
168
|
+
let _body_decorators;
|
|
169
|
+
let _body_initializers = [];
|
|
170
|
+
let _body_extraInitializers = [];
|
|
171
|
+
return class DuiBriefingBlock extends _classSuper {
|
|
172
|
+
static {
|
|
173
|
+
const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
|
|
174
|
+
_title_decorators = [property()];
|
|
175
|
+
_source_decorators = [property()];
|
|
176
|
+
_timestamp_decorators = [property()];
|
|
177
|
+
_category_decorators = [property()];
|
|
178
|
+
_confidence_decorators = [property()];
|
|
179
|
+
_body_decorators = [property()];
|
|
180
|
+
__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);
|
|
181
|
+
__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);
|
|
182
|
+
__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);
|
|
183
|
+
__esDecorate(this, null, _category_decorators, { kind: "accessor", name: "category", static: false, private: false, access: { has: obj => "category" in obj, get: obj => obj.category, set: (obj, value) => { obj.category = value; } }, metadata: _metadata }, _category_initializers, _category_extraInitializers);
|
|
184
|
+
__esDecorate(this, null, _confidence_decorators, { kind: "accessor", name: "confidence", static: false, private: false, access: { has: obj => "confidence" in obj, get: obj => obj.confidence, set: (obj, value) => { obj.confidence = value; } }, metadata: _metadata }, _confidence_initializers, _confidence_extraInitializers);
|
|
185
|
+
__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);
|
|
186
|
+
if (_metadata) Object.defineProperty(this, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
|
|
187
|
+
}
|
|
188
|
+
static tagName = "dui-briefing-block";
|
|
189
|
+
static styles = [base, styles];
|
|
190
|
+
#title_accessor_storage = __runInitializers(this, _title_initializers, "");
|
|
191
|
+
/** Primary title for the briefing. */
|
|
192
|
+
get title() { return this.#title_accessor_storage; }
|
|
193
|
+
set title(value) { this.#title_accessor_storage = value; }
|
|
194
|
+
#source_accessor_storage = (__runInitializers(this, _title_extraInitializers), __runInitializers(this, _source_initializers, ""));
|
|
195
|
+
/** Source or author attribution (e.g. "AI Analysis", "GPT-4o"). */
|
|
196
|
+
get source() { return this.#source_accessor_storage; }
|
|
197
|
+
set source(value) { this.#source_accessor_storage = value; }
|
|
198
|
+
#timestamp_accessor_storage = (__runInitializers(this, _source_extraInitializers), __runInitializers(this, _timestamp_initializers, ""));
|
|
199
|
+
/** Display timestamp (e.g. "2 min ago", "14:23 UTC"). */
|
|
200
|
+
get timestamp() { return this.#timestamp_accessor_storage; }
|
|
201
|
+
set timestamp(value) { this.#timestamp_accessor_storage = value; }
|
|
202
|
+
#category_accessor_storage = (__runInitializers(this, _timestamp_extraInitializers), __runInitializers(this, _category_initializers, ""));
|
|
203
|
+
/** Category or topic label — renders as a neutral badge. */
|
|
204
|
+
get category() { return this.#category_accessor_storage; }
|
|
205
|
+
set category(value) { this.#category_accessor_storage = value; }
|
|
206
|
+
#confidence_accessor_storage = (__runInitializers(this, _category_extraInitializers), __runInitializers(this, _confidence_initializers, ""));
|
|
207
|
+
/** Confidence level label — renders as a badge (e.g. "High", "Medium"). */
|
|
208
|
+
get confidence() { return this.#confidence_accessor_storage; }
|
|
209
|
+
set confidence(value) { this.#confidence_accessor_storage = value; }
|
|
210
|
+
#body_accessor_storage = (__runInitializers(this, _confidence_extraInitializers), __runInitializers(this, _body_initializers, ""));
|
|
211
|
+
/** Body text content. */
|
|
212
|
+
get body() { return this.#body_accessor_storage; }
|
|
213
|
+
set body(value) { this.#body_accessor_storage = value; }
|
|
214
|
+
/** Toggle hidden on slot wrapper when slotted content changes. */
|
|
215
|
+
#onSlotChange(e) {
|
|
216
|
+
const slot = e.target;
|
|
217
|
+
slot.parentElement.hidden = slot.assignedElements().length === 0;
|
|
218
|
+
}
|
|
219
|
+
render() {
|
|
220
|
+
const hasIcon = true; // always show the sparkle icon for AI content
|
|
221
|
+
const hasMeta = this.source || this.timestamp;
|
|
222
|
+
return html `
|
|
223
|
+
<article part="article">
|
|
224
|
+
<header part="header">
|
|
225
|
+
${hasIcon
|
|
226
|
+
? html `<dui-icon class="header-icon">
|
|
227
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round">
|
|
228
|
+
<path d="M9.937 15.5A2 2 0 0 0 8.5 14.063l-6.135-1.582a.5.5 0 0 1 0-.962L8.5 9.936A2 2 0 0 0 9.937 8.5l1.582-6.135a.5.5 0 0 1 .963 0L14.063 8.5A2 2 0 0 0 15.5 9.937l6.135 1.581a.5.5 0 0 1 0 .964L15.5 14.063a2 2 0 0 0-1.437 1.437l-1.582 6.135a.5.5 0 0 1-.963 0z"/>
|
|
229
|
+
<path d="M20 3v4"/>
|
|
230
|
+
<path d="M22 5h-4"/>
|
|
231
|
+
</svg>
|
|
232
|
+
</dui-icon>`
|
|
233
|
+
: nothing}
|
|
234
|
+
<div class="header-content">
|
|
235
|
+
<div class="title-row">
|
|
236
|
+
<span class="title" part="title">${this.title}</span>
|
|
237
|
+
<div class="badges">
|
|
238
|
+
${this.category
|
|
239
|
+
? html `<dui-badge appearance="soft">${this.category}</dui-badge>`
|
|
240
|
+
: nothing}
|
|
241
|
+
${this.confidence
|
|
242
|
+
? html `<dui-badge variant="primary" appearance="soft">${this.confidence}</dui-badge>`
|
|
243
|
+
: nothing}
|
|
244
|
+
</div>
|
|
245
|
+
</div>
|
|
246
|
+
${hasMeta
|
|
247
|
+
? html `<div class="meta" part="meta">
|
|
248
|
+
${this.source ? html `<span>${this.source}</span>` : nothing}
|
|
249
|
+
${this.source && this.timestamp
|
|
250
|
+
? html `<span class="meta-separator">·</span>`
|
|
251
|
+
: nothing}
|
|
252
|
+
${this.timestamp
|
|
253
|
+
? html `<time>${this.timestamp}</time>`
|
|
254
|
+
: nothing}
|
|
255
|
+
</div>`
|
|
256
|
+
: nothing}
|
|
257
|
+
</div>
|
|
258
|
+
</header>
|
|
259
|
+
|
|
260
|
+
${this.body
|
|
261
|
+
? html `
|
|
262
|
+
<dui-separator></dui-separator>
|
|
263
|
+
<p class="body" part="body">
|
|
264
|
+
<slot name="body">${this.body}</slot>
|
|
265
|
+
</p>`
|
|
266
|
+
: html `<slot name="body"></slot>`}
|
|
267
|
+
|
|
268
|
+
<div class="actions" hidden>
|
|
269
|
+
<slot name="actions" @slotchange=${this.#onSlotChange}></slot>
|
|
270
|
+
</div>
|
|
271
|
+
</article>
|
|
272
|
+
`;
|
|
273
|
+
}
|
|
274
|
+
constructor() {
|
|
275
|
+
super(...arguments);
|
|
276
|
+
__runInitializers(this, _body_extraInitializers);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
})();
|
|
280
|
+
export { DuiBriefingBlock };
|
|
281
|
+
customElements.define(DuiBriefingBlock.tagName, DuiBriefingBlock);
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { LitElement, type TemplateResult } from "lit";
|
|
2
|
+
import "@deepfuture/dui-components/icon";
|
|
3
|
+
/**
|
|
4
|
+
* `<dui-empty-state>` — A centered placeholder for no-data panels.
|
|
5
|
+
*
|
|
6
|
+
* Use inside section panels, tables, or lists when there's nothing to display.
|
|
7
|
+
* Shows an optional icon, heading, description, and action slot for a primary CTA.
|
|
8
|
+
*
|
|
9
|
+
* @slot icon - Custom icon content (overrides the default empty-box icon).
|
|
10
|
+
* @slot actions - Primary call-to-action button(s).
|
|
11
|
+
* @csspart container - The outer centered container.
|
|
12
|
+
* @csspart heading - The heading text.
|
|
13
|
+
* @csspart description - The description text.
|
|
14
|
+
*/
|
|
15
|
+
export declare class DuiEmptyState extends LitElement {
|
|
16
|
+
#private;
|
|
17
|
+
static tagName: "dui-empty-state";
|
|
18
|
+
static styles: import("lit").CSSResult[];
|
|
19
|
+
/** Primary heading text (e.g. "No events yet"). */
|
|
20
|
+
accessor heading: string;
|
|
21
|
+
/** Supporting description text. */
|
|
22
|
+
accessor description: string;
|
|
23
|
+
render(): TemplateResult;
|
|
24
|
+
}
|