@xmesh/system-design 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +472 -0
  2. package/assets/brand-lockup-dark.svg +9 -0
  3. package/assets/brand-lockup-light.svg +9 -0
  4. package/assets/brand-mark.svg +9 -0
  5. package/colors_and_type.css +11 -0
  6. package/dist/lit/components/alert/index.css +201 -0
  7. package/dist/lit/components/alert/index.d.ts +25 -0
  8. package/dist/lit/components/alert/index.js +191 -0
  9. package/dist/lit/components/app-bar/index.css +80 -0
  10. package/dist/lit/components/app-bar/index.d.ts +19 -0
  11. package/dist/lit/components/app-bar/index.js +120 -0
  12. package/dist/lit/components/artifact/index.css +166 -0
  13. package/dist/lit/components/artifact/index.d.ts +37 -0
  14. package/dist/lit/components/artifact/index.js +294 -0
  15. package/dist/lit/components/autocomplete/index.css +171 -0
  16. package/dist/lit/components/autocomplete/index.d.ts +47 -0
  17. package/dist/lit/components/autocomplete/index.js +404 -0
  18. package/dist/lit/components/avatar/index.css +62 -0
  19. package/dist/lit/components/avatar/index.d.ts +19 -0
  20. package/dist/lit/components/avatar/index.js +112 -0
  21. package/dist/lit/components/avatar-group/index.css +60 -0
  22. package/dist/lit/components/avatar-group/index.d.ts +19 -0
  23. package/dist/lit/components/avatar-group/index.js +97 -0
  24. package/dist/lit/components/badge/index.css +72 -0
  25. package/dist/lit/components/badge/index.d.ts +18 -0
  26. package/dist/lit/components/badge/index.js +115 -0
  27. package/dist/lit/components/brand-mark/index.css +109 -0
  28. package/dist/lit/components/brand-mark/index.d.ts +24 -0
  29. package/dist/lit/components/brand-mark/index.js +116 -0
  30. package/dist/lit/components/breadcrumbs/index.css +91 -0
  31. package/dist/lit/components/breadcrumbs/index.d.ts +19 -0
  32. package/dist/lit/components/breadcrumbs/index.js +104 -0
  33. package/dist/lit/components/bubble/index.css +182 -0
  34. package/dist/lit/components/bubble/index.d.ts +72 -0
  35. package/dist/lit/components/bubble/index.js +617 -0
  36. package/dist/lit/components/button/index.css +342 -0
  37. package/dist/lit/components/button/index.d.ts +32 -0
  38. package/dist/lit/components/button/index.js +202 -0
  39. package/dist/lit/components/card/index.css +99 -0
  40. package/dist/lit/components/card/index.d.ts +20 -0
  41. package/dist/lit/components/card/index.js +133 -0
  42. package/dist/lit/components/chat/index.css +292 -0
  43. package/dist/lit/components/chat/index.d.ts +74 -0
  44. package/dist/lit/components/chat/index.js +589 -0
  45. package/dist/lit/components/checkbox/index.css +126 -0
  46. package/dist/lit/components/checkbox/index.d.ts +21 -0
  47. package/dist/lit/components/checkbox/index.js +138 -0
  48. package/dist/lit/components/chip/index.css +145 -0
  49. package/dist/lit/components/chip/index.d.ts +30 -0
  50. package/dist/lit/components/chip/index.js +230 -0
  51. package/dist/lit/components/chip-group/index.css +19 -0
  52. package/dist/lit/components/chip-group/index.d.ts +24 -0
  53. package/dist/lit/components/chip-group/index.js +171 -0
  54. package/dist/lit/components/code/index.css +42 -0
  55. package/dist/lit/components/code/index.d.ts +12 -0
  56. package/dist/lit/components/code/index.js +68 -0
  57. package/dist/lit/components/composer/index.css +548 -0
  58. package/dist/lit/components/composer/index.d.ts +67 -0
  59. package/dist/lit/components/composer/index.js +713 -0
  60. package/dist/lit/components/data-table/index.css +166 -0
  61. package/dist/lit/components/data-table/index.d.ts +55 -0
  62. package/dist/lit/components/data-table/index.js +390 -0
  63. package/dist/lit/components/dialog/index.css +124 -0
  64. package/dist/lit/components/dialog/index.d.ts +24 -0
  65. package/dist/lit/components/dialog/index.js +199 -0
  66. package/dist/lit/components/divider/index.css +27 -0
  67. package/dist/lit/components/divider/index.d.ts +13 -0
  68. package/dist/lit/components/divider/index.js +67 -0
  69. package/dist/lit/components/empty-state/index.css +69 -0
  70. package/dist/lit/components/empty-state/index.d.ts +21 -0
  71. package/dist/lit/components/empty-state/index.js +123 -0
  72. package/dist/lit/components/expansion-panel/index.css +120 -0
  73. package/dist/lit/components/expansion-panel/index.d.ts +22 -0
  74. package/dist/lit/components/expansion-panel/index.js +174 -0
  75. package/dist/lit/components/field/index.css +223 -0
  76. package/dist/lit/components/field/index.d.ts +106 -0
  77. package/dist/lit/components/field/index.js +388 -0
  78. package/dist/lit/components/file-input/index.css +257 -0
  79. package/dist/lit/components/file-input/index.d.ts +30 -0
  80. package/dist/lit/components/file-input/index.js +298 -0
  81. package/dist/lit/components/form/index.css +29 -0
  82. package/dist/lit/components/form/index.d.ts +38 -0
  83. package/dist/lit/components/form/index.js +192 -0
  84. package/dist/lit/components/grid/index.css +53 -0
  85. package/dist/lit/components/grid/index.d.ts +14 -0
  86. package/dist/lit/components/grid/index.js +82 -0
  87. package/dist/lit/components/kbd/index.css +35 -0
  88. package/dist/lit/components/kbd/index.d.ts +11 -0
  89. package/dist/lit/components/kbd/index.js +43 -0
  90. package/dist/lit/components/list/index.css +15 -0
  91. package/dist/lit/components/list/index.d.ts +28 -0
  92. package/dist/lit/components/list/index.js +188 -0
  93. package/dist/lit/components/list-item/index.css +119 -0
  94. package/dist/lit/components/list-item/index.d.ts +20 -0
  95. package/dist/lit/components/list-item/index.js +127 -0
  96. package/dist/lit/components/menu/index.css +94 -0
  97. package/dist/lit/components/menu/index.d.ts +47 -0
  98. package/dist/lit/components/menu/index.js +386 -0
  99. package/dist/lit/components/navigation-drawer/index.css +114 -0
  100. package/dist/lit/components/navigation-drawer/index.d.ts +29 -0
  101. package/dist/lit/components/navigation-drawer/index.js +218 -0
  102. package/dist/lit/components/overlay/index.css +171 -0
  103. package/dist/lit/components/overlay/index.d.ts +65 -0
  104. package/dist/lit/components/overlay/index.js +566 -0
  105. package/dist/lit/components/pagination/index.css +102 -0
  106. package/dist/lit/components/pagination/index.d.ts +22 -0
  107. package/dist/lit/components/pagination/index.js +184 -0
  108. package/dist/lit/components/primitives/index.css +504 -0
  109. package/dist/lit/components/primitives/index.d.ts +25 -0
  110. package/dist/lit/components/primitives/index.js +283 -0
  111. package/dist/lit/components/progress/index.css +143 -0
  112. package/dist/lit/components/progress/index.d.ts +23 -0
  113. package/dist/lit/components/progress/index.js +180 -0
  114. package/dist/lit/components/radio-group/index.css +178 -0
  115. package/dist/lit/components/radio-group/index.d.ts +35 -0
  116. package/dist/lit/components/radio-group/index.js +292 -0
  117. package/dist/lit/components/select/index.css +151 -0
  118. package/dist/lit/components/select/index.d.ts +50 -0
  119. package/dist/lit/components/select/index.js +390 -0
  120. package/dist/lit/components/sidebar-item/index.css +133 -0
  121. package/dist/lit/components/sidebar-item/index.d.ts +20 -0
  122. package/dist/lit/components/sidebar-item/index.js +105 -0
  123. package/dist/lit/components/skeleton/index.css +81 -0
  124. package/dist/lit/components/skeleton/index.d.ts +19 -0
  125. package/dist/lit/components/skeleton/index.js +119 -0
  126. package/dist/lit/components/slider/index.css +171 -0
  127. package/dist/lit/components/slider/index.d.ts +36 -0
  128. package/dist/lit/components/slider/index.js +302 -0
  129. package/dist/lit/components/snackbar/index.css +279 -0
  130. package/dist/lit/components/snackbar/index.d.ts +33 -0
  131. package/dist/lit/components/snackbar/index.js +195 -0
  132. package/dist/lit/components/stack/index.css +41 -0
  133. package/dist/lit/components/stack/index.d.ts +20 -0
  134. package/dist/lit/components/stack/index.js +103 -0
  135. package/dist/lit/components/switch/index.css +126 -0
  136. package/dist/lit/components/switch/index.d.ts +17 -0
  137. package/dist/lit/components/switch/index.js +116 -0
  138. package/dist/lit/components/table/index.css +85 -0
  139. package/dist/lit/components/table/index.d.ts +25 -0
  140. package/dist/lit/components/table/index.js +139 -0
  141. package/dist/lit/components/tabs/index.css +116 -0
  142. package/dist/lit/components/tabs/index.d.ts +49 -0
  143. package/dist/lit/components/tabs/index.js +320 -0
  144. package/dist/lit/components/text-field/index.css +90 -0
  145. package/dist/lit/components/text-field/index.d.ts +17 -0
  146. package/dist/lit/components/text-field/index.js +101 -0
  147. package/dist/lit/components/textarea/index.css +55 -0
  148. package/dist/lit/components/textarea/index.d.ts +26 -0
  149. package/dist/lit/components/textarea/index.js +124 -0
  150. package/dist/lit/components/tooltip/index.css +37 -0
  151. package/dist/lit/components/tooltip/index.d.ts +31 -0
  152. package/dist/lit/components/tooltip/index.js +196 -0
  153. package/dist/lit/components/validation/index.css +386 -0
  154. package/dist/lit/components/validation/index.d.ts +45 -0
  155. package/dist/lit/components/validation/index.js +318 -0
  156. package/dist/lit/index.d.ts +50 -0
  157. package/dist/lit/index.js +59 -0
  158. package/package.json +81 -0
  159. package/styles/README.md +346 -0
  160. package/styles/_elevation.css +24 -0
  161. package/styles/_fonts.css +6 -0
  162. package/styles/_layout.css +37 -0
  163. package/styles/_primitives.css +154 -0
  164. package/styles/_scroll.css +75 -0
  165. package/styles/_semantic.css +146 -0
  166. package/styles/_space.css +61 -0
  167. package/styles/_type.css +139 -0
  168. package/styles/_xmesh-extensions.css +232 -0
  169. package/styles/index.css +44 -0
  170. package/styles/md3/_color.css +102 -0
  171. package/styles/md3/_elevation.css +26 -0
  172. package/styles/md3/_motion.css +35 -0
  173. package/styles/md3/_shape.css +22 -0
  174. package/styles/md3/_state.css +22 -0
  175. package/styles/md3/_type.css +111 -0
@@ -0,0 +1,91 @@
1
+ /* ============================================
2
+ <xm-breadcrumbs> — location trail.
3
+
4
+ Surface / ink (AD-13): a transparent trail that traces its host surface.
5
+ On the desk family: link ink var(--md-sys-color-on-surface-variant), hover
6
+ var(--md-sys-color-on-surface); the CURRENT (last) item is coral
7
+ var(--md-sys-color-primary) — the page indicator. The divider glyph is a
8
+ muted neutral, never a status hue.
9
+
10
+ BEM: block `breadcrumbs`; elements `__item` `__link` `__current`
11
+ `__separator` `__slash`.
12
+ ============================================ */
13
+
14
+ .breadcrumbs {
15
+ display: flex;
16
+ flex-wrap: wrap;
17
+ align-items: center;
18
+ gap: var(--s-1);
19
+ margin: 0;
20
+ padding: 0;
21
+ list-style: none;
22
+ font-family: var(--md-sys-typescale-body-medium-font);
23
+ font-size: var(--md-sys-typescale-body-medium-size);
24
+ line-height: var(--md-sys-typescale-body-medium-line-height);
25
+ letter-spacing: var(--md-sys-typescale-body-medium-tracking);
26
+ }
27
+
28
+ .breadcrumbs__item {
29
+ display: inline-flex;
30
+ align-items: center;
31
+ gap: var(--s-1);
32
+ min-width: 0;
33
+ }
34
+
35
+ .breadcrumbs__link {
36
+ display: inline-block;
37
+ padding: var(--s-1) var(--s-2);
38
+ border-radius: var(--md-sys-shape-corner-small);
39
+ color: var(--md-sys-color-on-surface-variant);
40
+ text-decoration: none;
41
+ white-space: nowrap;
42
+ transition:
43
+ color var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
44
+ background var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
45
+ }
46
+ .breadcrumbs__link:hover {
47
+ color: var(--md-sys-color-on-surface);
48
+ background: color-mix(
49
+ in oklab,
50
+ var(--md-sys-color-on-surface) var(--md-sys-state-hover-state-layer-opacity),
51
+ transparent
52
+ );
53
+ }
54
+ .breadcrumbs__link:focus {
55
+ outline: none;
56
+ }
57
+ .breadcrumbs__link:focus-visible {
58
+ outline: none;
59
+ color: var(--md-sys-color-on-surface);
60
+ box-shadow: var(--xm-state-focus-ring);
61
+ }
62
+
63
+ .breadcrumbs__current {
64
+ display: inline-block;
65
+ padding: var(--s-1) var(--s-2);
66
+ color: var(--md-sys-color-primary);
67
+ font-weight: 600;
68
+ white-space: nowrap;
69
+ }
70
+
71
+ /* A non-last item with no href: plain, non-interactive text — NOT the coral
72
+ current-page treatment (only the last item is the current page). */
73
+ .breadcrumbs__text {
74
+ display: inline-block;
75
+ padding: var(--s-1) var(--s-2);
76
+ color: var(--md-sys-color-on-surface-variant);
77
+ white-space: nowrap;
78
+ }
79
+
80
+ .breadcrumbs__separator {
81
+ display: inline-flex;
82
+ align-items: center;
83
+ color: var(--md-sys-color-on-surface-variant);
84
+ opacity: 0.7;
85
+ flex-shrink: 0;
86
+ }
87
+
88
+ .breadcrumbs__slash {
89
+ font-size: var(--md-sys-typescale-body-medium-size);
90
+ line-height: 1;
91
+ }
@@ -0,0 +1,19 @@
1
+ import { LitElement } from "lit";
2
+ import type { TemplateResult } from "lit";
3
+ export interface BreadcrumbItem {
4
+ label: string;
5
+ href?: string;
6
+ }
7
+ type BreadcrumbSeparator = "chevron" | "slash";
8
+ declare class XmBreadcrumbs extends LitElement {
9
+ items: BreadcrumbItem[];
10
+ separator: BreadcrumbSeparator;
11
+ render(): TemplateResult;
12
+ private _separatorGlyph;
13
+ }
14
+ declare global {
15
+ interface HTMLElementTagNameMap {
16
+ "xm-breadcrumbs": XmBreadcrumbs;
17
+ }
18
+ }
19
+ export {};
@@ -0,0 +1,104 @@
1
+ /*
2
+ breadcrumbs/index.ts — <xm-breadcrumbs>, the location trail.
3
+
4
+ <xm-breadcrumbs> — a trail of link items separated by a divider glyph,
5
+ wrapped in a labeled nav landmark with an ordered list. The last item is
6
+ the current page: not a link, coral-emphasized, aria-current="page".
7
+
8
+ API — items are supplied via the `items` PROPERTY (canonical):
9
+ el.items = [
10
+ { label: "Workspaces", href: "/workspaces" },
11
+ { label: "Smart routing", href: "/workspaces/smart-routing" },
12
+ { label: "domains.yml" }, // last item = current page (no href)
13
+ ];
14
+
15
+ The last entry is always the current page (its href is ignored). Labels
16
+ render in sentence case; tech identifiers stay caps.
17
+
18
+ Properties:
19
+ items Array<{ label: string; href?: string }>
20
+ separator "chevron" | "slash" (default "chevron")
21
+
22
+ Surface / ink (AD-13): a transparent trail. On the desk family link ink is
23
+ on-surface-variant, hover on-surface, current is coral primary. The divider
24
+ glyph is decorative (aria-hidden) and uses muted neutral ink.
25
+
26
+ Shadow DOM; Lit from lit; sibling CSS + primitives CSS
27
+ via the built-file-relative new URL(...). The chevron is the shared
28
+ primitives line-icon (xm-chevron-right-icon) — never an inlined SVG.
29
+ BEM block `breadcrumbs`.
30
+ */
31
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
32
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
33
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
34
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
35
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
36
+ };
37
+ import { LitElement, html, nothing } from "lit";
38
+ import { customElement, property } from "lit/decorators.js";
39
+ // Resolve CSS relative to the *built* file:
40
+ // lit/build/components/breadcrumbs/index.js → ../...
41
+ const BREADCRUMBS_CSS = new URL("../breadcrumbs/index.css", import.meta.url).href;
42
+ const PRIMITIVES_CSS = new URL("../primitives/index.css", import.meta.url).href;
43
+ let XmBreadcrumbs = class XmBreadcrumbs extends LitElement {
44
+ constructor() {
45
+ super(...arguments);
46
+ this.items = [];
47
+ this.separator = "chevron";
48
+ }
49
+ render() {
50
+ const items = Array.isArray(this.items) ? this.items : [];
51
+ const lastIndex = items.length - 1;
52
+ return html `
53
+ <link rel="stylesheet" href="${PRIMITIVES_CSS}" />
54
+ <link rel="stylesheet" href="${BREADCRUMBS_CSS}" />
55
+ <style>
56
+ :host {
57
+ display: block;
58
+ }
59
+ :host([hidden]) {
60
+ display: none;
61
+ }
62
+ </style>
63
+ <nav aria-label="Breadcrumb">
64
+ <ol class="breadcrumbs">
65
+ ${items.map((item, i) => {
66
+ const isLast = i === lastIndex;
67
+ return html `
68
+ <li class="breadcrumbs__item">
69
+ ${isLast
70
+ ? html `<span class="breadcrumbs__current" aria-current="page"
71
+ >${item.label}</span
72
+ >`
73
+ : item.href
74
+ ? html `<a class="breadcrumbs__link" href="${item.href}"
75
+ >${item.label}</a
76
+ >`
77
+ : html `<span class="breadcrumbs__text">${item.label}</span>`}
78
+ ${isLast
79
+ ? nothing
80
+ : html `<span class="breadcrumbs__separator" aria-hidden="true"
81
+ >${this._separatorGlyph()}</span
82
+ >`}
83
+ </li>
84
+ `;
85
+ })}
86
+ </ol>
87
+ </nav>
88
+ `;
89
+ }
90
+ _separatorGlyph() {
91
+ return this.separator === "slash"
92
+ ? html `<span class="breadcrumbs__slash">/</span>`
93
+ : html `<xm-chevron-right-icon size="14"></xm-chevron-right-icon>`;
94
+ }
95
+ };
96
+ __decorate([
97
+ property({ attribute: false })
98
+ ], XmBreadcrumbs.prototype, "items", void 0);
99
+ __decorate([
100
+ property({ type: String })
101
+ ], XmBreadcrumbs.prototype, "separator", void 0);
102
+ XmBreadcrumbs = __decorate([
103
+ customElement("xm-breadcrumbs")
104
+ ], XmBreadcrumbs);
@@ -0,0 +1,182 @@
1
+ /* ============================================================
2
+ <Bubble /> — chat message vocabulary
3
+
4
+ Three exported components share this stylesheet:
5
+ • .bubble — the message body itself (--user | --bot)
6
+ • .bubble-group — column wrapping bubble + actions, anchored
7
+ left for bot, right for user
8
+ • .bubble-actions — hover-reveal toolbar (timestamp + icons)
9
+
10
+ Pairs with components/bubble/index.jsx. Loaded directly by every preview
11
+ page that renders a chat thread (bubbles.html, chat.html). No tag
12
+ selectors — paragraph, list, strong, code content is wrapped by the
13
+ JSX <BubbleBody> walker into .bubble__paragraph / .bubble__list / etc.
14
+ ============================================================ */
15
+
16
+ /* ---------- Bubble body ---------- */
17
+ .bubble {
18
+ max-width: 640px;
19
+ font:
20
+ var(--md-sys-typescale-body-large-weight)
21
+ var(--md-sys-typescale-body-large-size) /
22
+ var(--md-sys-typescale-body-large-line-height)
23
+ var(--md-sys-typescale-body-large-font);
24
+ }
25
+ /* User bubble shares the composer's raised family (surface-container-high)
26
+ so "your voice" reads as one surface across input and thread.
27
+ surface-container-lowest was ~black in dark and vanished into the desk;
28
+ the high container sits a clear step above `surface` in both themes. */
29
+ .bubble--user {
30
+ padding: 11px var(--s-4-5);
31
+ border-radius: var(--md-sys-shape-corner-large);
32
+ background: var(--md-sys-color-surface-container-high);
33
+ color: var(--md-sys-color-on-surface);
34
+ }
35
+ /* Bot bubble has no surface of its own — it rides whatever's behind it.
36
+ In the xmesh chat the thread sits on `surface` (the warm dark "desk"
37
+ in dark theme, cream in light), so the bot bubble uses on-surface. The
38
+ primitives flip per theme — a single rule covers both. If a host page
39
+ puts the thread on `inverse-surface` (a card) instead, override with
40
+ .bubble--bot { color: var(--md-sys-color-inverse-on-surface) } at the
41
+ page level. */
42
+ .bubble--bot {
43
+ padding: 0 var(--s-0-5);
44
+ color: var(--md-sys-color-on-surface);
45
+ max-width: 720px;
46
+ background: transparent;
47
+ }
48
+
49
+ /* ---------- Bubble body content (BEM-wrapped by <BubbleBody>) ---------- */
50
+ .bubble__paragraph { margin: 0 0 0.75em; }
51
+ .bubble__paragraph:last-child { margin-bottom: 0; }
52
+
53
+ .bubble__list { margin: var(--s-1) 0 0; padding-left: var(--s-5-5); }
54
+ .bubble__list--ordered { list-style: decimal; }
55
+ .bubble__list--unordered { list-style: none; padding-left: var(--s-5-5); }
56
+ .bubble__list-item { padding-left: var(--s-1-5); margin-bottom: var(--s-1-5); }
57
+ .bubble__list--ordered .bubble__list-item::marker {
58
+ color: var(--xm-color-on-surface-soft);
59
+ font-variant-numeric: tabular-nums;
60
+ }
61
+ .bubble__list--unordered .bubble__list-item {
62
+ position: relative;
63
+ padding-left: var(--s-3-5);
64
+ margin-bottom: var(--s-1);
65
+ }
66
+ .bubble__list--unordered .bubble__list-item::before {
67
+ content: "";
68
+ position: absolute;
69
+ left: 0; top: 0.7em;
70
+ width: 4px; height: 4px;
71
+ border-radius: 50%;
72
+ background: var(--xm-color-on-surface-soft);
73
+ }
74
+
75
+ .bubble__strong { font-weight: 600; color: var(--md-sys-color-on-surface); }
76
+
77
+ /* Inline code — flat: monospaced ink shift, no chip background.
78
+ The page can still override --xm-color-code-ink at :root for accent
79
+ variants (see bubbles.html for the canonical override). */
80
+ .bubble__code {
81
+ background: transparent;
82
+ color: var(--xm-color-code-ink, oklch(0.55 0.16 25));
83
+ padding: 0;
84
+ border-radius: 0;
85
+ font: 500 12.5px/1.4 var(--xm-typescale-mono-font);
86
+ }
87
+
88
+ /* ---------- Bubble group (column wrapper) ---------- */
89
+ .bubble-group {
90
+ display: flex;
91
+ flex-direction: column;
92
+ gap: var(--s-1-5);
93
+ max-width: 720px;
94
+ }
95
+ .bubble-group--user {
96
+ align-items: flex-end;
97
+ max-width: 640px;
98
+ }
99
+ .bubble-group--bot {
100
+ align-items: flex-start;
101
+ }
102
+
103
+ /* ---------- Bubble actions (hover-reveal toolbar) ---------- */
104
+ .bubble-actions {
105
+ display: inline-flex;
106
+ align-items: center;
107
+ gap: var(--s-2-5);
108
+ padding: 0 var(--s-1);
109
+ background: transparent;
110
+ border: 0;
111
+ color: var(--xm-color-on-surface-soft);
112
+ opacity: 0;
113
+ transform: translateY(-1px);
114
+ transition:
115
+ opacity var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
116
+ transform var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
117
+ pointer-events: none;
118
+ }
119
+ .bubble-group:hover .bubble-actions,
120
+ .bubble-group:focus-within .bubble-actions {
121
+ opacity: 1;
122
+ transform: none;
123
+ pointer-events: auto;
124
+ }
125
+
126
+ .bubble-actions__ts {
127
+ font: 400 12px/1 var(--xm-typescale-mono-font);
128
+ color: var(--xm-color-on-surface-soft);
129
+ letter-spacing: 0.02em;
130
+ }
131
+
132
+ .bubble-actions__btn {
133
+ appearance: none;
134
+ border: 0;
135
+ background: transparent;
136
+ color: var(--xm-color-on-surface-soft);
137
+ padding: var(--s-1);
138
+ border-radius: 6px;
139
+ display: inline-flex;
140
+ align-items: center;
141
+ justify-content: center;
142
+ cursor: pointer;
143
+ transition:
144
+ background var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard),
145
+ color var(--md-sys-motion-duration-short3) var(--md-sys-motion-easing-standard);
146
+ }
147
+ .bubble-actions__btn:hover {
148
+ background: color-mix(in oklch, currentColor 14%, transparent);
149
+ color: var(--md-sys-color-on-surface);
150
+ }
151
+ .bubble-actions__btn svg {
152
+ width: 16px; height: 16px;
153
+ stroke: currentColor;
154
+ fill: none;
155
+ stroke-width: 1.6;
156
+ stroke-linecap: round;
157
+ stroke-linejoin: round;
158
+ }
159
+
160
+ /* ---------- Attachment chips (used when user bubble carries files) ---------- */
161
+ .bubble__atts {
162
+ display: flex;
163
+ flex-wrap: wrap;
164
+ gap: var(--s-1-5);
165
+ margin-bottom: var(--s-1-5);
166
+ }
167
+ .bubble__att-mini {
168
+ display: inline-flex;
169
+ align-items: center;
170
+ gap: var(--s-1-5);
171
+ padding: var(--s-1) var(--s-2);
172
+ border-radius: 6px;
173
+ background: color-mix(in oklab, currentColor 12%, transparent);
174
+ font: 500 11px/1 var(--xm-typescale-mono-font);
175
+ }
176
+ .bubble__att-thumb {
177
+ width: 14px; height: 14px;
178
+ border-radius: 3px;
179
+ background-size: cover;
180
+ background-position: center;
181
+ flex-shrink: 0;
182
+ }
@@ -0,0 +1,72 @@
1
+ import { LitElement, nothing } from "lit";
2
+ import type { TemplateResult } from "lit";
3
+ import "../button/index.js";
4
+ export type BubbleVariant = "user" | "bot";
5
+ export interface BubbleAttachment {
6
+ id?: string;
7
+ name: string;
8
+ kind: "image" | "file" | string;
9
+ dataUrl?: string;
10
+ }
11
+ export interface BubbleArtifact {
12
+ title: string;
13
+ sub?: string[];
14
+ provider?: string;
15
+ }
16
+ declare class LightElement extends LitElement {
17
+ createRenderRoot(): HTMLElement | DocumentFragment;
18
+ }
19
+ declare class XmBubbleGroup extends LightElement {
20
+ variant: BubbleVariant;
21
+ private _authoredChildren;
22
+ connectedCallback(): void;
23
+ render(): TemplateResult;
24
+ updated(): void;
25
+ }
26
+ declare class XmBubble extends LightElement {
27
+ variant: BubbleVariant;
28
+ attachments: BubbleAttachment[];
29
+ artifact: BubbleArtifact | null;
30
+ download: boolean;
31
+ text: string;
32
+ bodyHtml: string;
33
+ private _authored;
34
+ connectedCallback(): void;
35
+ private _onArtifactOpen;
36
+ private _onArtifactDownload;
37
+ private _attachmentTemplate;
38
+ private _artifactTemplate;
39
+ render(): TemplateResult;
40
+ updated(): void;
41
+ }
42
+ declare class XmBubbleActions extends LightElement {
43
+ ts: string;
44
+ ariaLabel: string;
45
+ private _authored;
46
+ private _copyResetTimer;
47
+ private _stragglerObserver;
48
+ connectedCallback(): void;
49
+ disconnectedCallback(): void;
50
+ private _isRenderedShell;
51
+ private _harvestAuthored;
52
+ private _onDelegatedClick;
53
+ private _showCopiedFeedback;
54
+ render(): TemplateResult;
55
+ updated(): void;
56
+ }
57
+ declare class XmArtifactChip extends LightElement {
58
+ artifact: BubbleArtifact | null;
59
+ download: boolean;
60
+ private _open;
61
+ private _download;
62
+ render(): TemplateResult | typeof nothing;
63
+ }
64
+ declare global {
65
+ interface HTMLElementTagNameMap {
66
+ "xm-bubble-group": XmBubbleGroup;
67
+ "xm-bubble": XmBubble;
68
+ "xm-bubble-actions": XmBubbleActions;
69
+ "xm-artifact-chip": XmArtifactChip;
70
+ }
71
+ }
72
+ export {};