@gemboss/ui 0.43.0 → 0.45.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 +57 -0
- package/README.md +70 -5
- package/catalog/editor.html +1 -1
- package/catalog/index.html +1 -1
- package/gemboss-ui.css +2 -2
- package/package.json +5 -2
- package/parts/components.css +1 -1
- package/parts/core.css +1 -1
- package/parts/shell.css +1 -1
- package/src/assistant-plain.js +1 -0
- package/src/index.ts +1 -1
- package/src/reactions-data.ts +15 -4
- package/src/reactions.tsx +64 -15
- package/src/team-chat-plain.js +1 -1
- package/src/team-chat.tsx +13 -7
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,63 @@
|
|
|
2
2
|
|
|
3
3
|
Versions up to 0.9.0 are described in the README, each in the section that introduced it.
|
|
4
4
|
|
|
5
|
+
## 0.45.0 (21/10/2026)
|
|
6
|
+
|
|
7
|
+
**The reaction picker speaks the app's language** (21/10/2026, seen on GemCommunity's Vietnamese chat with 0.43.0: the
|
|
8
|
+
picker opened by the composer's emoji button and by "More reactions" said "Search emoji", "No emoji matches.", "Frequently
|
|
9
|
+
used", "Smileys"…).
|
|
10
|
+
|
|
11
|
+
Added
|
|
12
|
+
- `REACTION_LABELS` and type `ReactionLabels` (reactions.tsx, exported from the root): every word `Reactions` and
|
|
13
|
+
`ReactionPicker` write, English by default: `pickReaction`, `searchEmoji`, `noEmojiMatches`, `frequentlyUsed`,
|
|
14
|
+
`groupName(id)` (a group's heading by its English id in `REACTION_GROUPS`, which stays the key), `pickReactionEmoji(emoji,
|
|
15
|
+
words, mine)`, `addReaction`, `addReactionTo(target)`, `reactionChip(emoji, names, mine)`. A `labels` prop (any subset) on
|
|
16
|
+
`Reactions` (passed on to its picker) and on `ReactionPicker`; its `label` prop still wins over `pickReaction`.
|
|
17
|
+
- `TEAM_CHAT_LABELS` carries those keys (same defaults) and `messageFrom(author)` ("the message from Linh", the target a
|
|
18
|
+
message gives its reaction row). `Message` passes its `labels` to its `Reactions` row and to the "More reactions" picker,
|
|
19
|
+
and uses `addReaction` for that button's tooltip (was a hard-coded "Add reaction"); `Composer` passes its `labels` to the
|
|
20
|
+
emoji button's picker.
|
|
21
|
+
- `team-chat-plain.js`: `LABELS` has the same keys; `reactions(props)` and `reactionPicker(props)` take `labels`, `message`
|
|
22
|
+
passes its own to both, `emojiButton({ labels })` to its picker.
|
|
23
|
+
- `searchReactions(query, groupName?)`: with the picker's `groupName`, a query found in a TRANSLATED group name (case and
|
|
24
|
+
Vietnamese marks ignored: "mat cuoi" finds "Mặt cười") adds that whole group. A name left as its English id is not
|
|
25
|
+
searched, so an English picker finds what it did. The emoji's own search words stay English for now.
|
|
26
|
+
|
|
27
|
+
Unchanged
|
|
28
|
+
- An app that passes no labels draws the same markup, word for word (held by `reactions.test.tsx`).
|
|
29
|
+
|
|
30
|
+
Tests
|
|
31
|
+
- `reactions.test.tsx`: the defaults; markup with Vietnamese labels (picker both kinds, row); every label replaced by a
|
|
32
|
+
marker leaves no English but the data (search words, names); the translated-group search; a guard that parses
|
|
33
|
+
`reactions.tsx` (TypeScript's parser) and fails on any string or JSX text outside `// labels:begin` … `// labels:end`
|
|
34
|
+
that is not a class name, key or attribute value, with negative controls for five words put back.
|
|
35
|
+
- `team-chat-plain-data.test.ts`: `searchReactions` with group names against the TypeScript; no picker word written in the
|
|
36
|
+
plain code outside `LABELS`. `team-chat-plain-browser.test.ts`: the translated picker, row and message drawn both ways;
|
|
37
|
+
live, a Vietnamese message's two pickers and a Vietnamese composer's, searched by a group's Vietnamese name and to
|
|
38
|
+
nothing, the same DOM both ways. `team-chat.test.tsx`: a message's reaction words follow its labels.
|
|
39
|
+
|
|
40
|
+
## 0.44.0 (21/10/2026)
|
|
41
|
+
|
|
42
|
+
**The assistant frame for a page with no React: `gembossUI.assistantFrame`** (Chris 21/10/2026: GemFactory's assistant was a
|
|
43
|
+
hand-copied popup with none of the other services' shapes; `AssistantHost` is React-only and GemFactory's pages are not).
|
|
44
|
+
|
|
45
|
+
Added
|
|
46
|
+
- `packages/ui/src/assistant-plain.js` (`@gemboss/ui/assistant-plain.js`, its own entry, ES5 classic script after
|
|
47
|
+
`kit-plain.js`): `assistantFrame(opts)` draws `AssistantProvider` + `AssistantHost`'s frame around the page's chat
|
|
48
|
+
(`body`): hidden / status bar / popup / side panel / full screen, with `dock.ts`'s rules (`gembossUI.assistantDock`:
|
|
49
|
+
the reducer, its clamps and constants), the provider's storage keys under `storagePrefix`, `<prefix>-busy` / `-unread` /
|
|
50
|
+
`-side` and `--gb-assistant-side-w` on `<body>`, the rail link's reopen, the popup's grip and slide and the panel's seam
|
|
51
|
+
with their keys, the ⋯ menu (`menuItems`, Clear history, pin / float, minimise), and the same markup and classes, so
|
|
52
|
+
`assistant.css` draws it. For a page that reloads on every click it keeps the shape on screen for the tab
|
|
53
|
+
(`keepAcrossPages`), enters full screen on its own page (`fullHref`), and hides the page's `launchers` while it is up.
|
|
54
|
+
API: `open`, `toggle`, `openDock`, `openSide`, `minimize`, `dismiss`, `enterFull`, `leaveFull`, `setBusy`, `state`,
|
|
55
|
+
`onChange`, `update`, `destroy`, `el`, `pane`. Not yet: `secondTab`, page facts.
|
|
56
|
+
6.9 KB gzip minified (ceiling 7,562 in `weight-budget.json`; a page without an assistant never loads it).
|
|
57
|
+
- `assistant-plain-browser.test.ts` (`test:ui-browser`): the reducer against `dock.ts` over 400 random sequences of 40
|
|
58
|
+
events; in Chromium, 19 steps (open, busy, ×, status bar, popup, resize, side, width, full and back) on the component and
|
|
59
|
+
on the plain frame at 1440 and 900px, the `.gb-dock` element, `<body>`'s classes and the stored keys compared after each;
|
|
60
|
+
the page-load, launcher, rail-link, ⋯ menu, grip-key and below-1100px behaviour; negative controls for both halves.
|
|
61
|
+
|
|
5
62
|
## 0.43.0 (21/10/2026)
|
|
6
63
|
|
|
7
64
|
**The full-screen assistant stops paying for a blur nobody sees** (21/10/2026, measured in the GemBoss desktop app).
|
package/README.md
CHANGED
|
@@ -312,6 +312,28 @@ minimise. Full screen's chrome shows ⋯ too when you pass either. Do not draw a
|
|
|
312
312
|
menuItems={<AssistantMenuItem onClick={exportChat}>Export chat</AssistantMenuItem>}>
|
|
313
313
|
```
|
|
314
314
|
|
|
315
|
+
**A page with no React (0.44.0): `assistant-plain.js`.** The same frame for a server-rendered page (GemFactory's board,
|
|
316
|
+
gemcare): the five shapes, `dock.ts`'s rules copied in ES5, the provider's storage keys, `<prefix>-side` and
|
|
317
|
+
`--gb-assistant-side-w` on `<body>`, the rail link's reopen, the ⋯ menu, the grips and their keys, and the same markup,
|
|
318
|
+
so `assistant.css` draws it. `assistant-plain-browser.test.ts` holds it to `AssistantProvider` + `AssistantHost`: the same
|
|
319
|
+
steps on both, the `.gb-dock` element compared after each one. A classic script after `kit-plain.js`:
|
|
320
|
+
|
|
321
|
+
```html
|
|
322
|
+
<script src="kit-plain.js"></script><script src="chat-plain.js"></script><script src="assistant-plain.js"></script>
|
|
323
|
+
<script>
|
|
324
|
+
const frame = gembossUI.assistantFrame({ title: "Factory Assistant", body: chatElement,
|
|
325
|
+
storagePrefix: "gemfactory.assistant", launchers: ".gb-assistant-launcher", fullHref: "/assistant",
|
|
326
|
+
onNewChat, onClearHistory, menuItems: [{ label: "Export chat", onClick: exportChat }] });
|
|
327
|
+
chat.onBusyChange = (busy) => frame.setBusy(busy);
|
|
328
|
+
</script>
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
The page reloads on every click, so the frame keeps the shape on screen for the tab (sessionStorage
|
|
332
|
+
`<prefix>.presentation`, `keepAcrossPages: false` to turn it off): open on one page, open on the next. A run does not
|
|
333
|
+
survive the reload, and leaving the full-screen page leaves the status bar, as `leave-full` does. The full-screen page
|
|
334
|
+
is yours (`fullHref`); the frame enters full there by itself. `launchers` are hidden while the frame is up and open it.
|
|
335
|
+
Not in the plain frame yet: `secondTab` and page facts.
|
|
336
|
+
|
|
315
337
|
## The engine picker (0.25.0): `EnginePicker`, `BridgeNotice`
|
|
316
338
|
|
|
317
339
|
Which engine answers the assistant, and the bridge on the user's machine, without spending the chat's space on it
|
|
@@ -1681,8 +1703,9 @@ and GemCare's chat, draw and accept the same thing.
|
|
|
1681
1703
|
| Piece | What |
|
|
1682
1704
|
|---|---|
|
|
1683
1705
|
| `@gemboss/ui/reactions-data` (plain TS, also re-exported from the root) | `REACTION_GROUPS` (GemCare's 137 emoji in 4 groups, each with search words), `REACTION_EMOJI`, `isReactionEmoji` (the server's check: refuse anything else), `searchReactions`, `reactionLabel` (names, two then `+n`), `toggleReaction` (the optimistic guess drawn before the server answers), `QUICK_REACTIONS` (👍 ✅), type `Reaction` = `{ emoji, names, mine }` |
|
|
1684
|
-
| `Reactions` (React, client) | the chips (emoji + NAMES of who put it; yours outlined + filled, `aria-pressed`) and "Add reaction", which opens `ReactionPicker` in flow under the row. `canReact={false}`: chips only; no chips and no right to react: nothing |
|
|
1685
|
-
| `ReactionPicker` | search, "Frequently used" (this browser's last picks, `localStorage`, filled up to nine with `SUGGESTED_REACTIONS`), the groups; arrows move in the grid, Enter in the search picks the first, Escape closes and returns focus. `items` absent: a picker that WRITES an emoji (the team chat composer's): plain buttons, none pressed. `label` (its name, default
|
|
1706
|
+
| `Reactions` (React, client) | the chips (emoji + NAMES of who put it; yours outlined + filled, `aria-pressed`) and "Add reaction", which opens `ReactionPicker` in flow under the row. `canReact={false}`: chips only; no chips and no right to react: nothing. `labels` (below) reaches its picker too |
|
|
1707
|
+
| `ReactionPicker` | search, "Frequently used" (this browser's last picks, `localStorage`, filled up to nine with `SUGGESTED_REACTIONS`), the groups; arrows move in the grid, Enter in the search picks the first, Escape closes and returns focus. `items` absent: a picker that WRITES an emoji (the team chat composer's): plain buttons, none pressed. `label` (its name, default `labels.pickReaction`), `className`, `initialFocus` (`"search"`, default, or `"emoji"`: under a finger a focused search brings the keyboard up over it), `labels` |
|
|
1708
|
+
| `REACTION_LABELS`, type `ReactionLabels` (21/10/2026) | every word the two write, English by default; `labels` (any subset) translates. The keys and how a search treats a translated group: "The words" in the team chat layer below (`TEAM_CHAT_LABELS` carries the same keys) |
|
|
1686
1709
|
| `reactions.css` (its own entry, NOT inside `gemboss-ui.css`: link it where reactions are drawn, as `collections.css`) | `ui-reactions`, `ui-reactions__row`, `ui-reaction` (+ `is-mine`), `__emoji`, `__names`, `ui-reaction-add`, `ui-reaction-picker` (`__search`, `__body`, `__head`, `__grid`, `__btn`, `__empty`) |
|
|
1687
1710
|
|
|
1688
1711
|
Every target is 44px (a control, CLAUDE.md §9.1); the pill you see is 26px, transparent padding carries the rest, so a
|
|
@@ -1717,7 +1740,8 @@ token, so `data-theme="dark"` turns it dark unchanged. It holds no rule on `:roo
|
|
|
1717
1740
|
|
|
1718
1741
|
Props only: no fetching, no store, no router. The app owns the data and the actions; the components keep only the screen's
|
|
1719
1742
|
own state (the reaction picker a message opened, the composer's text when the app does not hold it, focus). Every word they
|
|
1720
|
-
write themselves is in `TEAM_CHAT_LABELS`; pass `labels` (any subset) to translate
|
|
1743
|
+
write themselves is in `TEAM_CHAT_LABELS`; pass `labels` (any subset) to translate (the reactions' and the picker's words
|
|
1744
|
+
too: "The words", below). `teamChatRows(messages, { meId,
|
|
1721
1745
|
isUnread })` (plain TS, `team-chat-data.ts`) says where the day separators and the "New messages" line go and which
|
|
1722
1746
|
messages are `grouped`: same author, same day, under 5 minutes apart, not a reply, and not the first new one (GemCare's
|
|
1723
1747
|
rules). `chatDayWord` gives "Today" / "Yesterday"; older days the app formats in its own locale. Days are the viewer's
|
|
@@ -1740,6 +1764,47 @@ field where the caret was (a person who opened it was writing); a press or focus
|
|
|
1740
1764
|
opens on the first emoji, not the search, so the keyboard does not come up over it. Under 360px of the screen's width the
|
|
1741
1765
|
box's three 44px buttons touch (no gap), so the field keeps 150px at 320.
|
|
1742
1766
|
|
|
1767
|
+
**The words of the reactions and the picker** (21/10/2026: GemCommunity's Vietnamese chat showed "Search emoji",
|
|
1768
|
+
"Frequently used" and "Smileys"). `TEAM_CHAT_LABELS` carries `REACTION_LABELS`' keys (reactions.tsx) with the same defaults,
|
|
1769
|
+
and a `Message` passes its `labels` to the `Reactions` row and to the picker "More reactions" opens, the `Composer` to the
|
|
1770
|
+
picker its emoji button opens. So one `labels` object translates the chat, the reaction row and both pickers; outside the
|
|
1771
|
+
team chat, `Reactions` and `ReactionPicker` take the same `labels`. An app that passes nothing gets the English below,
|
|
1772
|
+
word for word.
|
|
1773
|
+
|
|
1774
|
+
| Key | Default | Where |
|
|
1775
|
+
|---|---|---|
|
|
1776
|
+
| `pickReaction` | "Pick a reaction" | the picker's accessible name (a `label` prop wins: the composer's picker is named `pickEmoji`, "Pick an emoji") |
|
|
1777
|
+
| `searchEmoji` | "Search emoji" | the search field's placeholder and accessible name |
|
|
1778
|
+
| `noEmojiMatches` | "No emoji matches." | the search found nothing |
|
|
1779
|
+
| `frequentlyUsed` | "Frequently used" | the first heading |
|
|
1780
|
+
| `groupName(id)` | the id: "Smileys", "Hands", "Marks", "Work" | each group's heading. `id` is the group's English id in `REACTION_GROUPS`: it stays the key, the name is display only |
|
|
1781
|
+
| `pickReactionEmoji(emoji, words, mine)` | "Add 🎉 party tada celebrate", "Remove 👍 like thumbs up yes ok" | a picker button's accessible name where the picker puts reactions (the composer's: the emoji and its words, no verb) |
|
|
1782
|
+
| `addReaction` | "Add reaction" | the tooltip of the button that opens the picker: the reaction row's, the action bar's |
|
|
1783
|
+
| `addReactionTo(target)` | "Add a reaction to the message from Linh" ("… to this" with no `target`) | the reaction row's button name |
|
|
1784
|
+
| `reactionChip(emoji, names, mine)` | "👍, Linh, Quan. Remove yours", "🎉, Bo. Add yours" | a chip's accessible name (`names` joined by ", ") |
|
|
1785
|
+
| `messageFrom(author)` (team chat only) | "the message from Linh" | the `target` a message gives its reaction row |
|
|
1786
|
+
|
|
1787
|
+
```tsx
|
|
1788
|
+
const VI: Partial<TeamChatLabels> = {
|
|
1789
|
+
pickReaction: "Chọn cảm xúc", pickEmoji: "Chọn emoji", searchEmoji: "Tìm emoji", noEmojiMatches: "Không có emoji nào khớp.",
|
|
1790
|
+
frequentlyUsed: "Hay dùng",
|
|
1791
|
+
groupName: (id) => ({ Smileys: "Mặt cười", Hands: "Bàn tay", Marks: "Ký hiệu", Work: "Công việc" } as Record<string, string>)[id] ?? id,
|
|
1792
|
+
pickReactionEmoji: (e, words, mine) => `${mine ? "Bỏ" : "Thả"} ${e} ${words}`,
|
|
1793
|
+
addReaction: "Thêm cảm xúc", addReactionTo: (target) => `Thêm cảm xúc cho ${target ?? "mục này"}`,
|
|
1794
|
+
reactionChip: (e, names, mine) => `${e}, ${names}. ${mine ? "Bỏ của bạn" : "Thả cùng"}`, messageFrom: (a) => `tin nhắn của ${a}`,
|
|
1795
|
+
};
|
|
1796
|
+
<Message {...m} labels={VI} /> <Composer onSend={send} labels={VI} /> <Reactions items={r} labels={VI} />
|
|
1797
|
+
// A plain page: the same object.
|
|
1798
|
+
gembossUI.teamChat.message({ ...m, labels: VI }); gembossUI.teamChat.emojiButton({ textarea, labels: VI });
|
|
1799
|
+
```
|
|
1800
|
+
|
|
1801
|
+
**Search** matches each emoji's search words, which are English (as before), and, when `groupName` gives a group a name
|
|
1802
|
+
other than its id, that name too: ignoring case and Vietnamese marks ("mặt cười", "mat cuoi" or "Mặt" for "Mặt cười"), it
|
|
1803
|
+
adds the whole group, in picker order, to what the words found. An English name is not searched, so an English picker
|
|
1804
|
+
finds exactly what it did. Still English for now: the emoji's own search words, a button's tooltip (the first of them) and
|
|
1805
|
+
the words read after the emoji in a button's name. `reactions.test.tsx` holds `reactions.tsx` to the table (no string or
|
|
1806
|
+
JSX text outside it but class names, keys and attribute values), and `team-chat-plain-data.test.ts` the plain script.
|
|
1807
|
+
|
|
1743
1808
|
**The layout.** `.gb-tc` is a CSS grid and a size container: it decides by its OWN width (in an app shell the chat is the
|
|
1744
1809
|
window minus the shell's rail), with container queries. `TEAM_CHAT_DRAWER_MAX` (1100) and `TEAM_CHAT_PHONE_MAX` (760) are the
|
|
1745
1810
|
same numbers for JS.
|
|
@@ -2217,11 +2282,11 @@ after `kit-plain.js` when the page has it (it adds `gembossUI.teamChat`; loaded
|
|
|
2217
2282
|
| `readReceipt({ read, of, label })` | `ReadReceipt` (`null` when `of` ≤ 0) |
|
|
2218
2283
|
| `channelSection({ label, id, items })`, `channelItem(props)` | `ChannelSection`, `ChannelItem` (`href`: a link, else a button; a DM's `avatar`); `items` are rows or their props |
|
|
2219
2284
|
| `peopleSection({ label, count, id, items })`, `personRow(props)` | `PeopleSection`, `PersonRow` (a link, a button with `onSelect`, else a `div`) |
|
|
2220
|
-
| `reactions(props)`, `reactionPicker(props)` | `Reactions` (plus `open` / `onOpenChange`), `ReactionPicker` (`items` absent: the composer's, which writes an emoji; `label`, `className`) |
|
|
2285
|
+
| `reactions(props)`, `reactionPicker(props)` | `Reactions` (plus `open` / `onOpenChange`), `ReactionPicker` (`items` absent: the composer's, which writes an emoji; `label`, `className`); both take `labels` ("The words" above) |
|
|
2221
2286
|
| `emojiButton({ textarea, button, host, labels })` | the `Composer`'s emoji button and picker, for a composer the page writes itself (below) |
|
|
2222
2287
|
| `avatar({ name, src, size, className })`, `icon(name, size)` | `Avatar` (portal.tsx's initials and tone), `Icon` (the icons the builders draw, and `more`) |
|
|
2223
2288
|
| `rows(messages, opts)`, `dayKey(at, timeZone)`, `dayISO(at, timeZone)`, `dayWord(at, now, timeZone)` | `teamChatRows`, `chatDayKey`, `chatDayISO`, `chatDayWord` |
|
|
2224
|
-
| `LABELS` | `TEAM_CHAT_LABELS
|
|
2289
|
+
| `LABELS` | `TEAM_CHAT_LABELS` (the reactions' and the picker's keys included); `labels` (any subset) translates, functions included: `message` passes them to its reaction row and both pickers, `emojiButton` to its picker |
|
|
2225
2290
|
|
|
2226
2291
|
```html
|
|
2227
2292
|
<link rel="stylesheet" href="/ui/portal.css"><link rel="stylesheet" href="/ui/reactions.css"><link rel="stylesheet" href="/ui/team-chat.css">
|
package/catalog/editor.html
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
.cat-code summary{padding:10px 16px;font-size:13px;cursor:pointer;color:var(--gemboss-text-muted);border-top:1px solid var(--gemboss-divider);min-height:24px}
|
|
9
9
|
.cat-code pre,.cat-api{margin:0;padding:12px 16px;overflow:auto;background:#0f1012;color:#e8e8e6;font-size:12px;line-height:1.5;border-radius:0}
|
|
10
10
|
.cat-api{border-radius:12px;margin:0 0 16px}</style></head><body><div class="cat">
|
|
11
|
-
<h1>@gemboss/ui 0.
|
|
11
|
+
<h1>@gemboss/ui 0.45.0 · Editor</h1>
|
|
12
12
|
<p>Khung của mọi editor: <code>EditorFrame</code> (cột trái · khe kéo · preview · cột phải dock trên mép phải preview) và <code>EditorTopbar</code> (← · tiêu đề · cụm giữa · cụm phải · dòng trạng thái). Là đúng khung của theme / page / section editor trong admin. Gói chỉ vẽ KHUNG; chat, Configure, canvas, page picker, menu, Publish là của editor, đi vào bằng slot. Trang HTML thuần nạp <code>editor.css</code> + <code>editor-plain.js</code> rồi gọi <code>gembossUI.initEditorFrame()</code>: kéo khe (chuột, chạm, phím mũi tên / Home / End), đổi thiết bị, mở ⋯ và Publish ▾, ẩn cột trái, Chat | Preview trên điện thoại. <a href="index.html">← Catalog</a></p>
|
|
13
13
|
<h2>React</h2><pre class="cat-api"><code>import "@gemboss/ui/editor.css";
|
|
14
14
|
import { EditorFrame, EditorTopbar, EditorBack, EditorChatToggle, EditorPaneTabs, EditorSaveState, DeviceToggle } from "@gemboss/ui/editor";
|
package/catalog/index.html
CHANGED
|
@@ -27,7 +27,7 @@ body{margin:0;background:var(--gemboss-app-bg,#f1f1f1);color:var(--gemboss-text)
|
|
|
27
27
|
@media (max-width:760px){.cat{grid-template-columns:1fr;padding:16px}.cat-nav{position:static;flex-direction:row;flex-wrap:wrap}}
|
|
28
28
|
</style></head><body>
|
|
29
29
|
<div class="cat"><nav class="cat-nav" aria-label="Mục"><a href="#tokens">Token</a><a href="#buttons">Nút</a><a href="#fields">Ô nhập</a><a href="#choice">Tab, nhóm nút, thẻ</a><a href="#surfaces">Thẻ, số liệu, bảng, trạng thái trống</a><a href="#report">Báo cáo</a><a href="#collections">Bảng, list, lưới, board</a><a href="#resizer">Thanh kéo giữa hai cột</a><a href="#modal">Hộp thoại, toast, menu (JS thuần)</a><a href="#sheet">Ngăn trượt cạnh phải</a><a href="#reader">Hộp đọc tài liệu</a><a href="#settings">Hộp cài đặt</a><a href="#switcher">Chuyển dịch vụ</a><a href="#shell">Khung app</a><a href="#nav">Chờ điều hướng</a><a href="#page">Bề rộng nội dung</a><a href="#portal">Cổng công khai: tab trên topbar, tìm kiếm, sáng / tối, người dẫn đầu</a><a href="#site">Trang công khai: thanh trên, logo cỡ site, nút, chân trang</a><a href="#auth">Đăng nhập</a><a href="#setup">Hướng dẫn thiết lập</a><a href="#chat">Thân chat</a><a href="#reactions">Reactions</a><a href="#team-chat">Chat đội</a><a href="#action-card">Thẻ hành động</a><a href="#assistant-engine">Trợ lý: chọn engine</a><a href="#assistant-bridge">Trợ lý: cầu nối trên máy (0.32.0)</a><a href="#assistant-chat">Trợ lý: khung chat (0.29.0)</a><a href="#assistant">Trợ lý: cột phiên</a><a href="#icons">Icon</a><a href="#editor">Editor</a></nav>
|
|
30
|
-
<main><header class="cat-head"><h1>@gemboss/ui 0.
|
|
30
|
+
<main><header class="cat-head"><h1>@gemboss/ui 0.45.0</h1><p>Ngôn ngữ thiết kế chung của các công cụ GemBoss. Markup dưới mỗi ví dụ là đúng thứ package render ra; bề mặt không dùng React (HTML tĩnh, Python) chép markup này và nạp <code>gemboss-ui.css</code>. Dựng từ gemboss <code>bf4b8350d940</code>.</p></header>
|
|
31
31
|
<section id="tokens"><h2>Token</h2><p>Đổi giao diện một bề mặt bằng cách đặt lại token, không viết đè class. Tên và giá trị đọc thẳng từ gemboss-ui.css.</p><div class="cat-swatches"><div class="cat-swatch"><i style="background:var(--gemboss-primary)"></i><code>--gemboss-primary</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-primary-dark)"></i><code>--gemboss-primary-dark</code><span>#000000</span></div><div class="cat-swatch"><i style="background:var(--gemboss-primary-soft)"></i><code>--gemboss-primary-soft</code><span>#f2f3f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent)"></i><code>--gemboss-accent</code><span>#5661f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-strong)"></i><code>--gemboss-accent-strong</code><span>#3a44de</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-soft)"></i><code>--gemboss-accent-soft</code><span>#eef0fe</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-wash)"></i><code>--gemboss-accent-wash</code><span>#f7f8ff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-tint)"></i><code>--gemboss-accent-tint</code><span>#dfe2ff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-accent-mid)"></i><code>--gemboss-accent-mid</code><span>#c9cffd</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text-strong)"></i><code>--gemboss-text-strong</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text)"></i><code>--gemboss-text</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-text-muted)"></i><code>--gemboss-text-muted</code><span>#686b71</span></div><div class="cat-swatch"><i style="background:var(--gemboss-surface)"></i><code>--gemboss-surface</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-canvas)"></i><code>--gemboss-canvas</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-preview-canvas)"></i><code>--gemboss-preview-canvas</code><span>#eceef1</span></div><div class="cat-swatch"><i style="background:var(--gemboss-rail-bg)"></i><code>--gemboss-rail-bg</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-panel-bg)"></i><code>--gemboss-panel-bg</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-divider)"></i><code>--gemboss-divider</code><span>#e5e7ea</span></div><div class="cat-swatch"><i style="background:var(--gemboss-divider-soft)"></i><code>--gemboss-divider-soft</code><span>#edeff2</span></div><div class="cat-swatch"><i style="background:var(--gemboss-hover)"></i><code>--gemboss-hover</code><span>#eceef2</span></div><div class="cat-swatch"><i style="background:var(--gemboss-active-bg)"></i><code>--gemboss-active-bg</code><span>#f0f1f4</span></div><div class="cat-swatch"><i style="background:var(--gemboss-active-fg)"></i><code>--gemboss-active-fg</code><span>#1b1c1e</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger)"></i><code>--gemboss-danger</code><span>#d72c0d</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-strong)"></i><code>--gemboss-danger-strong</code><span>#b42318</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-soft)"></i><code>--gemboss-danger-soft</code><span>#fff0e9</span></div><div class="cat-swatch"><i style="background:var(--gemboss-danger-border)"></i><code>--gemboss-danger-border</code><span>#f5c9bc</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success)"></i><code>--gemboss-success</code><span>#007f5f</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-strong)"></i><code>--gemboss-success-strong</code><span>#0a6a4c</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-soft)"></i><code>--gemboss-success-soft</code><span>#e3f1df</span></div><div class="cat-swatch"><i style="background:var(--gemboss-success-border)"></i><code>--gemboss-success-border</code><span>#b7dfcd</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning)"></i><code>--gemboss-warning</code><span>#9a6700</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning-soft)"></i><code>--gemboss-warning-soft</code><span>#fff8e0</span></div><div class="cat-swatch"><i style="background:var(--gemboss-warning-border)"></i><code>--gemboss-warning-border</code><span>#f5d569</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-bg)"></i><code>--gemboss-dark-bg</code><span>#0a0a0c</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-rail)"></i><code>--gemboss-dark-rail</code><span>#0e0e11</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-surface)"></i><code>--gemboss-dark-surface</code><span>#16161a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-surface-2)"></i><code>--gemboss-dark-surface-2</code><span>#1e1e24</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-divider)"></i><code>--gemboss-dark-divider</code><span>#2a2a31</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-text)"></i><code>--gemboss-dark-text</code><span>#ededf0</span></div><div class="cat-swatch"><i style="background:var(--gemboss-dark-muted)"></i><code>--gemboss-dark-muted</code><span>#9a9aa4</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-bg)"></i><code>--gemboss-field-bg</code><span>#fdfdfd</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-bg-hover)"></i><code>--gemboss-field-bg-hover</code><span>#fafafa</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-ink)"></i><code>--gemboss-field-ink</code><span>#303030</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-placeholder)"></i><code>--gemboss-field-placeholder</code><span>#616161</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line)"></i><code>--gemboss-field-line</code><span>#8a8a8a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line-hover)"></i><code>--gemboss-field-line-hover</code><span>#616161</span></div><div class="cat-swatch"><i style="background:var(--gemboss-field-line-active)"></i><code>--gemboss-field-line-active</code><span>#1a1a1a</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-ink)"></i><code>--gemboss-chip-ink</code><span>#303633</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-line)"></i><code>--gemboss-chip-line</code><span>#cfd6ce</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-line-hover)"></i><code>--gemboss-chip-line-hover</code><span>#aab4ad</span></div><div class="cat-swatch"><i style="background:var(--gemboss-chip-bg-hover)"></i><code>--gemboss-chip-bg-hover</code><span>#f6f7f5</span></div><div class="cat-swatch"><i style="background:var(--gemboss-on-primary)"></i><code>--gemboss-on-primary</code><span>#ffffff</span></div><div class="cat-swatch"><i style="background:var(--gemboss-app-bg)"></i><code>--gemboss-app-bg</code><span>#ffffff</span></div></div><table class="ui-table cat-scale"><thead><tr><th>Token</th><th>Giá trị</th><th>Mẫu</th></tr></thead><tbody><tr><td><code>--gemboss-fs-micro</code></td><td>11px</td><td style="font-size:var(--gemboss-fs-micro)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-caption</code></td><td>12px</td><td style="font-size:var(--gemboss-fs-caption)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-body</code></td><td>14px</td><td style="font-size:var(--gemboss-fs-body)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-body-lg</code></td><td>16px</td><td style="font-size:var(--gemboss-fs-body-lg)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h3</code></td><td>16px</td><td style="font-size:var(--gemboss-fs-h3)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h2</code></td><td>20px</td><td style="font-size:var(--gemboss-fs-h2)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-h1</code></td><td>24px</td><td style="font-size:var(--gemboss-fs-h1)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-fs-display</code></td><td>30px</td><td style="font-size:var(--gemboss-fs-display)">Ngôn ngữ thiết kế chung</td></tr><tr><td><code>--gemboss-radius-xs</code></td><td>4px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-xs)"></i></td></tr><tr><td><code>--gemboss-radius-sm</code></td><td>6px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-sm)"></i></td></tr><tr><td><code>--gemboss-radius-md</code></td><td>8px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-md)"></i></td></tr><tr><td><code>--gemboss-radius-lg</code></td><td>12px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-lg)"></i></td></tr><tr><td><code>--gemboss-radius-xl</code></td><td>16px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-xl)"></i></td></tr><tr><td><code>--gemboss-radius-2xl</code></td><td>20px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-2xl)"></i></td></tr><tr><td><code>--gemboss-radius-full</code></td><td>999px</td><td><i class="cat-radius" style="border-radius:var(--gemboss-radius-full)"></i></td></tr><tr><td><code>--gemboss-shadow-resting</code></td><td class="cat-small">0 1px 2px rgba(31, 30, 29, 0.04), 0 2px 6px rgba(31, 30, 29, 0.06)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-resting);border:0"></i></td></tr><tr><td><code>--gemboss-shadow-raised</code></td><td class="cat-small">0 4px 16px rgba(31, 30, 29, 0.10)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-raised);border:0"></i></td></tr><tr><td><code>--gemboss-shadow-overlay</code></td><td class="cat-small">0 16px 48px rgba(31, 30, 29, 0.18)</td><td><i class="cat-radius" style="box-shadow:var(--gemboss-shadow-overlay);border:0"></i></td></tr></tbody></table></section>
|
|
32
32
|
<section id="buttons"><h2>Nút</h2><p>Một lớp <code>ui-btn</code>, ba biến thể, tông đỏ, một cỡ nhỏ. Cao 28px dưới chuột như Button của Polaris (ô nhập và ô chọn 32, như TextField), 44px dưới ngón tay và ở khổ điện thoại, cỡ nhỏ cũng vậy. Dùng được trên <code><button></code> lẫn <code><a></code> (căn giữa sẵn).</p><figure class="cat-demo"><figcaption>Mặc định · chính · ghost · nhỏ · tắt</figcaption><div class="cat-live"><div class="cat-row"><button type="button" class="ui-btn">Lưu nháp</button><button type="button" class="ui-btn ui-btn--primary">Xuất bản</button><button type="button" class="ui-btn ui-btn--ghost">Huỷ</button><button type="button" class="ui-btn ui-btn--sm">Nhỏ</button><button type="button" class="ui-btn ui-btn--primary" disabled>Đang lưu…</button><a class="ui-btn" href="#buttons">Link dạng nút</a></div></div><details class="cat-code"><summary>Markup</summary><pre><code><div class="cat-row">
|
|
33
33
|
<button type="button" class="ui-btn">Lưu nháp</button>
|
package/gemboss-ui.css
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* GemBoss admin design system — GENERATED — do not edit; regenerate from gemboss:
|
|
3
3
|
* node apps/admin/scripts/export-ui-css.mjs --out <path> (npm run export:ui-css)
|
|
4
|
-
* gemboss commit:
|
|
5
|
-
* sources sha256:
|
|
4
|
+
* gemboss commit: bf4b8350d9402ab9f5d025fa5438a78fb347b8e3
|
|
5
|
+
* sources sha256: c28d8d08dbe89d67bcea8c8ec942c6f96d65f5b2f55c41fb55845b932e5b2815
|
|
6
6
|
* contents: 1 allow-listed rule from apps/admin/src/app/globals.css + packages/ui/src/gemboss-tokens.css
|
|
7
7
|
* (verbatim) + packages/ui/src/ui.css (verbatim) + packages/ui/src/gemboss-field.css (verbatim)
|
|
8
8
|
* + 182 rules from packages/ui/src/shell.css (the shared shell)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@gemboss/ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.45.0",
|
|
4
4
|
"description": "GemBoss design system for every surface in the fleet: the admin shell (topbar + rail + drawer) as React components, and the admin stylesheet exported as one CSS file.",
|
|
5
5
|
"license": "UNLICENSED",
|
|
6
6
|
"type": "module",
|
|
@@ -13,7 +13,8 @@
|
|
|
13
13
|
"./src/chat-plain.js",
|
|
14
14
|
"./src/service-switcher-plain.js",
|
|
15
15
|
"./src/auth-sso-plain.js",
|
|
16
|
-
"./src/team-chat-plain.js"
|
|
16
|
+
"./src/team-chat-plain.js",
|
|
17
|
+
"./src/assistant-plain.js"
|
|
17
18
|
],
|
|
18
19
|
"main": "./src/index.ts",
|
|
19
20
|
"types": "./src/index.ts",
|
|
@@ -67,6 +68,7 @@
|
|
|
67
68
|
"./kit-plain.js": "./src/kit-plain.js",
|
|
68
69
|
"./team-chat.css": "./src/team-chat.css",
|
|
69
70
|
"./team-chat-plain.js": "./src/team-chat-plain.js",
|
|
71
|
+
"./assistant-plain.js": "./src/assistant-plain.js",
|
|
70
72
|
"./assistant": "./src/assistant/index.ts",
|
|
71
73
|
"./assistant/dock": "./src/assistant/dock.ts",
|
|
72
74
|
"./assistant/markdown": "./src/assistant/chat-markdown.ts",
|
|
@@ -92,6 +94,7 @@
|
|
|
92
94
|
"src/service-switcher-plain.js",
|
|
93
95
|
"src/auth-sso-plain.js",
|
|
94
96
|
"src/team-chat-plain.js",
|
|
97
|
+
"src/assistant-plain.js",
|
|
95
98
|
"src/icon.svg",
|
|
96
99
|
"!src/**/*.test.*",
|
|
97
100
|
"gemboss-ui.css",
|
package/parts/components.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @gemboss/ui components.css — GENERATED by packages/ui/scripts/build-css.mjs from export:ui + export:field + src/kit-plain.css; do not edit
|
|
3
|
-
* gemboss commit:
|
|
3
|
+
* gemboss commit: bf4b8350d9402ab9f5d025fa5438a78fb347b8e3
|
|
4
4
|
*/
|
|
5
5
|
:root{--ui-surface: #ffffff;--ui-surface: var(--gemboss-surface, #ffffff);--ui-surface-2: var(--gemboss-hover, #eceef2);--ui-text: var(--gemboss-text, #1b1c1e);--ui-text-muted: var(--gemboss-text-muted, #686b71);--ui-border: var(--gemboss-divider, #e5e7ea);--ui-accent: var(--gemboss-primary, #1b1c1e);--ui-accent-hover: var(--gemboss-primary-dark, #000000);--ui-accent-fg: #ffffff;--ui-accent-soft: var(--gemboss-active-bg, #f0f1f4);--ui-accent-strong: var(--gemboss-active-fg, #1b1c1e);--ui-text-strong: var(--gemboss-text-strong, #1b1c1e);--ui-success-fg: var(--gemboss-success);--ui-warning-fg: var(--gemboss-primary-dark);--ui-danger-fg: var(--gemboss-danger-strong);--ui-focus: var(--gemboss-accent, #5661f5);--ui-radius-sm: 6px;--ui-radius-md: 8px;--ui-radius-lg: 12px;--ui-space-1: 4px;--ui-space-2: 8px;--ui-space-3: 12px;--ui-space-4: 16px;--ui-control-h: 32px;--ui-btn-h: 28px;--ui-card-shadow: 0 1px 0 rgba(26,26,26,.07);--ui-fs-body: 13px;--ui-fs-caption: 12px;--ui-content-max: 900px}.gemboss-admin-shell{--ui-surface: var(--adm-surface);--ui-surface-2: var(--adm-surface-2);--ui-text: var(--adm-text);--ui-text-muted: var(--adm-muted);--ui-border: var(--adm-divider);--ui-accent: var(--adm-accent);--ui-accent-hover: var(--gemboss-primary-dark, #000000);--ui-accent-fg: #ffffff;--ui-accent-soft: var(--adm-accent-soft);--ui-accent-strong: var(--adm-accent-fg);--ui-text-strong: var(--adm-text-strong);--ui-success-fg: color-mix(in srgb, var(--gemboss-success) 70%, #ffffff);--ui-warning-fg: color-mix(in srgb, #c99a2e 70%, #ffffff);--ui-danger-fg: color-mix(in srgb, var(--gemboss-danger-strong) 70%, #ffffff);--ui-focus: var(--adm-accent);--ui-card-shadow: none}.ui-btn{display:inline-flex;align-items:center;justify-content:center;gap:var(--ui-space-2);height:var(--ui-btn-h);padding:0 var(--ui-space-3);box-sizing:border-box;line-height:1;white-space:nowrap;vertical-align:middle;border-radius:var(--ui-radius-md);font-family:inherit;font-size:var(--ui-fs-caption);font-weight:550;cursor:pointer;text-decoration:none;user-select:none;border:1px solid var(--ui-border);background:transparent;color:var(--ui-text);transition:background .12s ease,border-color .12s ease}.ui-btn:hover{background:var(--ui-surface-2);text-decoration:none}.ui-btn:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-btn[disabled],.ui-btn[aria-disabled=true]{opacity:.5;cursor:not-allowed}.ui-btn--primary{background:var(--ui-accent);border-color:var(--ui-accent);color:var(--ui-accent-fg)}.ui-btn--primary:hover{background:var(--ui-accent-hover);border-color:var(--ui-accent-hover)}.ui-btn--ghost{border-color:transparent;background:transparent;color:var(--ui-text-muted)}.ui-btn--ghost:hover{background:var(--ui-surface-2);color:var(--ui-text)}.ui-btn--on,.ui-btn--on:hover{background:var(--ui-accent-soft);border-color:var(--ui-accent);color:var(--ui-accent-strong)}.ui-card{background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-card-shadow);padding:var(--ui-space-4);color:var(--ui-text)}.ui-card__title{font-size:14px;line-height:20px;font-weight:650;margin:0 0 var(--ui-space-2)}.ui-card__head{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--ui-space-2);margin-bottom:var(--ui-space-2)}.ui-card__head>.ui-card__title{margin:0}.ui-card__head>:last-child:not(.ui-card__title){display:flex;flex-wrap:wrap;gap:var(--ui-space-2)}.ui-select{height:var(--ui-control-h);padding:0 32px 0 12px;max-width:100%;background:var(--gemboss-field-bg) url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 20 20'><path fill='%239a9aa4' d='M5 7l5 5 5-5z'/></svg>") no-repeat right 10px center;border:1px solid var(--gemboss-field-line);border-radius:var(--ui-radius-md);color:var(--gemboss-field-ink);font-family:inherit;font-size:var(--ui-fs-body);font-weight:450;appearance:none;-webkit-appearance:none;cursor:pointer}.ui-select:hover:not(:disabled){border-color:var(--gemboss-field-line-hover);background-color:var(--gemboss-field-bg-hover)}.ui-select:focus{outline:none}.ui-select:focus-visible:not(:disabled){outline:2px solid var(--ui-focus);outline-offset:1px;border-color:var(--gemboss-field-line-active)}.ui-select:disabled{opacity:.5;cursor:not-allowed}.ui-select--slim{height:30px;font-size:var(--ui-fs-caption)}.ui-tag{display:inline-flex;align-items:center;gap:6px;font-size:var(--ui-fs-caption);line-height:20px;font-weight:450;padding:0 6px;border-radius:var(--ui-radius-md);background:var(--ui-surface-2);color:var(--ui-text-muted)}.ui-tag--accent{background:var(--adm-accent-soft, rgba(20,22,26,.05));color:var(--adm-accent-fg, var(--ui-accent))}.ui-tag--chip{text-transform:none;letter-spacing:0;font-size:11px;font-weight:500;padding:2px 8px;background:transparent;border:1px solid var(--ui-border);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.ui-tag--chip.ui-tag--accent{color:var(--adm-accent-fg, var(--ui-accent));border-color:var(--ui-accent);background:transparent}.ui-chips{display:flex;flex-wrap:wrap;gap:var(--ui-space-2, 8px);margin:0;padding:0;list-style:none}.ui-chips>a.ui-tag--chip{min-height:28px;padding:4px 12px;border-radius:var(--ui-radius-md, 8px);font-family:inherit;font-size:var(--gemboss-fs-caption, 12px);color:var(--ui-text);text-decoration:none}.ui-chips>a.ui-tag--chip:hover{background:var(--ui-surface-2);border-color:var(--ui-text-muted)}.ui-chips>a.ui-tag--chip:focus-visible{outline:2px solid var(--ui-focus);outline-offset:1px}.ui-chips>a.ui-tag--chip[aria-current=page]{background:var(--ui-accent-soft);border-color:var(--ui-accent);color:var(--ui-accent-strong);font-weight:600}.ui-tag--success{background:var(--gemboss-success-soft);color:var(--gemboss-success-strong, var(--gemboss-success))}.ui-tag--warning{background:var(--gemboss-warning-soft);color:var(--gemboss-warning)}.ui-tag--danger{background:var(--gemboss-danger-soft);color:var(--gemboss-danger-strong, var(--gemboss-danger))}.ui-muted{color:var(--ui-text-muted);font-size:var(--ui-fs-caption)}.ui-page-head{margin-bottom:20px}.ui-page-head h1{color:var(--ui-text-strong);font-size:20px;line-height:24px;font-weight:700;letter-spacing:-.01em}.ui-page-head p{color:var(--ui-text-muted);font-size:var(--ui-fs-body);margin-top:4px}.ui-toolbar{display:flex;flex-wrap:wrap;align-items:center;gap:12px;margin-bottom:20px}.ui-metrics{display:flex;flex-wrap:wrap;gap:8px;margin:2px 0}.ui-metric{display:flex;flex-direction:column;gap:1px;min-width:78px;padding:8px 12px;background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:12px}a.ui-metric{text-decoration:none;color:inherit}a.ui-metric:hover{border-color:var(--ui-text-muted)}a.ui-metric:focus-visible{outline:2px solid var(--ui-focus);outline-offset:1px}.ui-metric__val{font-size:17px;font-weight:700;color:var(--ui-text);font-variant-numeric:tabular-nums;line-height:1.15}.ui-metric__lbl{font-size:var(--ui-fs-caption);font-weight:500;color:var(--ui-text-muted)}.ui-metric--success{border-color:color-mix(in srgb,var(--gemboss-success) 40%,transparent)}.ui-metric--success .ui-metric__val{color:var(--ui-success-fg)}.ui-metric--warning{border-color:color-mix(in srgb,#c99a2e 40%,transparent)}.ui-metric--warning .ui-metric__val{color:var(--ui-warning-fg)}.ui-metric--danger{border-color:color-mix(in srgb,var(--gemboss-danger-strong) 40%,transparent)}.ui-metric--danger .ui-metric__val{color:var(--ui-danger-fg)}.ui-dl{display:grid;grid-template-columns:repeat(auto-fill,minmax(160px,1fr));gap:12px 16px;margin:0}.ui-dl>div{min-width:0}.ui-dl dt{font-size:var(--ui-fs-caption);color:var(--ui-text-muted)}.ui-dl dd{margin:4px 0 0;font-weight:600;color:var(--ui-text);overflow-wrap:anywhere}.ui-notice{padding:12px 16px;border-radius:var(--ui-radius-md);border:1px solid var(--ui-border);background:var(--ui-surface-2);color:var(--ui-text);font-size:var(--ui-fs-body);overflow-wrap:anywhere}.ui-notice--warning{background:var(--gemboss-warning-soft);border-color:var(--gemboss-warning-border);color:var(--gemboss-warning)}.ui-notice--danger{background:var(--gemboss-danger-soft);border-color:var(--gemboss-danger-border);color:var(--gemboss-danger-strong)}.ui-notice--success{background:var(--gemboss-success-soft);border-color:var(--gemboss-success-border);color:var(--gemboss-success-strong)}.ui-pager{display:flex;flex-wrap:wrap;align-items:center;gap:8px;margin:16px 0}.ui-pager>a{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);color:var(--ui-text);text-decoration:none;font-size:var(--ui-fs-body)}.ui-pager>a:hover{background:var(--ui-surface-2)}.ui-pager>a:focus-visible{outline:2px solid var(--ui-focus);outline-offset:1px}.ui-pager>[aria-current=page]{color:var(--ui-text-muted);font-size:var(--ui-fs-caption)}.ui-badge{display:inline-flex;align-items:center;gap:4px;font-size:var(--ui-fs-caption);line-height:16px;font-weight:450;white-space:nowrap;padding:2px 8px;border-radius:var(--ui-radius-md);background:color-mix(in srgb,var(--ui-text) 8%,transparent);color:var(--ui-text-muted)}.ui-overlay{position:fixed;inset:0;z-index:500;background:#00000080;display:grid;place-items:center;padding:20px}.ui-modal{width:min(460px,100%);background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:16px;box-shadow:var(--gemboss-shadow-overlay, 0 20px 60px rgba(0, 0, 0, .4));overflow:hidden}.ui-modal:focus{outline:none}.ui-modal__head{display:flex;align-items:center;gap:12px;padding:12px 16px;border-bottom:1px solid var(--ui-border);font-size:14px;line-height:20px;font-weight:650;color:var(--ui-text)}.ui-modal__title{min-width:0;flex:1 1 auto}.ui-modal__close{flex:0 0 auto;display:inline-flex;align-items:center;justify-content:center;width:28px;height:28px;padding:0;border:0;border-radius:var(--ui-radius-md, 8px);background:transparent;color:var(--ui-text-muted);cursor:pointer}.ui-modal__close svg{width:20px;height:20px}.ui-modal__close:hover{background:var(--ui-surface-2);color:var(--ui-text)}.ui-modal__close:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-modal__body{padding:16px}.ui-modal__foot{display:flex;flex-wrap:wrap;gap:8px;justify-content:flex-end;padding:12px 16px;border-top:1px solid var(--ui-border)}@media (pointer: coarse),(max-width: 47.9975em){.ui-modal__close{width:44px;height:44px;margin:-8px -8px -8px 0}:is(.ui-modal__head,.ui-modal__foot) .ui-btn{min-height:44px}}.ui-modal--lg{position:relative}.ui-textarea{width:100%;min-height:96px;resize:vertical;box-sizing:border-box;background:var(--gemboss-field-bg);border:1px solid var(--gemboss-field-line);border-radius:var(--ui-radius-md);padding:12px;color:var(--gemboss-field-ink);font-size:var(--ui-fs-body);line-height:1.5;font-family:inherit}.ui-textarea::placeholder{color:var(--gemboss-field-placeholder)}.ui-textarea:hover:not(:disabled){border-color:var(--gemboss-field-line-hover);background-color:var(--gemboss-field-bg-hover)}.ui-textarea:focus{outline:none}.ui-textarea:focus-visible:not(:disabled){outline:2px solid var(--ui-focus);outline-offset:1px;border-color:var(--gemboss-field-line-active)}.ui-textarea:disabled{opacity:.5;cursor:not-allowed}@media (max-width: 47.9975em){.ui-select.ui-select,.ui-textarea{font-size:16px}.ui-select:not(.ui-select--slim){min-height:44px}}.ui-seg{display:inline-flex;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);overflow:hidden;overflow:clip;min-width:0}.ui-seg :is(button,a){display:inline-grid;place-items:center;width:calc(var(--ui-btn-h) - 2px);height:calc(var(--ui-btn-h) - 2px);border:0;background:transparent;color:var(--ui-text-muted);cursor:pointer;font-family:inherit}.ui-seg :is(button,a).is-text{width:auto;padding:0 12px;font-size:var(--ui-fs-caption);font-weight:550;grid-auto-flow:column;column-gap:2px}.ui-seg :is(button,a)+:is(button,a){border-left:1px solid var(--ui-border)}.ui-seg :is(button,a):hover{background:var(--ui-surface-2);color:var(--ui-text)}.ui-seg :is(button,a):focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-seg a{display:inline-flex;align-items:center;justify-content:center;text-decoration:none;color:var(--ui-text-muted)}.ui-seg a[aria-current=page],.ui-seg button.active{background:var(--ui-accent-soft);color:var(--ui-accent-strong)}.ui-seg svg{width:16px;height:16px;fill:currentColor}.ui-seg svg[fill=none]{fill:none}.ui-seg :is(button,a):is(:disabled,[aria-disabled=true]){opacity:.45;cursor:not-allowed}.ui-seg :is(button,a):is(:disabled,[aria-disabled=true]):not(.active):hover{background:transparent;color:var(--ui-text-muted)}.ui-seg--fill{display:flex;width:100%}.ui-seg.ui-seg--fill>:is(button,a).is-text{flex:1 1 0;min-width:0}.ui-seg-n{margin-left:6px;font-variant-numeric:tabular-nums;color:var(--ui-text-muted);font-weight:450}.ui-stats{display:flex;flex-wrap:wrap;gap:var(--ui-space-2);margin-bottom:24px}.ui-stat{display:inline-flex;align-items:center;gap:var(--ui-space-2);padding:6px 12px;border-radius:999px;font-family:inherit;background:var(--ui-surface);border:1px solid var(--ui-border);font-size:var(--ui-fs-caption);color:var(--ui-text-muted)}.ui-stat b{color:var(--ui-text-strong);font-weight:650}.ui-stat.is-clickable{cursor:pointer;transition:border-color .14s ease,background-color .14s ease}.ui-stat.is-clickable:hover{border-color:var(--ui-text-muted);background:var(--ui-surface-2)}.ui-stat.is-clickable.active{border-color:var(--ui-accent);background:var(--ui-accent-soft);color:var(--ui-accent-strong)}.ui-stat.is-clickable.active b{color:var(--ui-accent-strong)}.gemboss-toast-viewport{position:fixed;left:50%;bottom:24px;transform:translate(-50%);z-index:2147483000;display:flex;flex-direction:column;align-items:center;gap:12px;width:max-content;max-width:min(560px,calc(100vw - 32px));pointer-events:none}.gemboss-toast{pointer-events:auto;display:flex;align-items:center;gap:12px;min-width:220px;max-width:100%;padding:12px 12px 12px 16px;background:var(--ui-text-strong, #1a1917);color:var(--gemboss-on-primary, #fff);border-radius:12px;font-size:var(--ui-fs-body, 13px);line-height:1.4;font-weight:500;box-shadow:var(--gemboss-shadow-overlay, 0 8px 28px rgba(0, 0, 0, .24));animation:gemboss-toast-in .24s cubic-bezier(.16,1,.3,1)}.gemboss-toast.is-error{background:var(--gemboss-danger, #d72c0d)}.gemboss-toast-text{flex:1 1 auto;min-width:0}.gemboss-toast-action{flex:0 0 auto;border:0;background:transparent;color:var(--gemboss-on-primary, #fff);cursor:pointer;padding:4px 8px;border-radius:8px;font:inherit;font-weight:650;text-decoration:underline;text-underline-offset:2px;transition:background .14s ease}.gemboss-toast-action:hover{background:#ffffff29}.gemboss-toast-dismiss{flex:0 0 auto;display:inline-grid;place-items:center;width:24px;height:24px;border:0;border-radius:8px;cursor:pointer;background:#ffffff1f;color:var(--gemboss-on-primary, #fff);transition:background .14s ease}.gemboss-toast-dismiss:hover{background:#ffffff42}.gemboss-toast-action:focus-visible,.gemboss-toast-dismiss:focus-visible{outline:2px solid var(--gemboss-on-primary, #fff);outline-offset:2px}@keyframes gemboss-toast-in{0%{opacity:0;transform:translateY(12px)}to{opacity:1;transform:translateY(0)}}@media (prefers-reduced-motion: reduce){.gemboss-toast{animation:none}}@media (max-width: 47.9975em){.ui-btn:not(.ui-btn--sm),.ui-seg :is(button,a){min-height:44px}.ui-seg :is(button,a):not(.is-text){min-width:44px}}@media (pointer: coarse){.ui-btn:not(.ui-btn--sm),.ui-stat.is-clickable,.ui-chips>a.ui-tag--chip,.ui-pager>a,.ui-seg :is(button,a){min-height:44px}.ui-stat.is-clickable{min-width:44px;justify-content:center}.ui-chips>a.ui-tag--chip{min-width:44px;justify-content:center}.ui-select.ui-select,.ui-select--slim.ui-select--slim{min-height:44px}.ui-seg :is(button,a){min-width:44px}}.ui-skeleton{display:flex;flex-direction:column;gap:var(--ui-space-2)}.ui-skeleton__line{display:block;height:12px;border-radius:6px;background:linear-gradient(90deg,var(--ui-surface-2) 25%,var(--ui-border) 37%,var(--ui-surface-2) 63%);background-size:400% 100%;animation:ui-skeleton-sheen 1.4s ease-in-out infinite}@keyframes ui-skeleton-sheen{0%{background-position:100% 50%}to{background-position:0 50%}}@media (prefers-reduced-motion: reduce){.ui-skeleton__line{animation:none;background:var(--ui-surface-2)}}.ui-sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.ui-resizer{cursor:col-resize;position:relative;touch-action:none;outline:none}.ui-resizer:before{content:"";position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);width:4px;height:44px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-primary);opacity:0;transition:opacity .14s ease,height .14s ease}.ui-resizer:hover:before,.ui-resizer:focus-visible:before,.ui-resizer.dragging:before,body.ui-resizing .ui-resizer:before{opacity:1;height:52px}@media (pointer: coarse){.ui-resizer:after{content:"";position:absolute;inset:0 -14px;touch-action:none;z-index:2}}body.ui-resizing,body.ui-resizing *{cursor:col-resize!important;user-select:none!important}body.ui-resizing:after{content:"";position:fixed;inset:0;z-index:9999;cursor:col-resize}.ui-tabs{display:flex;gap:var(--ui-space-2);border-bottom:1px solid var(--ui-border);overflow-x:auto;scrollbar-width:none}.ui-tabs>button,.ui-tabs>a{position:relative;flex:0 0 auto;display:inline-flex;align-items:center;gap:var(--ui-space-2);min-height:var(--ui-btn-h);padding:0 var(--ui-space-3);border:0;background:transparent;cursor:pointer;border-radius:var(--ui-radius-sm) var(--ui-radius-sm) 0 0;font-family:inherit;font-size:var(--ui-fs-caption);font-weight:550;white-space:nowrap;color:var(--ui-text-muted);transition:color var(--gemboss-transition-fast) ease,background-color var(--gemboss-transition-fast) ease}.ui-tabs>button:hover,.ui-tabs>a:hover{color:var(--ui-text);background:var(--ui-surface-2)}.ui-tabs>button:focus-visible,.ui-tabs>a:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-tabs>a{text-decoration:none}.ui-tabs>a[aria-current=page],.ui-tabs>button[aria-selected=true]{color:var(--ui-text-strong)}.ui-tabs>a[aria-current=page]:after,.ui-tabs>button[aria-selected=true]:after{content:"";position:absolute;left:var(--ui-space-3);right:var(--ui-space-3);bottom:0;height:2px;border-radius:var(--gemboss-radius-full);background:var(--ui-accent)}.ui-tabs>button:disabled{opacity:.5;cursor:not-allowed}@media (pointer: coarse),(max-width: 47.9975em){.ui-tabs>:is(button,a){min-height:44px}}.ui-table-wrap{overflow-x:auto;max-width:100%;background:var(--ui-surface);border:1px solid var(--ui-border);border-radius:var(--ui-radius-lg);box-shadow:var(--ui-card-shadow)}.ui-table{width:100%;border-collapse:collapse;font-size:var(--ui-fs-body);color:var(--ui-text)}.ui-table th,.ui-table td{padding:var(--ui-space-2) 6px;text-align:left;vertical-align:middle;border-bottom:1px solid var(--ui-border)}.ui-table :is(th,td):where(:first-child){padding-left:var(--ui-space-3)}.ui-table :is(th,td):where(:last-child){padding-right:var(--ui-space-3)}.ui-table th{font-weight:450;color:var(--ui-text-muted);white-space:nowrap}.ui-table thead th{padding-block:var(--ui-space-3)}.ui-table tbody tr:last-child>:is(td,th){border-bottom:0}.ui-table tbody tr:hover{background:var(--ui-surface-2)}.ui-table .is-num{text-align:right;font-variant-numeric:tabular-nums;white-space:nowrap}.ui-table td>a{display:inline-flex;align-items:center;min-height:24px}.ui-table .ui-sub{display:block;margin-top:2px;font-size:var(--ui-fs-caption);color:var(--ui-text-muted);font-weight:400}.ui-empty{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:var(--ui-space-2);padding:var(--ui-space-4);padding-block:40px;text-align:center;color:var(--ui-text-muted);font-size:var(--ui-fs-body)}.ui-empty__title{margin:0;font-size:14px;line-height:20px;font-weight:650;color:var(--ui-text-strong)}.ui-empty__body{margin:0;max-width:48ch;line-height:1.5}.ui-empty>.ui-btn{margin-top:var(--ui-space-2)}.gemboss-field,.gemboss-control{box-sizing:border-box;height:32px;min-width:0;padding:0 12px;font:inherit;font-size:13px;line-height:20px;color:var(--gemboss-field-ink);background-color:var(--gemboss-field-bg);border:1px solid var(--gemboss-field-line);border-radius:8px}input[type=search]:is(.gemboss-field,.gemboss-field__bare){-webkit-appearance:none;appearance:none}.gemboss-field::placeholder{color:var(--gemboss-field-placeholder)}.gemboss-field--tall{min-height:44px}.gemboss-field--narrow{padding:0 6px;appearance:textfield;-moz-appearance:textfield}.gemboss-field--narrow::-webkit-outer-spin-button,.gemboss-field--narrow::-webkit-inner-spin-button{-webkit-appearance:none;margin:0}.gemboss-field:hover:not(:disabled):not(:has(>.gemboss-field__bare:disabled)),.gemboss-control:hover:not(:disabled){border-color:var(--gemboss-field-line-hover);background-color:var(--gemboss-field-bg-hover)}.gemboss-field:focus-visible,.gemboss-control:focus-visible{outline:2px solid var(--ui-focus, #5661f5);outline-offset:1px;border-color:var(--gemboss-field-line-active)}.gemboss-field:disabled,.gemboss-control:disabled{opacity:.5;cursor:not-allowed}@media (max-width: 47.9975em){.gemboss-field,.gemboss-control{font-size:16px;min-height:44px}}textarea.gemboss-field{height:auto;padding:6px 12px;resize:vertical}.gemboss-field--group{display:flex;align-items:center;gap:6px;height:auto;min-height:32px;padding-right:0;overflow:hidden}@media (max-width: 47.9975em){.gemboss-field--group{min-height:44px}}.gemboss-field--group:focus-within{outline:2px solid var(--ui-focus, #5661f5);outline-offset:1px;border-color:var(--gemboss-field-line-active)}.gemboss-field--group input[type=color]{flex:none;align-self:stretch;width:44px;min-width:44px;height:auto;min-height:0;margin:-1px 0 -1px -12px;padding:0;border:0;border-right:1px solid var(--gemboss-field-line);border-radius:0;background:none;cursor:pointer}.gemboss-field--group input[type=color]::-webkit-color-swatch-wrapper{padding:0}.gemboss-field--group input[type=color]::-webkit-color-swatch{border:0;border-radius:0}.gemboss-field__bare{flex:1;min-width:0;align-self:stretch;margin-block:-1px;padding:0 12px 0 0;border:0;border-radius:0;outline:none;background:transparent;color:inherit;font:inherit}.gemboss-field__bare::placeholder{color:var(--gemboss-field-placeholder)}.gemboss-field__suffix{flex:none;padding-right:12px;color:var(--gemboss-field-placeholder)}.gemboss-field__bare:has(+.gemboss-field__suffix){padding-right:0}.gemboss-field--group:has(>.gemboss-field__bare:disabled){opacity:.5;cursor:not-allowed}.gemboss-field__bare:disabled{cursor:not-allowed}@media (pointer: coarse){.gemboss-field,.gemboss-control{height:auto;min-height:44px}}.gemboss-control{cursor:pointer}.gemboss-control.gemboss-control--icon{width:32px;flex:0 0 auto;padding:0}@media (pointer: coarse){.gemboss-control.gemboss-control--icon{width:44px;min-width:44px}}.ui-btn--icon{flex:none;width:var(--ui-btn-h);padding:0}.ui-btn--icon svg{width:18px;height:18px}.ui-menu{position:relative;display:inline-block}.ui-menu>summary{list-style:none;cursor:pointer}.ui-menu>summary::-webkit-details-marker{display:none}.ui-menu__list{position:absolute;z-index:20;top:calc(100% + 4px);left:0;display:grid;min-width:220px;padding:var(--ui-space-1);box-sizing:border-box}.ui-menu--end .ui-menu__list{left:auto;right:0}.ui-menu__list[popover]{position:fixed;inset:auto;margin:0;overflow:auto}.ui-menu__list[popover]:not(:popover-open){display:none}:where(.ui-menu__list[popover]){border:0;background:none;color:inherit}:root[data-gb-menus=float] .ui-menu[open]>.ui-menu__list:not([popover]){visibility:hidden}.ui-menu__item:is([disabled],[aria-disabled=true]){opacity:.5;cursor:not-allowed;pointer-events:none}.ui-menu__hint{margin-left:auto;padding-left:var(--ui-space-4);color:var(--ui-text-muted);font-size:var(--ui-fs-caption)}.ui-menu__sep{height:1px;margin:var(--ui-space-1) 0;border:0;background:var(--ui-border)}.ui-check{display:inline-flex;align-items:center;gap:var(--ui-space-2);min-height:44px;max-width:100%;overflow-wrap:break-word;cursor:pointer;font-size:var(--ui-fs-body);color:var(--ui-text)}.ui-check>input{flex:none;width:18px;height:18px;margin:0;accent-color:var(--ui-accent);cursor:inherit}.ui-check>input:focus-visible{outline:2px solid var(--ui-focus);outline-offset:2px}.ui-check:has(>input:disabled){opacity:.5;cursor:not-allowed}.ui-check>:last-child:not(input){min-width:0}.ui-label{display:block;margin:0 0 var(--ui-space-1);font-size:var(--ui-fs-caption);font-weight:600;color:var(--ui-text-muted)}.ui-kv{display:grid;grid-template-columns:max-content minmax(0,1fr);gap:var(--ui-space-2) var(--ui-space-4);margin:0;font-size:var(--ui-fs-body)}.ui-kv>dt{color:var(--ui-text-muted)}.ui-kv>dd{margin:0;min-width:0;overflow-wrap:anywhere;color:var(--ui-text)}@media (pointer: coarse){.ui-btn--icon:not(.ui-btn--sm){min-width:44px}}@media (max-width: 47.9975em){.ui-btn--icon:not(.ui-btn--sm){min-width:44px;min-height:44px}}.ui-link,.ui-prose :where(a:not([class])){color:var(--gemboss-accent-strong, #3a44de);text-decoration:underline;text-decoration-thickness:from-font;text-underline-offset:2px}.ui-link:visited,.ui-prose :where(a:not([class])):visited{color:var(--gemboss-accent-strong, #3a44de)}.ui-link:hover,.ui-prose :where(a:not([class])):hover{color:var(--gemboss-accent, #5661f5);text-decoration-thickness:2px}.ui-link:focus-visible,.ui-prose :where(a:not([class])):focus-visible{outline:2px solid var(--ui-focus, #5661f5);outline-offset:2px;border-radius:2px}.ui-card--media{position:relative;padding:0;overflow:hidden;display:flex;flex-direction:column}.ui-card__link{display:-webkit-box;-webkit-box-orient:vertical;-webkit-line-clamp:2;line-clamp:2;overflow:hidden;color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;font-weight:650;text-decoration:none;overflow-wrap:anywhere}.ui-card__link:after{content:"";position:absolute;inset:0;z-index:0}.ui-card__link:focus-visible{outline:none}.ui-card--media:has(.ui-card__link){cursor:pointer}.ui-card--media:has(.ui-card__link:hover){border-color:var(--ui-text-muted)}.ui-card--media:has(.ui-card__link:focus-visible){outline:2px solid var(--ui-focus);outline-offset:1px}.ui-card--media :is(.ui-card__foot button,.ui-card__foot a,.ui-card__body a:not(.ui-card__link),.ui-card__body button,select,input,summary){position:relative;z-index:1}.ui-card__menu{position:absolute;top:8px;right:8px;z-index:2}.ui-card--media:has(>.ui-card__menu){overflow:visible}.ui-card--media:has(>.ui-card__menu)>.ui-card__media{border-radius:inherit;border-bottom-left-radius:0;border-bottom-right-radius:0}.ui-card__meta{color:var(--ui-text-muted);font-size:var(--ui-fs-caption);line-height:16px}.ui-card--media[data-ratio="4/3"]>.ui-card__media{aspect-ratio:4 / 3}.ui-card--media[data-ratio="1/1"]>.ui-card__media{aspect-ratio:1 / 1}.ui-card__media{display:block;width:100%;aspect-ratio:16 / 10;margin:0;padding:0;border:0;border-bottom:1px solid var(--ui-border);background:var(--ui-surface-2);overflow:hidden;color:inherit}.ui-card__media>img{display:block;width:100%;height:100%;object-fit:cover}button.ui-card__media,a.ui-card__media{cursor:pointer}.ui-card__media:focus-visible{outline:2px solid var(--ui-focus, #5661f5);outline-offset:-2px}.ui-card__body{display:grid;justify-items:start;gap:var(--ui-space-2, 8px);padding:var(--ui-space-3, 12px) var(--ui-space-4, 16px);min-width:0}.ui-card__foot{display:flex;flex-wrap:wrap;align-items:center;justify-content:space-between;gap:var(--ui-space-2, 8px);margin-top:auto;padding:0 var(--ui-space-4, 16px) var(--ui-space-3, 12px);color:var(--ui-text-muted);font-size:var(--ui-fs-caption, 13px)}.ui-modal__subtitle{display:block;margin-top:2px;font-size:var(--ui-fs-caption);line-height:16px;font-weight:450;color:var(--ui-text-muted);overflow-wrap:anywhere}.ui-modal__actions{flex:none;display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2)}.ui-overlay>.ui-modal{display:flex;flex-direction:column;max-height:calc(100dvh - 40px)}.ui-modal>.ui-modal__head,.ui-modal>.ui-modal__foot{flex:none}.ui-modal>.ui-modal__body{flex:1 1 auto;min-height:0;overflow:auto}:root{--ui-series-1: var(--gemboss-accent, #5661f5);--ui-series-2: #0f9f8f;--ui-series-3: #d9822b;--ui-series-4: #c2417a;--ui-series-5: #6b7280}.ui-delta{display:inline-flex;flex-wrap:wrap;align-items:baseline;gap:2px;font-size:var(--gemboss-fs-caption);font-weight:600;color:var(--ui-text-muted);font-variant-numeric:tabular-nums}.ui-delta--good{color:var(--ui-success-fg)}.ui-delta--bad{color:var(--ui-danger-fg)}.ui-metrics--grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(min(180px,100%),1fr));gap:var(--ui-space-3);margin:0}.ui-metric--lg{gap:4px;padding:var(--ui-space-3) var(--ui-space-4)}.ui-metric--lg .ui-metric__val{font-size:24px;line-height:32px}.ui-metric--lg .ui-metric__lbl{order:-1;font-size:var(--ui-fs-body)}.ui-metric__foot{display:flex;flex-wrap:wrap;align-items:baseline;gap:4px 8px;font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted)}@media (max-width: 520px){.ui-metrics--grid{grid-template-columns:repeat(2,minmax(0,1fr))}}.ui-barlist{display:grid;gap:var(--ui-space-3);margin:0;padding:0;list-style:none;font-size:var(--ui-fs-body, 13px)}.ui-barlist>li{display:grid;grid-template-columns:minmax(0,1fr) auto;align-items:baseline;gap:4px var(--ui-space-3)}.ui-barlist__label{min-width:0;overflow-wrap:anywhere;color:var(--ui-text)}.ui-barlist__label a{color:inherit}.ui-barlist__val{font-weight:600;color:var(--ui-text);font-variant-numeric:tabular-nums;white-space:nowrap;text-align:right}.ui-barlist__share{margin-left:6px;font-weight:400;color:var(--ui-text-muted)}.ui-barlist__note{grid-column:1 / -1;margin-top:-2px;font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted)}.ui-barlist__bar{grid-column:1 / -1;position:relative;height:6px;border-radius:999px;background:var(--ui-surface-2);overflow:hidden}.ui-barlist__bar:after{content:"";position:absolute;inset:0 auto 0 0;width:calc(var(--v, 0) * 100%);min-width:3px;border-radius:inherit;background:var(--c, var(--ui-series-1))}.ui-chart{margin:0}.ui-chart__plot{position:relative;display:flex;align-items:flex-end;justify-content:space-between;gap:3px;height:180px;padding-top:18px;border-bottom:1px solid var(--ui-border);background:linear-gradient(to top,var(--ui-border) 1px,transparent 1px) 0 0 / 100% 25% repeat-y;background-origin:content-box;background-clip:content-box}.ui-chart__plot[data-max]:before{content:attr(data-max);position:absolute;top:0;left:0;font-size:var(--gemboss-fs-micro, 11px);line-height:1;color:var(--ui-text-muted);font-variant-numeric:tabular-nums}.ui-chart__col{position:relative;flex:1 1 0;min-width:0;max-width:48px;height:100%;display:flex;flex-direction:column-reverse}.ui-chart__col:hover{background:color-mix(in srgb,var(--ui-text) 6%,transparent)}.ui-chart__seg{display:block;flex:none;height:calc(var(--v, 0) * 100%);background:var(--c, var(--ui-series-1))}.ui-chart__dot{position:absolute;left:50%;bottom:calc(var(--v, 0) * 100%);width:8px;height:8px;margin:0 0 -4px -4px;box-sizing:border-box;border-radius:50%;background:var(--ui-surface);border:2px solid var(--c, var(--ui-text-strong, var(--ui-text)))}.ui-chart__axis{display:flex;justify-content:space-between;gap:var(--ui-space-2);margin-top:6px;font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted);font-variant-numeric:tabular-nums}.ui-legend{display:flex;flex-wrap:wrap;gap:6px 16px;margin:var(--ui-space-2) 0 0;font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted)}.ui-legend__item{display:inline-flex;align-items:center;gap:6px}.ui-legend__item>i{display:inline-block;width:10px;height:10px;border-radius:2px;background:var(--c, var(--ui-series-1))}.ui-legend__item--dot>i{border-radius:50%;background:var(--ui-surface);border:2px solid var(--c, var(--ui-text-strong, var(--ui-text)));box-sizing:border-box}.ui-funnel{display:grid;grid-auto-flow:column;grid-auto-columns:minmax(0,1fr);gap:var(--ui-space-2);margin:0;padding:0;list-style:none}.ui-funnel>li{position:relative;display:flex;flex-direction:column;gap:2px;padding:var(--ui-space-3);border-radius:var(--ui-radius-md);background:var(--ui-surface-2);min-width:0}.ui-funnel__val{font-size:20px;font-weight:700;color:var(--ui-text);font-variant-numeric:tabular-nums;line-height:24px}.ui-funnel__lbl{font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted);overflow-wrap:anywhere}.ui-funnel__rate{order:-1;font-size:var(--gemboss-fs-caption);font-weight:600;color:var(--ui-series-1);font-variant-numeric:tabular-nums}@media (max-width: 520px){.ui-funnel{grid-auto-flow:row}}.ui-grid{display:grid;gap:var(--ui-space-4);align-items:start}.ui-grid--2{grid-template-columns:repeat(2,minmax(0,1fr))}.ui-grid--3{grid-template-columns:repeat(3,minmax(0,1fr))}@media (max-width: 1100px){.ui-grid--3{grid-template-columns:repeat(2,minmax(0,1fr))}}@media (max-width: 960px){.ui-grid--2{grid-template-columns:minmax(0,1fr)}}@media (max-width: 720px){.ui-grid--3{grid-template-columns:minmax(0,1fr)}}.ui-section-head{margin:var(--ui-space-4) 0 0}.ui-section-head>h2{margin:0;font-size:14px;line-height:20px;font-weight:650;color:var(--ui-text)}.ui-section-head>p{margin:2px 0 0;font-size:var(--gemboss-fs-caption);color:var(--ui-text-muted)}.ui-seg{max-width:100%;overflow-x:auto}.ui-seg :is(button,a).is-text{flex:none;white-space:nowrap}@media (max-width: 360px){.ui-seg :is(button,a).is-text{padding:0 9px}}@media (pointer: coarse),(max-width: 47.9975em){.ui-seg :is(button,a){height:44px;min-height:44px}}.ui-btn--critical{color:var(--gemboss-danger-strong)}.ui-btn--critical:hover{background:var(--gemboss-danger-soft);color:var(--gemboss-danger-strong)}.ui-btn--primary.ui-btn--critical{background:var(--gemboss-danger);border-color:var(--gemboss-danger);color:var(--gemboss-on-primary)}.ui-btn--primary.ui-btn--critical:hover{background:var(--gemboss-danger-strong);border-color:var(--gemboss-danger-strong);color:var(--gemboss-on-primary)}.ui-btn--critical:focus-visible{outline-color:var(--gemboss-danger-strong)}@media (pointer: coarse),(max-width: 47.9975em){.ui-btn,.ui-btn.ui-btn--sm,.ui-select.ui-select{min-height:44px}.ui-btn--icon.ui-btn--sm,.ui-seg :is(button,a):not(.is-text){min-width:44px}}.ui-badge--success{background:var(--gemboss-success-soft);color:var(--gemboss-success-strong)}.ui-badge--warning{background:var(--gemboss-warning-soft);color:var(--gemboss-warning)}.ui-badge--critical{background:var(--gemboss-danger-soft);color:var(--gemboss-danger-strong)}.ui-badge--info{background:var(--gemboss-accent-soft);color:var(--gemboss-accent-strong)}.ui-badge--dot:before{content:"";flex:none;width:6px;height:6px;border-radius:50%;background:currentColor}.ui-banner{--ui-banner-bg: var(--ui-surface-2);--ui-banner-fg: var(--ui-text);border-radius:var(--ui-radius-lg);overflow:hidden;background:var(--ui-surface);color:var(--ui-text);box-shadow:0 0 0 1px var(--ui-border),0 3px 1px -1px #1a1a1a12;font-size:var(--ui-fs-body);line-height:20px}.ui-banner--success{--ui-banner-bg: var(--gemboss-success-soft);--ui-banner-fg: var(--gemboss-success-strong)}.ui-banner--warning{--ui-banner-bg: var(--gemboss-warning-soft);--ui-banner-fg: var(--gemboss-warning)}.ui-banner--critical{--ui-banner-bg: var(--gemboss-danger-soft);--ui-banner-fg: var(--gemboss-danger-strong)}.ui-banner--info{--ui-banner-bg: var(--gemboss-accent-soft);--ui-banner-fg: var(--gemboss-accent-strong)}.ui-banner__head{display:flex;align-items:center;gap:var(--ui-space-2);min-height:32px;padding:6px var(--ui-space-3);background:var(--ui-banner-bg);color:var(--ui-banner-fg)}.ui-banner__icon{flex:none;width:20px;height:20px;fill:currentColor}.ui-banner__title{flex:1 1 auto;min-width:0;margin:0;font-size:var(--ui-fs-body);font-weight:650;line-height:20px}.ui-banner__close{flex:none;display:inline-grid;place-items:center;width:32px;height:32px;margin:-6px -8px -6px 0;border:0;border-radius:var(--ui-radius-md);background:transparent;color:inherit;cursor:pointer}.ui-banner__close:hover{background:color-mix(in srgb,currentColor 10%,transparent)}.ui-banner__close:focus-visible{outline:2px solid var(--ui-focus);outline-offset:-2px}.ui-banner__close svg{width:16px;height:16px}.ui-banner__body{padding:var(--ui-space-3) var(--ui-space-4)}.ui-banner__body>:first-child{margin-top:0}.ui-banner__body>:last-child{margin-bottom:0}.ui-banner__actions{display:flex;flex-wrap:wrap;gap:var(--ui-space-2);margin-top:var(--ui-space-3)}@media (pointer: coarse),(max-width: 47.9975em){.ui-banner__close{width:44px;height:44px;margin:-12px -12px -12px 0}}.ui-help{margin:var(--ui-space-1) 0 0;font-size:var(--ui-fs-body);line-height:20px;color:var(--ui-text-muted)}.ui-error:empty{display:none}.ui-error{display:flex;gap:6px;margin:var(--ui-space-1) 0 0;font-size:var(--ui-fs-body);line-height:20px;color:var(--gemboss-danger-strong)}.ui-error:before{content:"";flex:none;width:16px;height:16px;margin-top:2px;background:currentColor;-webkit-mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 4h1.5v5.5h-1.5V6Zm.75 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'/></svg>") center / contain no-repeat;mask:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 20 20'><path d='M10 2a8 8 0 1 0 0 16 8 8 0 0 0 0-16Zm-.75 4h1.5v5.5h-1.5V6Zm.75 9a1 1 0 1 1 0-2 1 1 0 0 1 0 2Z'/></svg>") center / contain no-repeat}.gemboss-field[aria-invalid=true],.gemboss-field--group:has([aria-invalid=true]),.ui-select[aria-invalid=true],.ui-textarea[aria-invalid=true]{border-color:var(--gemboss-danger-strong);background-color:var(--gemboss-danger-soft)}.ui-choices{display:grid;grid-template-columns:minmax(0,1fr);gap:0;margin:0;padding:0;border:0;min-width:0}.ui-choices>legend{padding:0}.ui-switch>input[type=checkbox]{appearance:none;-webkit-appearance:none;position:relative;width:32px;height:20px;margin:0;border-radius:var(--gemboss-radius-full);background:var(--gemboss-field-line);transition:background-color var(--gemboss-transition-fast) ease}.ui-switch>input[type=checkbox]:before{content:"";position:absolute;top:2px;left:2px;width:16px;height:16px;border-radius:50%;background:var(--gemboss-surface);box-shadow:0 1px 2px #0003;transition:transform var(--gemboss-transition-fast) ease}.ui-switch>input[type=checkbox]:checked{background:var(--ui-accent)}.ui-switch>input[type=checkbox]:checked:before{transform:translate(12px)}@media (prefers-reduced-motion: reduce){.ui-switch>input[type=checkbox],.ui-switch>input[type=checkbox]:before{transition:none}}.ui-tooltip{position:relative;display:inline-flex}.ui-tooltip__bubble{position:absolute;z-index:30;bottom:calc(100% + 8px);left:50%;transform:translate(-50%);width:max-content;max-width:240px;padding:4px 8px;border-radius:var(--ui-radius-md);background:var(--ui-surface);color:var(--ui-text);font-size:var(--ui-fs-body);line-height:20px;font-weight:450;box-shadow:0 8px 16px -4px #1a1a1a38,0 0 0 1px var(--ui-border);opacity:0;visibility:hidden;pointer-events:none;transition:opacity var(--gemboss-transition-fast) ease}.ui-tooltip--end .ui-tooltip__bubble{left:auto;right:0;transform:none}.ui-tooltip:hover>.ui-tooltip__bubble,.ui-tooltip:focus-within>.ui-tooltip__bubble{opacity:1;visibility:visible}.ui-spinner{display:inline-block;flex:none;width:20px;height:20px;box-sizing:border-box;border-radius:50%;border:2px solid color-mix(in srgb,var(--ui-text) 18%,transparent);border-top-color:var(--ui-text);animation:ui-spin .7s linear infinite;vertical-align:middle}.ui-spinner--lg{width:44px;height:44px;border-width:4px}@keyframes ui-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.ui-spinner{animation-duration:2s}}.ui-progress{appearance:none;-webkit-appearance:none;display:block;width:100%;height:8px;border:0;border-radius:var(--gemboss-radius-full);overflow:hidden;background:var(--gemboss-divider);color:var(--ui-accent)}.ui-progress::-webkit-progress-bar{background:var(--gemboss-divider);border-radius:inherit}.ui-progress::-webkit-progress-value{background:currentColor;border-radius:inherit}.ui-progress::-moz-progress-bar{background:currentColor;border-radius:inherit}.ui-progress--success{color:var(--gemboss-success)}.ui-progress--critical{color:var(--gemboss-danger)}.ui-modal--wide{width:min(620px,100%)}dialog.ui-modal{padding:0;max-width:calc(100% - 40px);max-height:calc(100dvh - 40px);color:var(--ui-text)}dialog.ui-modal[open]{display:flex;flex-direction:column}dialog.ui-modal::backdrop{background:#00000080}html:has(dialog.ui-modal:modal){overflow:hidden}@media (pointer: coarse),(max-width: 47.9975em){.ui-btn.ui-btn--sm{min-width:44px}}.ui-badge--wrap{white-space:normal;overflow-wrap:anywhere;line-height:16px}.ui-page-head--actions{display:flex;flex-wrap:wrap;align-items:flex-end;justify-content:space-between;gap:12px 16px}.ui-page-head--actions>:first-child{min-width:0}.ui-page-head__actions{display:flex;flex-wrap:wrap;align-items:center;gap:var(--ui-space-2)}.ui-chips>button.ui-tag--chip{min-height:28px;padding:4px 12px;border-radius:var(--ui-radius-md, 8px);cursor:pointer;font-family:inherit;font-size:var(--gemboss-fs-caption, 12px);color:var(--ui-text)}.ui-chips>button.ui-tag--chip:hover{background:var(--ui-surface-2);border-color:var(--ui-text-muted)}.ui-chips>button.ui-tag--chip:focus-visible{outline:2px solid var(--ui-focus, #5661f5);outline-offset:1px}.ui-chips>button.ui-tag--chip[aria-pressed=true]{background:var(--ui-accent-soft);border-color:var(--ui-accent);color:var(--ui-accent-strong);font-weight:600}@media (pointer: coarse),(max-width: 47.9975em){.ui-chips>button.ui-tag--chip{min-height:44px;min-width:44px;justify-content:center}}@media (max-width: 47.9975em){.gemboss-ec-input.gemboss-ec-input textarea{font-size:16px}}.ui-seg button[aria-pressed=true]{background:var(--ui-accent-soft);color:var(--ui-accent-strong)}:is(.gemboss-field,.ui-textarea)[readonly][readonly]{background:var(--ui-surface-2);border-color:var(--ui-border);cursor:default}.ui-modal>form{display:contents}.ui-modal>form>.ui-modal__head,.ui-modal>form>.ui-modal__foot{flex:none}.ui-modal>form>.ui-modal__body{flex:1 1 auto;min-height:0;overflow:auto}button.ui-metric{font:inherit;text-align:left;color:inherit;cursor:pointer}button.ui-metric:hover{border-color:var(--ui-text-muted)}button.ui-metric:focus-visible{outline:2px solid var(--ui-focus);outline-offset:1px}.ui-metric.ui-metric:is([aria-pressed=true],[aria-current=page]){border-color:var(--gemboss-accent);box-shadow:inset 0 0 0 1px var(--gemboss-accent)}.ui-pager>a,.ui-pager>[aria-disabled=true]{min-width:32px;justify-content:center;box-sizing:border-box;gap:4px}.ui-pager>a[aria-current=page]{background:var(--ui-text);border-color:var(--ui-text);color:var(--ui-surface);font-size:var(--ui-fs-body);font-weight:600}.ui-pager>a[aria-current=page]:hover{background:var(--ui-text)}.ui-pager>[aria-disabled=true]{display:inline-flex;align-items:center;min-height:32px;padding:0 12px;border:1px solid var(--ui-border);border-radius:var(--ui-radius-md);color:var(--ui-text-muted);font-size:var(--ui-fs-body);opacity:.55;cursor:default}.ui-pager>[aria-disabled=true]:hover{background:none}.ui-pager__gap{min-width:16px;text-align:center;color:var(--ui-text-muted)}.ui-pager__range{margin-left:auto;color:var(--ui-text-muted);font-size:var(--ui-fs-body);font-variant-numeric:tabular-nums}.ui-more{display:flex;flex-wrap:wrap;align-items:center;justify-content:center;gap:12px;padding:16px 0;color:var(--ui-text-muted);font-size:var(--ui-fs-body);text-align:center}.ui-more[hidden]{display:none}@media (pointer: coarse),(max-width: 47.9975em){.ui-pager>a,.ui-pager>[aria-disabled=true]{min-width:44px;min-height:44px}}@media (max-width: 35.9975em){.ui-pager>a:not([rel]):not([aria-current]):not([aria-disabled]),.ui-pager__gap{display:none}}.ui-chip{display:inline-flex;align-items:center;justify-content:center;gap:4px;box-sizing:border-box;height:var(--ui-btn-h, 28px);padding:0 12px;border:1px dashed var(--ui-border);border-radius:var(--ui-radius-md);background:var(--ui-surface);color:var(--ui-text);font:inherit;font-size:var(--ui-fs-caption);font-weight:550;line-height:16px;white-space:nowrap;text-decoration:none;cursor:pointer}.ui-chip:hover{border-style:solid;background:var(--ui-surface-2)}.ui-chip:focus-visible{outline:2px solid var(--ui-focus);outline-offset:1px}.ui-chip:is([aria-pressed=true],[aria-current=page],[aria-current=true]){border-style:solid;border-color:var(--ui-accent);background:var(--ui-accent-soft);color:var(--ui-accent-strong)}@media (pointer: coarse),(max-width: 47.9975em){.ui-chip{height:auto;min-height:44px;min-width:44px}}.ui-stack{display:grid;grid-template-columns:minmax(0,1fr);gap:var(--ui-space-4)}.ui-stack--tight{gap:var(--ui-space-2)}
|
package/parts/core.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @gemboss/ui core.css — GENERATED by packages/ui/scripts/build-css.mjs from export:globals + export:tokens; do not edit
|
|
3
|
-
* gemboss commit:
|
|
3
|
+
* gemboss commit: bf4b8350d9402ab9f5d025fa5438a78fb347b8e3
|
|
4
4
|
*/
|
|
5
5
|
*{box-sizing:border-box}:root{--gemboss-primary: #1b1c1e;--gemboss-primary-dark: #000000;--gemboss-primary-soft: #f2f3f5;--gemboss-accent: #5661f5;--gemboss-accent-strong: #3a44de;--gemboss-accent-soft: #eef0fe;--gemboss-accent-wash: #f7f8ff;--gemboss-accent-tint: #dfe2ff;--gemboss-accent-mid: #c9cffd;--gemboss-text-strong: #1b1c1e;--gemboss-text: #1b1c1e;--gemboss-text-muted: #686b71;--gemboss-surface: #ffffff;--gemboss-canvas: #ffffff;--gemboss-preview-canvas: #eceef1;--gemboss-rail-bg: #ffffff;--gemboss-panel-bg: #ffffff;--gemboss-divider: #e5e7ea;--gemboss-invite-h: 0px;--gemboss-divider-soft: #edeff2;--gemboss-hover: #eceef2;--gemboss-active-bg: #f0f1f4;--gemboss-active-fg: #1b1c1e;--gemboss-danger: #d72c0d;--gemboss-danger-strong: #b42318;--gemboss-danger-soft: #fff0e9;--gemboss-danger-border: #f5c9bc;--gemboss-success: #007f5f;--gemboss-success-strong: #0a6a4c;--gemboss-success-soft: #e3f1df;--gemboss-success-border: #b7dfcd;--gemboss-warning: #9a6700;--gemboss-warning-soft: #fff8e0;--gemboss-warning-border: #f5d569;--gemboss-radius-xs: 4px;--gemboss-radius-sm: 6px;--gemboss-radius-md: 8px;--gemboss-radius-lg: 12px;--gemboss-radius-xl: 16px;--gemboss-radius-2xl: 20px;--gemboss-radius-full: 999px;--gemboss-shadow-resting: 0 1px 2px rgba(31, 30, 29, .04), 0 2px 6px rgba(31, 30, 29, .06);--gemboss-shadow-raised: 0 4px 16px rgba(31, 30, 29, .1);--gemboss-shadow-overlay: 0 16px 48px rgba(31, 30, 29, .18);--gemboss-transition-fast: .12s;--gemboss-transition-base: .15s;--gemboss-fs-micro: 11px;--gemboss-fs-caption: 12px;--gemboss-fs-body: 14px;--gemboss-fs-body-lg: 16px;--gemboss-fs-h3: 16px;--gemboss-fs-h2: 20px;--gemboss-fs-h1: 24px;--gemboss-fs-display: 30px;--gemboss-dark-bg: #0a0a0c;--gemboss-dark-rail: #0e0e11;--gemboss-dark-surface: #16161a;--gemboss-dark-surface-2: #1e1e24;--gemboss-dark-divider: #2a2a31;--gemboss-dark-text: #ededf0;--gemboss-dark-muted: #9a9aa4;--gemboss-serif: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;--gemboss-font-sans: "Inter", -apple-system, BlinkMacSystemFont, "San Francisco", "Segoe UI", Roboto, "Helvetica Neue", sans-serif;--gemboss-field-bg: #fdfdfd;--gemboss-field-bg-hover: #fafafa;--gemboss-field-ink: #303030;--gemboss-field-placeholder: #616161;--gemboss-field-line: #8a8a8a;--gemboss-field-line-hover: #616161;--gemboss-field-line-active: #1a1a1a;--gemboss-chip-ink: #303633;--gemboss-chip-line: #cfd6ce;--gemboss-chip-line-hover: #aab4ad;--gemboss-chip-bg-hover: #f6f7f5;--gemboss-on-primary: #ffffff;--gemboss-topbar-bg: rgba(255, 255, 255, .98);--gemboss-nav-bg: var(--gemboss-surface);--gemboss-nav-hover: rgba(20, 19, 18, .045)}:root{--gemboss-primary: #1b1c1e;--gemboss-primary-dark: #000000;--gemboss-primary-soft: #f2f3f5;--gemboss-accent: #5661f5;--gemboss-accent-strong: #3a44de;--gemboss-accent-soft: #eef0fe;--gemboss-active-bg: #f0f1f4;--gemboss-active-fg: #1b1c1e;--gemboss-app-bg: #ffffff}
|
package/parts/shell.css
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* @gemboss/ui shell.css — GENERATED by packages/ui/scripts/build-css.mjs from export:shell + src/app-shell.css; do not edit
|
|
3
|
-
* gemboss commit:
|
|
3
|
+
* gemboss commit: bf4b8350d9402ab9f5d025fa5438a78fb347b8e3
|
|
4
4
|
*/
|
|
5
5
|
.gemboss-popover-surface{background:var(--gemboss-surface);background:color-mix(in srgb,var(--gemboss-surface) 93%,transparent);-webkit-backdrop-filter:blur(14px) saturate(1.4);backdrop-filter:blur(14px) saturate(1.4);border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-lg);box-shadow:var(--gemboss-shadow-raised)}@supports not ((backdrop-filter: blur(1px)) or (-webkit-backdrop-filter: blur(1px))){.gemboss-popover-surface{background:var(--gemboss-surface)}}.icon-nav{position:fixed;top:56px;left:0;z-index:200;height:calc(100dvh - 56px);background:var(--gemboss-rail-bg);border-right:1px solid var(--gemboss-divider);display:flex;flex-direction:column;padding-top:8px;overflow:hidden}.gemboss-account-menu{position:absolute;top:calc(100% + 6px);right:0;min-width:220px;z-index:320;overflow:hidden}.gemboss-account-menu-item,.ui-menu__item{display:block;width:100%;min-height:44px;padding:12px 16px;border:0;background:transparent;font:inherit;font-size:13px;color:var(--gemboss-text);text-align:left;text-decoration:none;cursor:pointer;transition:background var(--gemboss-transition-fast) ease,color var(--gemboss-transition-fast) ease}.gemboss-account-menu-item:hover,.ui-menu__item:hover{background:var(--gemboss-hover)}.gemboss-account-menu-item:focus-visible,.ui-menu__item:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:-2px;background:var(--gemboss-hover)}.gemboss-account-menu-item.danger,.ui-menu__item--danger{color:var(--gemboss-danger-strong)}.gemboss-account-chip{width:30px;height:30px;border:1px solid #cfd6ce;border-radius:var(--gemboss-radius-full);background:#f5f7f4;color:#303633;display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;font-size:11px;font-weight:700;cursor:pointer}.gemboss-platform-main{box-sizing:border-box;min-height:100dvh;padding-top:56px;background:var(--gemboss-app-bg)}.icon-nav{top:56px;height:calc(100dvh - 56px);background:var(--gemboss-nav-bg);border-right-color:var(--gemboss-divider)}@media (max-width: 1040px){.gemboss-platform-topbar{grid-template-columns:minmax(120px,1fr) minmax(220px,520px) minmax(120px,1fr)}}@media (max-width: 760px){.gemboss-platform-main{margin-left:0}}.gemboss-account-chip{width:32px;height:32px;border-radius:50%;background:var(--gemboss-primary);color:#fff;font-weight:600;font-size:12px;display:inline-flex;align-items:center;justify-content:center;border:none;cursor:pointer;transition:transform var(--gemboss-transition-base) ease}.gemboss-account-chip:hover{transform:scale(1.05)}.gemboss-account-chip:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gemboss-platform-main{margin-top:56px;min-height:calc(100vh - 56px);padding:24px;background:#fafafb}@media (max-width: 768px){.gemboss-platform-main{margin-left:0;padding:16px}}.gemboss-platform-shell{display:block;min-height:100vh;background:var(--gemboss-app-bg)}.gemboss-platform-topbar{position:fixed;inset:0 0 auto;z-index:300;height:56px;border-bottom:1px solid var(--gemboss-divider);background:var(--gemboss-topbar-bg);display:grid;grid-template-columns:minmax(200px,1fr) minmax(280px,560px) minmax(200px,1fr);align-items:center;gap:16px;padding:0 16px;box-shadow:var(--gemboss-shadow-resting)}:root:has(.gemboss-platform-topbar){scroll-padding-top:64px}.gemboss-account-chip{width:32px;height:32px;border:1px solid var(--gemboss-chip-line);border-radius:var(--gemboss-radius-full);background:var(--gemboss-surface);color:var(--gemboss-chip-ink);display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;font-size:11px;font-weight:700;cursor:pointer;transition:border-color var(--gemboss-transition-base) ease,background-color var(--gemboss-transition-base) ease}.gemboss-account-chip:hover{border-color:var(--gemboss-chip-line-hover);background:var(--gemboss-chip-bg-hover);transform:none}.icon-nav{position:fixed;top:56px;left:0;z-index:200;height:calc(100dvh - 56px);border-right:1px solid var(--gemboss-divider);background:var(--gemboss-nav-bg);padding-top:12px}.gemboss-platform-main{min-height:calc(100vh - 56px);margin-top:56px;background:var(--gemboss-app-bg);padding:24px}@media (max-width: 1120px){.gemboss-platform-topbar{grid-template-columns:220px minmax(220px,1fr) auto;gap:12px}}@media (max-width: 760px){.gemboss-platform-topbar{height:auto;min-height:56px;grid-template-columns:minmax(0,1fr) auto;padding:12px}.gemboss-account-chip,.icon-nav{display:none}.gemboss-platform-main{margin-left:0;padding:16px}}.gnav-scroll{scrollbar-width:thin;scrollbar-color:rgba(31,30,29,.22) transparent}.gemboss-assistant-railfoot.is-button{width:100%;border:none;background:none;cursor:pointer;text-align:left;font:inherit;border-radius:8px;transition:background .12s ease,color .12s ease}.gemboss-assistant-railfoot.is-button:hover{background:var(--gemboss-primary-soft);color:var(--gemboss-primary-dark)}.gemboss-assistant-empty{padding:24px 20px;color:var(--gemboss-text-muted);font-size:13px}@media (max-width: 760px){.gemboss-platform-topbar{display:flex;align-items:center;gap:8px;height:56px;min-height:56px;padding:0 12px}.gemboss-account-chip{display:inline-flex}.gemboss-platform-main{padding-top:16px;padding-bottom:calc(56px + env(safe-area-inset-bottom))}}@media (pointer: coarse){.gemboss-account-chip{width:44px;height:44px}.gnav-item{min-height:44px}.gemboss-assistant-collapse,.gemboss-assistant-newchat{min-height:44px;min-width:44px}}.icon-nav{width:240px;padding:12px 0 0;overflow:hidden;background:var(--gemboss-nav-bg);display:flex;flex-direction:column}.gnav-scroll{flex:1;overflow-y:auto;overflow-x:hidden;padding-inline:12px}.gnav-bottom{padding:0 12px 12px}.gnav-item{display:flex;align-items:center;gap:12px;width:100%;padding:8px 12px;margin:1px 0;border:0;background:transparent;cursor:pointer;text-align:left;border-radius:var(--gemboss-radius-md);text-decoration:none;font-family:inherit;color:var(--gemboss-text);font-size:var(--gemboss-fs-body);font-weight:500;line-height:1.2;transition:background-color var(--gemboss-transition-fast) ease,color var(--gemboss-transition-fast) ease}.gnav-item:hover{background:var(--gemboss-nav-hover)}.gnav-item:focus-visible{outline:2px solid var(--gemboss-accent);outline-offset:-2px}.gnav-item.active{color:var(--gemboss-active-fg);font-weight:600}.gnav-group:not(.has-active-child)>.gnav-item.active{background:var(--gemboss-active-bg)}.gnav-group:not(.has-active-child)>.gnav-item.active:hover{background:var(--gemboss-active-bg)}.gnav-group.has-active-child>.gnav-item.active:hover{background:var(--gemboss-nav-hover)}.gnav-ico{flex:0 0 20px;width:20px;height:20px;display:grid;place-items:center}.gnav-ico svg{width:20px;height:20px;fill:currentColor}.gnav-label{flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gnav-sub{list-style:none;margin:1px 0 6px;padding:0}.gnav-subitem{position:relative;display:flex;align-items:center;justify-content:space-between;gap:8px;padding:6px 12px 6px 44px;margin:1px 0;border-radius:var(--gemboss-radius-sm);color:var(--gemboss-text-muted);font-size:13px;line-height:1.2;text-decoration:none;white-space:nowrap;transition:background-color var(--gemboss-transition-fast) ease,color var(--gemboss-transition-fast) ease}@media (pointer: coarse){.gnav-subitem{min-height:44px}}.gnav-subitem:hover{background:var(--gemboss-nav-hover);color:var(--gemboss-text)}.gnav-subitem.active{color:var(--gemboss-active-fg);font-weight:600;background:var(--gemboss-active-bg)}.gnav-subitem.active:hover{background:var(--gemboss-active-bg);color:var(--gemboss-active-fg)}.gnav-subitem.active:before{content:"";position:absolute;left:20px;top:50%;transform:translateY(-50%);width:3px;height:15px;border-radius:2px;background:var(--gemboss-primary)}.gnav-subitem.is-soon{opacity:.5;cursor:default}.gnav-subitem em{font-style:normal;font-size:var(--gemboss-fs-micro);font-weight:600;letter-spacing:.04em;text-transform:uppercase;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-sm);padding:1px 6px}.gnav-sep{height:1px;background:var(--gemboss-divider);margin:8px 6px}.gnav-item.gnav-assistant{color:var(--gemboss-accent-strong);font-weight:600;background:var(--gemboss-accent-soft)}.gnav-item.gnav-assistant .gnav-ico svg{fill:var(--gemboss-accent)}.gnav-item.gnav-assistant:hover{background:color-mix(in srgb,var(--gemboss-accent) 16%,var(--gemboss-surface))}.gnav-item.gnav-assistant.active{background:var(--gemboss-active-bg);color:var(--gemboss-active-fg)}.gnav-item.gnav-assistant.active .gnav-ico svg{fill:var(--gemboss-active-fg)}.gemboss-platform-main{margin-left:240px}.gemboss-mobile-menu-btn,.gemboss-mobile-nav-backdrop{display:none}@media (max-width: 760px){.gemboss-platform-main{margin-left:0;padding-bottom:env(safe-area-inset-bottom)}.gemboss-mobile-menu-btn{display:inline-flex;align-items:center;justify-content:center;flex:0 0 auto;width:38px;height:38px;margin-left:-2px;border:0;border-radius:8px;background:transparent;cursor:pointer;color:var(--gemboss-text)}.gemboss-mobile-menu-btn:active{background:var(--gemboss-hover)}.icon-nav{display:flex;width:min(82vw,300px);transform:translate(-100%);transition:transform .26s cubic-bezier(.4,0,.2,1),box-shadow .26s cubic-bezier(.4,0,.2,1);z-index:1000;box-shadow:none}.gemboss-platform-shell.is-mobile-nav-open .icon-nav{transform:translate(0);box-shadow:2px 0 26px #1f1e1d33}.gemboss-mobile-nav-backdrop{display:block;position:fixed;inset:56px 0 0;width:100%;border:0;padding:0;background:#14131261;opacity:0;pointer-events:none;transition:opacity .22s ease;z-index:999}.gemboss-platform-shell.is-mobile-nav-open .gemboss-mobile-nav-backdrop{opacity:1;pointer-events:auto}}@media (max-width: 305.98px){.gemboss-platform-topbar{padding:0 8px}}@media (min-width: 306px) and (max-width: 460px){.gemboss-platform-topbar{padding:0 8px}.gemboss-mobile-menu-btn,.gemboss-account-chip{width:44px;height:44px}}.gemboss-assistant-chatslot{display:flex;flex-direction:column;flex:1 1 auto;min-height:0;min-width:0}.gemboss-assistant-chatslot[hidden]{display:none}.gemboss-assistant-page>.gemboss-assistant-tabs{flex:0 0 auto;display:flex;align-items:center;gap:4px;padding:4px 8px 0;overflow-x:auto;scrollbar-width:none}.gemboss-assistant-tabs::-webkit-scrollbar{display:none}.gemboss-assistant-tab{display:flex;align-items:center;flex:0 1 auto;min-width:0;max-width:190px;border:1px solid var(--gemboss-divider);border-radius:var(--gemboss-radius-md);background:transparent}.gemboss-assistant-tab.active{background:var(--gemboss-active-bg);border-color:var(--gemboss-active-bg)}.gemboss-assistant-tab-main{display:flex;align-items:center;gap:6px;min-width:0;min-height:44px;padding:0 4px 0 8px;border:0;background:transparent;font:inherit;font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted);cursor:pointer}.gemboss-assistant-tab.active .gemboss-assistant-tab-main{color:var(--gemboss-text-strong)}.gemboss-assistant-tab-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.gemboss-assistant-tab-dot{flex:0 0 auto;width:6px;height:6px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-divider)}.gemboss-assistant-tab-dot.is-running{background:var(--gemboss-primary);animation:gemboss-assistant-pulse 1.4s ease-in-out infinite}.gemboss-assistant-tab-close{flex:0 0 auto;width:44px;height:44px;display:grid;place-items:center;border:0;background:transparent;color:var(--gemboss-text-muted);cursor:pointer;padding:0}.gemboss-assistant-tab-close:hover{color:var(--gemboss-text-strong)}.gemboss-assistant-tab-close svg{width:14px;height:14px}.gemboss-assistant-sronly{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap;border:0}.gemboss-assistant-thread-running{flex:0 0 auto;width:6px;height:6px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-primary);animation:gemboss-assistant-pulse 1.4s ease-in-out infinite}@media (prefers-reduced-motion: reduce){.gemboss-assistant-tab-dot.is-running,.gemboss-assistant-thread-running{animation:none}}.gemboss-assistant-route-claim{display:block;height:100%}.gemboss-assistant-layout.is-dock{height:auto;min-height:0}.gemboss-assistant-layout.is-dock .gemboss-assistant-page{height:auto;max-width:none;padding:4px 0 8px}.gnav-item.gnav-assistant{position:relative}body.gemboss-assistant-busy .gnav-item.gnav-assistant:after,body.gemboss-assistant-unread .gnav-item.gnav-assistant:after{content:"";position:absolute;top:6px;left:26px;width:8px;height:8px;border-radius:50%;border:2px solid var(--gemboss-surface)}body.gemboss-assistant-busy .gnav-item.gnav-assistant:after{background:var(--gemboss-primary);animation:gemboss-assistant-pulse 1.4s ease-in-out infinite}body.gemboss-assistant-unread .gnav-item.gnav-assistant:after{background:var(--gemboss-success-strong)}@media (prefers-reduced-motion: reduce){body.gemboss-assistant-busy .gnav-item.gnav-assistant:after{animation:none}}.gemboss-assistant-layout{display:flex;height:calc(100dvh - 56px);width:100%;min-height:0}.gemboss-assistant-rail{flex:0 0 264px;width:264px;display:flex;flex-direction:column;min-height:0;border-right:1px solid var(--gemboss-divider);background:transparent;padding:16px 12px 12px;gap:12px;transition:flex-basis .18s ease,width .18s ease}.gemboss-assistant-rail-top{display:flex;align-items:center;gap:6px}.gemboss-assistant-newchat{display:flex;align-items:center;gap:8px;flex:1 1 auto;min-width:0;padding:12px;border:1px solid var(--gemboss-divider);border-radius:12px;background:transparent;color:var(--gemboss-text);font-size:var(--gemboss-fs-body);font-weight:600;cursor:pointer;transition:background .12s ease,border-color .12s ease}.gemboss-assistant-newchat:hover{background:#00000009;border-color:var(--gemboss-text-muted)}.gemboss-assistant-newchat svg{width:17px;height:17px;fill:currentColor;flex:0 0 auto}.gemboss-assistant-newchat span{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;flex:1 1 auto}.gemboss-assistant-kbd{flex:0 0 auto;font-size:var(--gemboss-fs-micro);font-weight:600;line-height:1;padding:4px 6px;border:1px solid var(--gemboss-divider);border-radius:6px;background:transparent;color:var(--gemboss-text-muted);font-family:ui-monospace,SFMono-Regular,Menlo,monospace}.gemboss-assistant-search:focus-within .gemboss-assistant-kbd{display:none}.gemboss-assistant-collapse{flex:0 0 auto;display:grid;place-items:center;width:34px;height:34px;border:0;border-radius:8px;background:transparent;color:var(--gemboss-text-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.gemboss-assistant-collapse:hover{background:#0000000d;color:var(--gemboss-text)}.gemboss-assistant-collapse svg{width:16px;height:16px;fill:currentColor}.gemboss-assistant-search{gap:6px}.gemboss-assistant-search>svg{width:15px;height:15px;fill:var(--gemboss-text-muted);flex:0 0 auto}.gemboss-assistant-search-clear{display:grid;place-items:center;width:20px;height:20px;border:0;border-radius:6px;background:transparent;color:var(--gemboss-text-muted);cursor:pointer}.gemboss-assistant-search-clear:hover{background:#00000012;color:var(--gemboss-text)}.gemboss-assistant-search-clear svg{width:13px;height:13px;fill:currentColor}.gemboss-assistant-railfoot{flex:0 0 auto;display:flex;align-items:center;gap:6px;padding:8px 12px 2px;border-top:1px solid var(--gemboss-divider);margin-top:4px;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption);line-height:1.35}.gemboss-assistant-railfoot svg{width:13px;height:13px;flex:0 0 auto;fill:currentColor;opacity:.8}.gemboss-assistant-threads{flex:1 1 auto;min-height:0;overflow-y:auto;display:flex;flex-direction:column;gap:2px}.gemboss-assistant-threads-empty{padding:16px 8px;color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-caption)}.gemboss-assistant-group{display:flex;flex-direction:column;gap:2px}.gemboss-assistant-group+.gemboss-assistant-group{margin-top:12px}.gemboss-assistant-group-label{padding:4px 12px;font-size:11px;font-weight:600;letter-spacing:.02em;color:var(--gemboss-text-muted);text-transform:uppercase}.gemboss-assistant-thread{position:relative;display:flex;align-items:center;border-radius:8px;transition:background .12s ease}.gemboss-assistant-thread:hover{background:var(--gemboss-hover, rgba(0,0,0,.04))}.gemboss-assistant-thread.active{background:#00000012}.gemboss-assistant-thread-main{flex:1 1 auto;min-width:0;display:flex;flex-direction:column;align-items:flex-start;gap:2px;padding:8px 12px;border:0;background:transparent;text-align:left;cursor:pointer}.gemboss-assistant-thread-titlerow{display:flex;align-items:center;gap:6px;width:100%;min-width:0}.gemboss-assistant-pin-dot{width:12px;height:12px;flex:0 0 auto;fill:var(--gemboss-text-muted)}.gemboss-assistant-thread-title{flex:1 1 auto;min-width:0;font-size:13px;font-weight:500;color:var(--gemboss-text);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.gemboss-assistant-thread-meta{font-size:var(--gemboss-fs-caption);color:var(--gemboss-text-muted)}.gemboss-assistant-thread.menu-open{background:#00000012}.gemboss-assistant-thread.menu-open .gemboss-assistant-thread-actions{opacity:1}.gemboss-assistant-menu{z-index:60;width:184px;padding:6px;display:flex;flex-direction:column}.gemboss-assistant-menu-confirm{padding:8px 12px 6px;font-size:var(--gemboss-fs-caption);font-weight:600;color:var(--gemboss-text)}.gemboss-assistant-menu button{display:flex;align-items:center;gap:8px;width:100%;padding:8px 12px;border:0;border-radius:8px;background:transparent;text-align:left;font-size:13px;color:var(--gemboss-text);cursor:pointer}.gemboss-assistant-menu button:hover{background:var(--gemboss-hover, rgba(0,0,0,.05))}.gemboss-assistant-menu button.danger{color:var(--gemboss-danger-strong)}.gemboss-assistant-menu button svg{width:15px;height:15px;fill:currentColor;flex:0 0 auto}.gemboss-assistant-thread-actions{position:absolute;right:6px;display:flex;gap:2px;opacity:0;transition:opacity .12s ease}.gemboss-assistant-thread:hover .gemboss-assistant-thread-actions,.gemboss-assistant-thread:focus-within .gemboss-assistant-thread-actions{opacity:1}.gemboss-assistant-thread-act{display:grid;place-items:center;width:26px;height:26px;border:0;border-radius:8px;background:transparent;color:var(--gemboss-text-muted);cursor:pointer;transition:background .12s ease,color .12s ease}.gemboss-assistant-thread-act:hover{background:#00000012;color:var(--gemboss-text)}.gemboss-assistant-thread-act.danger:hover{color:var(--gemboss-danger-strong)}.gemboss-assistant-thread-act svg{width:15px;height:15px;fill:currentColor}.gemboss-assistant-thread.editing{background:#00000012}.gemboss-assistant-thread-edit{display:flex;align-items:center;gap:2px;width:100%;padding:6px}.gemboss-assistant-thread-edit input{flex:1 1 auto;min-width:0}.gemboss-assistant-layout .gemboss-assistant-page{height:100%;max-width:820px;flex:1 1 auto;min-width:0;padding-top:16px}.gemboss-assistant-layout .gemboss-assistant-page.is-switching{opacity:.55;transition:opacity .12s ease;pointer-events:none}.gemboss-assistant-rail.is-collapsed{flex-basis:60px;width:60px;padding:16px 8px 12px}.gemboss-assistant-rail.is-collapsed .gemboss-assistant-rail-top{flex-direction:column;gap:8px}.gemboss-assistant-rail.is-collapsed .gemboss-assistant-newchat{justify-content:center;padding:8px;flex:0 0 auto}.gemboss-assistant-rail.is-collapsed .gemboss-assistant-newchat span,.gemboss-assistant-rail.is-collapsed .gemboss-assistant-search,.gemboss-assistant-rail.is-collapsed .gemboss-assistant-railfoot,.gemboss-assistant-rail.is-collapsed .gemboss-assistant-threads{display:none}@media (max-width: 760px){.gemboss-assistant-rail{flex-basis:60px;width:60px;padding:16px 8px 12px}.gemboss-assistant-rail .gemboss-assistant-rail-top{flex-direction:column;gap:8px}.gemboss-assistant-newchat{justify-content:center;padding:8px;flex:0 0 auto}.gemboss-assistant-newchat span,.gemboss-assistant-search,.gemboss-assistant-railfoot,.gemboss-assistant-threads,.gemboss-assistant-collapse{display:none}}.gemboss-assistant-page{height:calc(100dvh - 56px);width:100%;max-width:760px;margin:0 auto;padding:24px 0 16px;display:flex;flex-direction:column;min-height:0}.gemboss-assistant-page>*{flex:1 1 auto;min-height:0}.gemboss-assistant-empty{flex:1;display:grid;place-items:center;color:var(--gemboss-text-muted);font-size:14px}.gemboss-platform-shell{display:flow-root}.gemboss-platform-main{padding-bottom:calc(24px + var(--gemboss-invite-h, 0px))}.gb-account{position:relative}.gb-account>summary{list-style:none}.gb-account>summary::-webkit-details-marker{display:none}.gb-account-head{padding:12px 16px;border-bottom:1px solid var(--gemboss-divider)}.gb-account-name{font-size:13px;font-weight:600;color:var(--gemboss-text-strong)}.gb-account-email{font-size:12px;color:var(--gemboss-text-muted)}.gb-account-role{display:inline-block;margin-top:4px;padding:1px 6px;border-radius:4px;font-size:11px;font-weight:600;color:var(--gemboss-active-fg);background:var(--gemboss-active-bg)}.gb-account-form{margin:0}.gnav-scroll::-webkit-scrollbar{width:9px}.gnav-scroll::-webkit-scrollbar-track{background:transparent}.gnav-scroll::-webkit-scrollbar-thumb{background:#1f1e1d33;border-radius:6px;border:2px solid transparent;background-clip:content-box}@keyframes gemboss-assistant-pulse{0%,to{opacity:1}50%{opacity:.35}}:where(html,body,button){font-family:var(--gemboss-font-sans)}:where(body){font-size:13px;line-height:20px;font-weight:450;color:var(--gemboss-text);-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}:where(h1,h2,h3){letter-spacing:-.01em;line-height:1.3}:where(.gemboss-platform-shell) :where(h1,h2,h3,h4,h5,h6,p):where(:not([class])):not(:where(.ui-prose,[data-content],[class*=prose i],[class*=markdown i],.md-body,.recap-md,.asst-md,.article-body) *){margin:0;font-size:1em;font-weight:inherit;line-height:inherit}.gemboss-topbar-start{display:flex;align-items:center;gap:8px;min-width:0}.gemboss-topbar-center{display:flex;justify-content:center;min-width:0}.gemboss-topbar-end{display:flex;align-items:center;justify-content:flex-end;gap:8px;min-width:0}@media (max-width: 760px){.gemboss-topbar-center{flex:1 1 0;min-width:96px;justify-content:flex-start}.gemboss-topbar-center:empty{min-width:0}.gemboss-topbar-end:empty{display:none}.gemboss-topbar-end{flex:0 0 auto}.gemboss-topbar-start{flex:0 1 auto}.gemboss-topbar-start>.gemboss-mobile-menu-btn{flex:0 0 auto}.gemboss-topbar-start>.gb-brand{min-width:44px}}.gnav-heading{padding:10px 12px 4px;font-size:var(--gemboss-fs-micro);font-weight:600;line-height:1.2;letter-spacing:.08em;text-transform:uppercase;color:var(--gemboss-text-muted)}.gnav-scroll>.gnav-heading:first-child,.gnav-scroll>.gnav-section:first-child>.gnav-heading:first-child{padding-top:2px}.gnav-count{margin-left:auto;flex:0 0 auto;min-width:20px;padding:0 6px;border-radius:var(--gemboss-radius-full);background:var(--gemboss-hover);color:var(--gemboss-text-muted);font-size:var(--gemboss-fs-micro);font-weight:700;line-height:18px;text-align:center;font-variant-numeric:tabular-nums}.gnav-item.active .gnav-count{background:var(--gemboss-primary);color:var(--gemboss-on-primary)}.gnav-item:is([aria-busy=true],:has(>.gnav-pending)),.gnav-subitem:is([aria-busy=true],:has(>.gnav-pending)){cursor:progress}.gnav-item:is([aria-busy=true],:has(>.gnav-pending))>.gnav-ico>*{visibility:hidden}.gnav-item:is([aria-busy=true],:has(>.gnav-pending))>.gnav-ico:after,.gnav-subitem:is([aria-busy=true],:has(>.gnav-pending)):after,.gb-pending-mark{content:"";display:inline-block;vertical-align:middle;grid-area:1 / 1;flex:none;box-sizing:border-box;width:20px;height:20px;border-radius:50%;border:2px solid color-mix(in srgb,currentColor 18%,transparent);border-top-color:currentColor;animation:gnav-spin .7s linear infinite}.gnav-subitem:is([aria-busy=true],:has(>.gnav-pending)):after{position:absolute;left:22px;top:50%;margin-top:-6px;width:12px;height:12px;border-width:1.5px}@keyframes gnav-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion: reduce){.gnav-item:is([aria-busy=true],:has(>.gnav-pending))>.gnav-ico:after,.gnav-subitem:is([aria-busy=true],:has(>.gnav-pending)):after,.gb-pending-mark{animation-duration:2s}}a[data-gb-pending]:has(>.gb-pending-mark),a[data-gb-pending][aria-busy=true]{cursor:progress}a[data-gb-pending]>.gb-pending-mark{display:inline-block;width:12px;height:12px;border-width:1.5px;margin-left:6px;vertical-align:-1px}a[data-gb-pending=corner]{position:relative}a[data-gb-pending=corner]>.gb-pending-mark{position:absolute;top:12px;right:12px;width:16px;height:16px;margin:0}.gb-route-holding{padding-top:4px}.gb-route-holding .ui-skeleton{gap:16px}.gb-route-holding__heading{margin:0 0 20px;font-size:20px;font-weight:650;line-height:1.3;color:var(--gemboss-text)}.gb-route-holding .ui-skeleton__line{height:10px}.gb-route-holding .ui-skeleton__line.gb-route-holding__title{height:20px;width:34%;margin-bottom:8px}.gb-route-holding .ui-skeleton__line:nth-last-child(4){width:46%}.gb-route-holding .ui-skeleton__line:nth-last-child(3){width:92%}.gb-route-holding .ui-skeleton__line:nth-last-child(2){width:78%}.gb-route-holding .ui-skeleton__line:nth-last-child(1){width:61%}.gb-route-cover{display:none}html[data-gb-navigating] .gb-route-cover{display:block;position:fixed;inset:56px 0 0 240px;z-index:5;overflow:hidden;box-sizing:border-box;padding:24px;background:var(--gemboss-app-bg);pointer-events:none;animation:gb-route-cover-in .08s ease-out both}@keyframes gb-route-cover-in{0%{opacity:0}to{opacity:1}}@media (max-width: 760px){html[data-gb-navigating] .gb-route-cover{left:0;padding:16px}}@media (prefers-reduced-motion: reduce){html[data-gb-navigating] .gb-route-cover{animation-duration:0s}}.gnav-pending{position:absolute;width:1px;height:1px;margin:-1px;padding:0;border:0;overflow:hidden;clip:rect(0 0 0 0);white-space:nowrap}.gb-brand{min-width:0;height:40px;margin:0;padding:0 8px;border-radius:var(--gemboss-radius-md);display:inline-flex;align-items:center;gap:4.5px;color:var(--gb-brand-ink, #14151a);text-decoration:none;transition:background-color var(--gemboss-transition-base) ease}.gb-brand:hover{background:var(--gemboss-hover)}.gb-brand:focus-visible{outline:2px solid var(--gemboss-primary);outline-offset:2px}.gb-brand-gem{display:block;flex:0 0 auto}.gb-brand-name{font-family:Inter,var(--gemboss-font-sans);font-size:13.3px;font-weight:700;letter-spacing:-.13px;line-height:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0}@media (max-width: 460px){.gb-brand-name{display:none}.gb-brand{min-width:44px;height:44px;justify-content:center}}.gemboss-topbar-search{width:100%;max-width:560px;height:36px;min-width:0;margin:0 auto;border:1px solid var(--gemboss-field-line);border-radius:var(--gemboss-radius-md);background:var(--gemboss-field-bg);padding:0 8px 0 12px;display:grid;grid-template-columns:18px minmax(0,1fr) auto;gap:8px;align-items:center;color:var(--gemboss-text-muted)}.gemboss-topbar-search:hover{border-color:var(--gemboss-field-line-hover);background:var(--gemboss-field-bg-hover)}.gemboss-topbar-search:focus-within{border-color:var(--gemboss-field-line-active);background:var(--gemboss-surface)}.gemboss-topbar-search-icon{width:18px;height:18px;color:currentColor}.gemboss-topbar-search-input{min-width:0;height:calc(100% + 2px);border:0;background:transparent;padding:0;margin:-1px 0;font:inherit;font-size:var(--gemboss-fs-body);line-height:18px;color:var(--gemboss-field-ink);outline:none}.gemboss-topbar-search-input::placeholder{color:var(--gemboss-field-placeholder);opacity:1}.gemboss-topbar-search-kbd{border:1px solid var(--gemboss-field-line);border-radius:var(--gemboss-radius-sm);background:var(--gemboss-surface);padding:1px 6px;color:var(--gemboss-text-muted);font-family:inherit;font-size:var(--gemboss-fs-micro);line-height:16px}.gemboss-topbar-search:focus-within .gemboss-topbar-search-kbd{display:none}@media (pointer: coarse),(max-width: 47.9975em){.gemboss-topbar-search{height:44px}}@media (max-width: 460px){.gemboss-topbar-search-kbd{display:none}}.ui-page{box-sizing:border-box;width:100%;min-width:0;max-width:var(--ui-content-max, 900px);margin-inline:auto}.ui-page--feed{max-width:720px}.ui-page--form{max-width:662px}.ui-page--canvas{max-width:1440px}.ui-page--full{max-width:none}.ui-menu__item{display:flex;align-items:center;gap:var(--ui-space-2);white-space:nowrap;border-radius:var(--ui-radius-sm)}@media (max-width: 47.9975em){.gemboss-assistant-collapse,.gemboss-assistant-newchat{min-height:44px;min-width:44px}}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(function(d){"use strict";var G=d.gembossUI;if(!G){d.console&&d.console.error("@gemboss/ui assistant-plain.js: load kit-plain.js first (it defines gembossUI)");return}if(G.assistantFrame)return;var _=280,Ae=480,Ve=56,je=12,De=Ve+je,oe=24,T=380,se=400,le=720,Ne=480,He="(min-width: 1100px)",de="--gb-assistant-side-w",K=9007199254740991;function ue(n,i){var r=isFinite(i)&&i>0?Math.max(T,Math.min(le,i-Ne)):le;return Math.min(Math.max(Math.round(n),T),r)}function Me(n,i,r){return r<i?i:Math.min(Math.max(Math.round(n),i),r)}function P(n,i){var r=Math.max(_,i-De);return Math.min(Math.max(Math.round(n),_),r)}function U(n,i){var r=n!==null&&isFinite(n)&&n>0?n:1/0;return P(r,i)}var Ie={presentation:"hidden",mounted:!1,busy:!1,unread:!1,dockHeight:Ae,dockOffsetRight:oe,openNonce:0,sideWidth:se,floatShape:"side",sideAllowed:!1};function h(n,i){var r={},p;for(p in n)r[p]=n[p];for(p in i)r[p]=i[p];return r}function X(n){return n.sideAllowed?n.floatShape:"dock"}function ce(n,i){switch(i.type){case"enter-full":return h(n,{presentation:"full",mounted:!0,unread:!1,openNonce:n.openNonce+1});case"leave-full":return n.presentation!=="full"?n:h(n,{presentation:n.busy?X(n):"mini"});case"dock":return h(n,{presentation:"dock",floatShape:"dock",mounted:!0,unread:!1,openNonce:n.openNonce+1});case"side":return n.sideAllowed?h(n,{presentation:"side",floatShape:"side",mounted:!0,unread:!1,openNonce:n.openNonce+1}):h(n,{presentation:"dock",floatShape:"dock",mounted:!0,unread:!1,openNonce:n.openNonce+1});case"reopen":return h(n,{presentation:X(n),mounted:!0,unread:!1,openNonce:n.openNonce+1});case"side-allowed":return i.allowed===n.sideAllowed?n:i.allowed?h(n,{sideAllowed:!0,presentation:n.presentation==="dock"&&n.floatShape==="side"?"side":n.presentation}):h(n,{sideAllowed:!1,presentation:n.presentation==="side"?"dock":n.presentation});case"restore-float":return h(n,{floatShape:i.shape});case"minimize":return h(n,{presentation:"mini"});case"dismiss":return n.busy?h(n,{presentation:n.presentation==="mini"?X(n):"mini"}):h(n,{presentation:"hidden"});case"busy":{if(i.busy===n.busy)return n;var r=n.presentation==="mini"||n.presentation==="hidden";return h(n,{busy:i.busy,unread:!i.busy&&r?!0:n.unread})}case"resize":return h(n,{dockHeight:P(i.height,i.viewport)});case"slide":return h(n,{dockOffsetRight:Me(i.offsetRight,i.min,i.max)});case"side-resize":return h(n,{sideWidth:ue(i.width,i.available)});default:return n}}G.assistantDock={reducer:ce,initial:Ie,clampSideWidth:ue,clampDockOffset:Me,clampDockHeight:P,openingDockHeight:U,DOCK_MIN_HEIGHT:_,DOCK_DEFAULT_HEIGHT:Ae,DOCK_VIEWPORT_RESERVE:De,DOCK_DEFAULT_OFFSET_RIGHT:oe,SIDE_MIN_WIDTH:T,SIDE_DEFAULT_WIDTH:se,SIDE_MAX_WIDTH:le,SIDE_PAGE_MIN:Ne,SIDE_FITS_QUERY:He};var Ye={ready:"Ready",working:"Working",done:"Done \u2014 tap to see it",answerWaiting:"An answer is waiting",askAboutScreen:"Ask about this screen",reopen:"Reopen the {title}",hide:"Hide the assistant",hideTitle:"Hide the assistant",openInstead:"Open the assistant",openInsteadTitle:"Still working \u2014 open it",grip:"Drag to resize the assistant; left and right arrows move it sideways",headerTitle:"Drag this bar to move the popup left or right",newChat:"New chat",openFull:"Open full screen",minimize:"Minimise",minimizeTitle:"Shrink to a bar",close:"Close the assistant",closeBusy:"Shrink to a bar",closeBusyTitle:"Still working \u2014 shrink it to a bar",shrinkToPopup:"Shrink to popup",tablist:"Assistant or a person",primaryTab:"Assistant",pinSide:"Pin to the side",floatPopup:"Float as a popup",sideGrip:"Drag to resize the assistant; left and right arrows work too",backToSide:"Back to the side panel",more:"More",clearHistory:"Clear history"},Le={hidden:"gb-dock-hidden",mini:"gb-dock-mini",dock:"gb-dock-dock",side:"gb-dock-side",full:"gb-dock-full"},_e="http://www.w3.org/2000/svg",Te=function(n){return typeof Node<"u"&&n instanceof Node};function u(n,i,r){var p=document.createElement(n);if(i)for(var y in i){var k=i[y];k==null||k===!1||(y==="text"?p.textContent=String(k):y==="className"?p.className=k:p.setAttribute(y,k===!0?"":String(k)))}return fe(p,r),p}function fe(n,i){return i==null||i===!1?n:Array.isArray(i)?(i.forEach(function(r){fe(n,r)}),n):(n.appendChild(Te(i)?i:document.createTextNode(String(i))),n)}function R(n){var i=document.createElementNS(_e,"svg");return i.setAttribute("viewBox","0 0 20 20"),i.setAttribute("aria-hidden","true"),n.forEach(function(r){var p=document.createElementNS(_e,r.tag||"path");for(var y in r)y!=="tag"&&p.setAttribute(y,r[y]);i.appendChild(p)}),i}var A={close:function(){return R([{d:"M6 6l8 8M14 6l-8 8",stroke:"currentColor","stroke-width":"1.7","stroke-linecap":"round"}])},plus:function(){return R([{d:"M10 4.5v11M4.5 10h11",stroke:"currentColor","stroke-width":"1.7","stroke-linecap":"round"}])},expand:function(){return R([{d:"M11 9l5-5M16 4h-3.5M16 4v3.5M9 11l-5 5M4 16h3.5M4 16v-3.5",stroke:"currentColor","stroke-width":"1.6",fill:"none","stroke-linecap":"round","stroke-linejoin":"round"}])},shrink:function(){return R([{d:"M16 4l-5 5M11 9h3.5M11 9V5.5M4 16l5-5M9 11H5.5M9 11v3.5",stroke:"currentColor","stroke-width":"1.6",fill:"none","stroke-linecap":"round","stroke-linejoin":"round"}])},more:function(){return R([{tag:"circle",cx:"5",cy:"10",r:"1.5",fill:"currentColor"},{tag:"circle",cx:"10",cy:"10",r:"1.5",fill:"currentColor"},{tag:"circle",cx:"15",cy:"10",r:"1.5",fill:"currentColor"}])}};function Qe(n){var i=Math.max(0,Math.floor((Date.now()-n)/1e3)),r=i%60;return Math.floor(i/60)+":"+(r<10?"0":"")+r}function Pe(n){try{return n==="session"?d.sessionStorage:d.localStorage}catch{return null}}function D(n,i){var r=Pe(n);try{return r?r.getItem(i):null}catch{return null}}function E(n,i,r){var p=Pe(n);try{p&&(r===null?p.removeItem(i):p.setItem(i,r))}catch{}}function x(){var n=document.querySelector(".gemboss-platform-main"),i=n?n.getBoundingClientRect().left:0;return(document.documentElement.clientWidth||d.innerWidth)-i}G.assistantFrame=function(n){n=n||{};var i={title:n.title||"Assistant",storagePrefix:n.storagePrefix||"gemboss.assistant",bodyClassPrefix:n.bodyClassPrefix||"gemboss-assistant",dockedEvent:n.dockedEvent||"gemboss:assistant-docked",allowSide:n.allowSide!==!1,keepAcrossPages:n.keepAcrossPages!==!1,fullHref:n.fullHref||"",miniHint:n.miniHint||"",canClearHistory:n.canClearHistory!==!1},r=h(Ye,n.labels||{}),p=function(){try{return i.fullHref?new URL(i.fullHref,d.location.href).pathname:""}catch{return""}},y=n.isFullLink||function(e){return!!p()&&e.pathname===p()},k=n.isOnFullPage||function(){return!!p()&&d.location.pathname===p()},Je=n.onExpand||function(){i.fullHref&&(d.location.href=i.fullHref)},Ze=n.onShrink||function(){E("session",b("presentation"),X(a));var e=document.referrer,t=!1;try{t=!!e&&new URL(e).origin===d.location.origin&&new URL(e).pathname!==d.location.pathname}catch{t=!1}t?d.history.back():m({type:"reopen"})},pe=n.onNewChat||null,me=n.onClearHistory||null,he=n.menuItems||null,ve=n.fullActions||null,b=function(e){return i.storagePrefix+"."+e},a=Ie,q=[],V=[],N=function(e,t,l,o){e.addEventListener(t,l,o),V.push(function(){e.removeEventListener(t,l,o)})},j=null,be=oe,Y=se,Q=null,Re=!1,C=0,f=u("div",{className:"gb-dock "+Le.hidden}),J=u("div",{className:"gb-dock-body"}),ge=u("div",{className:"gb-dock-pane",id:"gem-dock-pane-assistant"});n.body&&ge.appendChild(n.body),J.appendChild(ge),f.appendChild(J);var s={},ye="";function xe(){var e=document.querySelector(".gemboss-platform-main"),t=e?e.getBoundingClientRect().width:document.documentElement.clientWidth||d.innerWidth,l=Math.min(460,Math.max(0,t-48));return{min:8,max:Math.max(8,Math.floor(t-l-8))}}function Z(){var e=Math.ceil(f.getBoundingClientRect().width||600),t=document.querySelector(".gemboss-platform-main"),l=t?t.getBoundingClientRect().width:document.documentElement.clientWidth||d.innerWidth;return{min:8,max:Math.max(8,Math.floor(l-e-8))}}function m(e){var t=a;a=ce(a,e),a!==t&&(t.presentation!==a.presentation&&((a.presentation==="full"||a.presentation==="dock"||a.presentation==="side")&&E("local",b("lastMode"),a.presentation),a.presentation==="side"&&(a=ce(a,{type:"side-resize",width:Y,available:x()})),i.keepAcrossPages&&E("session",b("presentation"),a.presentation)),t.busy!==a.busy&&(Q=a.busy?Date.now():null),te(),q.slice().forEach(function(l){try{l(Ke.state())}catch(o){d.console&&d.console.error(o)}}))}function Oe(e){E("local",b("shape"),e)}function H(e){var t=d.innerHeight,l=Math.round(e)>=U(null,t);j=l?null:Math.round(e),m({type:"resize",height:e,viewport:t}),E("local",b("dockHeight"),l?null:String(Math.round(e)))}function $(e,t,l){be=Math.round(e),m({type:"slide",offsetRight:e,min:t,max:l}),E("local",b("dockOffsetRight"),String(Math.round(e)))}function M(e){Y=Math.round(e),m({type:"side-resize",width:e,available:x()}),E("local",b("sideWidth"),String(Math.round(e)))}var We=function(){m({type:"dock"}),Oe("dock")},Fe=function(){m({type:"side"}),a.sideAllowed&&Oe("side")},I=function(){m({type:"reopen"})},ze=function(){m({type:"minimize"})},ee=function(){m({type:"dismiss"})};function O(e,t,l){l=l||{};var o=u("button",{type:"button",className:["ui-menu__item",l.danger?"ui-menu__item--danger":"",l.className||""].filter(Boolean).join(" "),disabled:!!l.disabled},e);return o.addEventListener("click",function(c){var g=o.closest("details");if(g){g.removeAttribute("open");var v=g.querySelector("summary");v&&v.focus()}t&&t(c)}),o}function Be(e,t,l){var o=u("details",{className:"gb-dock-menu"}),c=u("summary",{className:t,title:e,"aria-label":e});return c.appendChild(A.more()),o.appendChild(c),o.appendChild(u("div",{className:"gemboss-popover-surface gb-dock-menu-list",title:""},l)),o}function $e(){var e=[];return(he||[]).forEach(function(t){Te(t)?e.push(t):t&&e.push(O(t.label,t.onClick,{danger:t.danger,disabled:t.disabled,className:t.className}))}),me&&e.push(O(r.clearHistory,function(){me()},{danger:!0,disabled:!i.canClearHistory})),e}N(d,"keydown",function(e){var t=f.querySelector("details.gb-dock-menu[open]");if(!(!t||e.key!=="Escape"||e.defaultPrevented||e.isComposing||e.keyCode===229)){var l=document.activeElement,o=l&&l.closest?l.closest('dialog[open], [aria-modal="true"]'):null;if(!(o&&!t.contains(o)))if(e.preventDefault(),t.contains(l)){e.stopPropagation(),t.open=!1;var c=t.querySelector("summary");c&&c.focus()}else t.open=!1}},!0),N(document,"pointerdown",function(e){Array.prototype.forEach.call(f.querySelectorAll("details.gb-dock-menu[open]"),function(t){t.contains(e.target)||(t.open=!1)})},!0),N(d,"blur",function(){Array.prototype.forEach.call(f.querySelectorAll("details.gb-dock-menu[open]"),function(e){e.open=!1})});function L(e){Re=e,f.classList.toggle("gb-dock-dragging",e)}function et(e){var t=null;e.addEventListener("pointerdown",function(o){o.preventDefault(),e.setPointerCapture(o.pointerId),L(!0),t={startY:o.clientY,startH:a.dockHeight}}),e.addEventListener("pointermove",function(o){t&&H(t.startH+(t.startY-o.clientY))});var l=function(o){t=null,L(!1);try{e.releasePointerCapture(o.pointerId)}catch{}};e.addEventListener("pointerup",l),e.addEventListener("pointercancel",l),e.addEventListener("keydown",function(o){var c=o.shiftKey?96:32,g=P(K,d.innerHeight),v;o.key==="ArrowUp"?(o.preventDefault(),H(a.dockHeight+c)):o.key==="ArrowDown"?(o.preventDefault(),H(a.dockHeight-c)):o.key==="ArrowLeft"?(v=Z(),o.preventDefault(),$(a.dockOffsetRight+c,v.min,v.max)):o.key==="ArrowRight"?(v=Z(),o.preventDefault(),$(a.dockOffsetRight-c,v.min,v.max)):o.key==="Home"?(o.preventDefault(),H(g)):o.key==="End"&&(o.preventDefault(),H(_))})}function tt(e){var t=null;e.addEventListener("pointerdown",function(o){a.presentation!=="dock"||o.target.closest&&o.target.closest("button, summary, .gb-dock-menu")||(e.setPointerCapture(o.pointerId),L(!0),t={startX:o.clientX,startOffset:a.dockOffsetRight,moved:!1})}),e.addEventListener("pointermove",function(o){if(t&&!(!t.moved&&Math.abs(o.clientX-t.startX)<4)){t.moved=!0;var c=Z();$(t.startOffset-(o.clientX-t.startX),c.min,c.max)}});var l=function(o){if(t){t=null,L(!1);try{e.releasePointerCapture(o.pointerId)}catch{}}};e.addEventListener("pointerup",l),e.addEventListener("pointercancel",l)}var S=null;function W(e,t){if(S=null,L(!1),document.body.classList.remove("ui-resizing"),e&&t)try{e.releasePointerCapture(t.pointerId)}catch{}}function nt(e){e.addEventListener("pointerdown",function(t){t.button!==0||t.pointerType==="mouse"&&t.ctrlKey||(t.preventDefault(),e.setPointerCapture(t.pointerId),L(!0),document.body.classList.add("ui-resizing"),S={startX:t.clientX,startW:a.sideWidth,id:t.pointerId})}),e.addEventListener("pointermove",function(t){if(!(!S||t.pointerId!==S.id)){if(t.pointerType==="mouse"&&t.buttons===0){W(e,t);return}M(S.startW+(S.startX-t.clientX))}}),e.addEventListener("pointerup",function(t){W(e,t)}),e.addEventListener("pointercancel",function(t){W(e,t)}),e.addEventListener("lostpointercapture",function(){S&&W()}),e.addEventListener("keydown",function(t){if(!(t.altKey||t.metaKey||t.ctrlKey)){var l=t.shiftKey?64:16;t.key==="ArrowLeft"?(t.preventDefault(),M(a.sideWidth+l)):t.key==="ArrowRight"?(t.preventDefault(),M(a.sideWidth-l)):t.key==="Home"?(t.preventDefault(),M(T)):t.key==="End"&&(t.preventDefault(),M(K))}})}function it(e){Array.prototype.slice.call(f.childNodes).forEach(function(ae){ae!==J&&f.removeChild(ae)}),s={};var t=function(ae){f.insertBefore(ae,J)},l=e==="dock",o=e==="side",c=$e();if(e==="full"){var g=u("div",{className:"gb-dock-fullchrome","data-gb-dock-chrome":""});fe(g,ve),c.length&&g.appendChild(Be(r.more,"gb-dock-shrink gb-dock-menu-pill",c)),s.shrinkLabel=u("span");var v=u("button",{type:"button",className:"gb-dock-shrink"},[A.shrink(),s.shrinkLabel]);v.addEventListener("click",function(){Ze()}),g.appendChild(v),t(g)}if(e==="mini"&&(s.miniDot=u("span",{className:"gb-dock-dot","aria-hidden":"true"}),s.miniStatus=u("span",{className:"gb-dock-ministatus"}),s.miniBar=u("button",{type:"button",className:"gb-dock-minibar"},[s.miniDot,u("strong",null,i.title),s.miniStatus,u("span",{className:"gb-dock-minichevron","aria-hidden":"true"},"\u25B2")]),s.miniBar.addEventListener("click",I),s.miniClose=u("button",{type:"button",className:"gb-dock-icon"}),s.miniCloseSr=u("span",{className:"gb-dock-sr"}),s.miniClose.appendChild(A.close()),s.miniClose.appendChild(s.miniCloseSr),s.miniClose.addEventListener("click",ee),t(u("div",{className:"gb-dock-minirow"},[s.miniBar,s.miniClose]))),o&&(s.sideGrip=u("div",{className:"ui-resizer gb-dock-sidegrip",role:"separator","aria-orientation":"vertical","aria-label":r.sideGrip,tabindex:"0"}),nt(s.sideGrip),t(s.sideGrip)),l||o){l&&(s.grip=u("div",{className:"gb-dock-grip",role:"separator","aria-orientation":"horizontal","aria-label":r.grip,tabindex:"0"},u("span",{"aria-hidden":"true"})),et(s.grip),t(s.grip)),s.dot=u("span",{className:"gb-dock-dot","aria-hidden":"true"}),s.status=u("span",{className:"gb-dock-status"});var z=u("div",{className:"gb-dock-actions"});if(pe){var Ue=u("button",{type:"button",className:"gb-dock-icon gb-dock-action",title:r.newChat},[A.plus(),u("span",{className:"gb-dock-sr"},r.newChat)]);Ue.addEventListener("click",function(){pe()}),z.appendChild(Ue)}var Xe=u("button",{type:"button",className:"gb-dock-icon",title:r.openFull},[A.expand(),u("span",{className:"gb-dock-sr"},r.openFull)]);Xe.addEventListener("click",function(){Je()}),z.appendChild(Xe);var B=c.slice();c.length&&B.push(u("hr",{className:"gb-dock-menu-sep"})),l&&a.sideAllowed&&B.push(O(r.pinSide,Fe,{className:"gb-dock-pinside"})),o&&B.push(O(r.floatPopup,We)),B.push(O(r.minimizeTitle,ze)),z.appendChild(Be(r.more,"gb-dock-icon",B)),s.close=u("button",{type:"button",className:"gb-dock-icon"}),s.closeSr=u("span",{className:"gb-dock-sr"}),s.close.appendChild(A.close()),s.close.appendChild(s.closeSr),s.close.addEventListener("click",ee),z.appendChild(s.close);var qe=u("header",{className:"gb-dock-header",title:l?r.headerTitle:null},[s.dot,u("span",{className:"gb-dock-title"},i.title),s.status,z]);l&&tt(qe),t(qe)}}function te(){var e=a.presentation,t=[a.mounted?e:"unmounted",a.sideAllowed,!!pe,!!me,i.canClearHistory,i.title,(he||[]).length,(ve||[]).length].join("|");t!==ye&&(it(a.mounted?e:"hidden"),ye=t),a.mounted&&!f.parentNode&&(n.container||document.body).appendChild(f),f.className="gb-dock "+Le[e]+(Re?" gb-dock-dragging":""),e==="hidden"?(f.removeAttribute("role"),f.removeAttribute("aria-label"),f.setAttribute("inert","")):(f.setAttribute("role","region"),f.setAttribute("aria-label",i.title),f.removeAttribute("inert")),f.style.removeProperty("height"),f.style.removeProperty("right"),f.style.removeProperty("--gb-dock-side-w"),e==="dock"&&(f.style.height=a.dockHeight+"px",f.style.right=a.dockOffsetRight+"px"),e==="side"&&f.style.setProperty("--gb-dock-side-w",a.sideWidth+"px");var l=a.busy?r.working:a.unread?r.done:r.ready;s.dot&&(s.dot.className="gb-dock-dot"+(a.busy?" gb-dock-dot-busy":"")),s.status&&(s.status.textContent=l),s.close&&(s.close.title=a.busy?r.closeBusyTitle:r.close,s.closeSr.textContent=a.busy?r.closeBusy:r.close),s.grip&&(s.grip.setAttribute("aria-valuenow",String(a.dockHeight)),s.grip.setAttribute("aria-valuemin",String(_)),s.grip.setAttribute("aria-valuemax",String(P(K,d.innerHeight)))),s.sideGrip&&(s.sideGrip.setAttribute("aria-valuenow",String(a.sideWidth)),s.sideGrip.setAttribute("aria-valuemin",String(T)),s.sideGrip.setAttribute("aria-valuemax",String(ue(K,x())))),s.miniBar&&(s.miniBar.setAttribute("aria-label",r.reopen.replace("{title}",i.title)),s.miniDot.className="gb-dock-dot"+(a.busy?" gb-dock-dot-busy":a.unread?" gb-dock-dot-unread":""),s.miniStatus.textContent=a.busy&&Q?r.working+" \xB7 "+Qe(Q):a.unread?r.answerWaiting:i.miniHint||r.askAboutScreen,s.miniClose.title=a.busy?r.openInsteadTitle:r.hideTitle,s.miniCloseSr.textContent=a.busy?r.openInstead:r.hide),s.shrinkLabel&&(s.shrinkLabel.textContent=a.sideAllowed&&a.floatShape==="side"?r.backToSide:r.shrinkToPopup),a.busy&&Q&&e==="mini"?C||(C=d.setInterval(te,1e3)):C&&(d.clearInterval(C),C=0);var o=i.bodyClassPrefix,c=document.body;c.classList.toggle(o+"-busy",a.busy),c.classList.toggle(o+"-unread",a.unread&&!a.busy),c.classList.toggle(o+"-side",e==="side"),e==="side"?c.style.setProperty(de,a.sideWidth+"px"):c.style.removeProperty(de),e!=="side"&&S&&W(),ke().forEach(function(g){var v=e!=="hidden";g.hidden=v,g.style.display=v?"none":""})}function ke(){var e=n.launchers;return e?typeof e=="string"?Array.prototype.slice.call(document.querySelectorAll(e)):Array.prototype.slice.call(e.length!==void 0?e:[e]):[]}N(document,"click",function(e){if(!(!n.launchers||e.defaultPrevented)){var t=e.target&&e.target.closest?e.target.closest("button"):null;t&&ke().indexOf(t)>=0&&(e.preventDefault(),I())}}),N(document,"click",function(e){if(!(e.defaultPrevented||e.button!==0||e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)){var t=e.target&&e.target.closest?e.target.closest("a"):null;if(!(!t||t.target==="_blank")){var l;try{l=new URL(t.href,d.location.origin)}catch{return}if(!(!y(l)||k())){var o=D("local",b("lastMode"))||"",c=!!t.closest(".gnav-assistant");(c?o==="full":o!=="dock"&&o!=="side")||(e.preventDefault(),e.stopPropagation(),I(),d.dispatchEvent(new CustomEvent(i.dockedEvent)))}}}},!0);var w=d.matchMedia?d.matchMedia(He):null,F=function(){m({type:"side-allowed",allowed:i.allowSide&&(!w||w.matches)})};w&&(w.addEventListener?(w.addEventListener("change",F),V.push(function(){w.removeEventListener("change",F)})):(w.addListener(F),V.push(function(){w.removeListener(F)}))),N(d,"resize",function(){m({type:"resize",height:U(j,d.innerHeight),viewport:d.innerHeight});var e=xe();m({type:"slide",offsetRight:be,min:e.min,max:e.max}),m({type:"side-resize",width:Y,available:x()})}),F();var Ee=D("local",b("dockHeight")),Se=Ee===null||Ee===""?NaN:Number(Ee);j=isFinite(Se)&&Se>0?Se:null,m({type:"resize",height:U(j,d.innerHeight),viewport:d.innerHeight});var we=D("local",b("dockOffsetRight")),ne=Number(we);if(we!==null&&we!==""&&isFinite(ne)&&ne>=0){be=ne;var Ge=xe();m({type:"slide",offsetRight:ne,min:Ge.min,max:Ge.max})}var Ce=D("local",b("shape"));(Ce==="side"||Ce==="dock")&&m({type:"restore-float",shape:Ce}),E("local",b("floatShape"),null);var ie=Number(D("local",b("sideWidth")));if(isFinite(ie)&&ie>0&&(Y=ie,m({type:"side-resize",width:ie,available:x()})),k())m({type:"enter-full"});else if(i.keepAcrossPages){var re=D("session",b("presentation"));re==="dock"||re==="side"?m({type:"reopen"}):(re==="mini"||re==="full")&&(m({type:"reopen"}),m({type:"minimize"}))}te();var Ke={el:f,pane:ge,state:function(){return h(a,{})},open:I,reopen:I,openDock:We,openSide:Fe,minimize:ze,dismiss:ee,toggle:function(){a.presentation==="hidden"||a.presentation==="mini"?I():ee()},enterFull:function(){m({type:"enter-full"})},leaveFull:function(){m({type:"leave-full"})},setBusy:function(e){m({type:"busy",busy:!!e})},setDockHeight:H,setSideWidth:M,setDockOffsetRight:function(e){var t=Z();$(e,t.min,t.max)},onChange:function(e){return q.push(e),function(){q=q.filter(function(t){return t!==e})}},update:function(e){e=e||{},e.title!==void 0&&(i.title=e.title),e.miniHint!==void 0&&(i.miniHint=e.miniHint),e.canClearHistory!==void 0&&(i.canClearHistory=e.canClearHistory!==!1),e.menuItems!==void 0&&(he=e.menuItems),e.fullActions!==void 0&&(ve=e.fullActions),e.labels&&(r=h(r,e.labels)),ye="",te()},destroy:function(){V.forEach(function(t){t()}),C&&d.clearInterval(C);var e=i.bodyClassPrefix;document.body.classList.remove(e+"-busy",e+"-unread",e+"-side"),document.body.style.removeProperty(de),ke().forEach(function(t){t.hidden=!1,t.style.display=""}),f.parentNode&&f.parentNode.removeChild(f)}};return Ke}})(typeof globalThis<"u"?globalThis:this);
|
package/src/index.ts
CHANGED
|
@@ -55,7 +55,7 @@ export { SettingsDialog, type SettingsDialogProps, type SettingsSectionItem } fr
|
|
|
55
55
|
export { SearchDialog, type SearchItem, type SearchSection } from "./search-dialog";
|
|
56
56
|
export { ThemeToggle } from "./theme";
|
|
57
57
|
export { THEME_KEY, themeScript } from "./theme-script";
|
|
58
|
-
export { Reactions, ReactionPicker, type ReactionPickerProps, type ReactionsProps } from "./reactions";
|
|
58
|
+
export { REACTION_LABELS, Reactions, ReactionPicker, type ReactionLabels, type ReactionPickerProps, type ReactionsProps } from "./reactions";
|
|
59
59
|
export { ActionCard, ActionCardItem, ActionCardSection, ActionChange, type ActionCardItemProps, type ActionCardOutcome, type ActionCardProps } from "./action-card";
|
|
60
60
|
// 0.43.0 (the Market redesign, 21/10/2026): the assistant asks one question and a person only confirms, and the pieces around it.
|
|
61
61
|
export { QuestionCard, MAX_QUESTION_CHOICES, type QuestionCardProps, type QuestionChoice, type QuestionChoices } from "./question-card";
|
package/src/reactions-data.ts
CHANGED
|
@@ -8,7 +8,8 @@
|
|
|
8
8
|
* Plain TypeScript (no React): a server, a plain-HTML surface and the React component all import it.
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
|
-
/** [group
|
|
11
|
+
/** [group id, [emoji, search words][]][] — the picker draws the groups in this order. The id is English and stays: it is the
|
|
12
|
+
* heading's default and the key a translation is looked up by (`labels.groupName(id)`, reactions.tsx). */
|
|
12
13
|
export const REACTION_GROUPS: ReadonlyArray<readonly [string, ReadonlyArray<readonly [string, string]>]> = [
|
|
13
14
|
["Smileys", [["😀", "grin smile happy"], ["😃", "smile happy"], ["😄", "smile laugh happy"], ["😁", "grin beam"], ["😆", "laugh squint"], ["😅", "sweat smile relief"], ["😂", "joy tears laugh lol"], ["🤣", "rofl rolling laugh"], ["😊", "blush smile"], ["😇", "innocent halo"], ["🙂", "slight smile ok"], ["😉", "wink"], ["😍", "heart eyes love"], ["🥰", "love hearts"], ["😘", "kiss"], ["😋", "yum tasty"], ["😜", "wink tongue"], ["🤪", "zany crazy"], ["🤗", "hug"], ["🤭", "oops giggle"], ["🤔", "think hmm"], ["🤨", "raised eyebrow doubt"], ["😐", "neutral"], ["😶", "no words"], ["🙄", "eye roll"], ["😏", "smirk"], ["😬", "grimace awkward"], ["😌", "relieved"], ["😴", "sleep tired"], ["😷", "mask sick"], ["🤯", "mind blown"], ["🥳", "party celebrate"], ["😎", "cool sunglasses"], ["🤓", "nerd"], ["😕", "confused"], ["😟", "worried"], ["😮", "wow surprised"], ["😲", "astonished"], ["😳", "flushed embarrassed"], ["🥺", "pleading please"], ["😢", "cry sad"], ["😭", "sob crying"], ["😱", "scream shock"], ["😤", "huff frustrated"], ["😡", "angry mad"], ["🤬", "swear"], ["💀", "dead skull"], ["🫠", "melting"], ["🫡", "salute"]]],
|
|
14
15
|
["Hands", [["👍", "like thumbs up yes ok"], ["👎", "dislike thumbs down no"], ["👌", "ok perfect"], ["✌️", "peace victory"], ["🤞", "fingers crossed luck"], ["🤟", "love you"], ["🤘", "rock"], ["👏", "clap applause"], ["🙌", "raise hands hooray"], ["👐", "open hands"], ["🤝", "handshake deal"], ["🙏", "thanks please pray"], ["💪", "strong muscle"], ["👀", "eyes looking"], ["🫶", "heart hands"], ["✍️", "writing"], ["👋", "wave hi bye"], ["☝️", "point up"], ["👇", "point down"], ["👉", "point right"], ["👈", "point left"], ["🤙", "call me"], ["🖐️", "stop hand"], ["🤌", "pinched"]]],
|
|
@@ -45,10 +46,20 @@ export function reactionWords(e: string): string {
|
|
|
45
46
|
return KEYS.get(e) ?? "";
|
|
46
47
|
}
|
|
47
48
|
|
|
48
|
-
|
|
49
|
-
|
|
49
|
+
const GROUP_OF = new Map<string, string>(REACTION_GROUPS.flatMap(([id, items]) => items.map(([e]) => [e, id] as [string, string])));
|
|
50
|
+
/** A name as a search compares it: lower case, Vietnamese marks and the like dropped ("Mặt cười" → "mat cuoi"), đ → d. */
|
|
51
|
+
const fold = (s: string) => s.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g, "").replace(/\u0111/g, "d");
|
|
52
|
+
|
|
53
|
+
/** Emoji whose search words contain the query (any case); all of them for an empty query. The search words are English.
|
|
54
|
+
* `groupName` (the picker's `labels.groupName`, 21/10/2026): a query found in a TRANSLATED group name ("mặt cười", "mat cuoi"
|
|
55
|
+
* for a group called "Mặt cười") adds that whole group, in picker order. A name left as its English id adds nothing, so a
|
|
56
|
+
* picker in English searches exactly as before. */
|
|
57
|
+
export function searchReactions(query: string, groupName?: (id: string) => string): string[] {
|
|
50
58
|
const t = query.trim().toLowerCase();
|
|
51
|
-
|
|
59
|
+
if (!t) return [...REACTION_EMOJI];
|
|
60
|
+
const q = fold(t), groups = new Set<string>();
|
|
61
|
+
if (groupName) for (const [id] of REACTION_GROUPS) { const name = groupName(id); if (name !== id && fold(String(name)).includes(q)) groups.add(id); }
|
|
62
|
+
return REACTION_EMOJI.filter((e) => KEYS.get(e)!.includes(t) || groups.has(GROUP_OF.get(e)!));
|
|
52
63
|
}
|
|
53
64
|
|
|
54
65
|
/** One emoji on one thing: who put it there. `mine` is the viewer's own. */
|
package/src/reactions.tsx
CHANGED
|
@@ -18,12 +18,55 @@
|
|
|
18
18
|
*
|
|
19
19
|
* Each target is 44px (a control, CLAUDE.md §9.1) while the visible pill is 26px: transparent padding carries the rest,
|
|
20
20
|
* so a message with reactions does not grow a whole line.
|
|
21
|
+
*
|
|
22
|
+
* Every word both write is in `REACTION_LABELS` (21/10/2026: GemCommunity's Vietnamese chat showed "Search emoji" and
|
|
23
|
+
* "Smileys"); pass `labels` (any subset) to translate. The team chat's `TEAM_CHAT_LABELS` carries the same keys and its
|
|
24
|
+
* components pass their `labels` on. reactions.test.tsx holds this file to it: no word outside the table.
|
|
21
25
|
*/
|
|
22
26
|
import "./reactions.css"; // its own stylesheet travels with it (0.23.0): a surface that never renders it never loads it
|
|
23
27
|
import React, { useEffect, useId, useRef, useState } from "react";
|
|
24
28
|
import { Icon } from "./icons";
|
|
25
29
|
import { frequentReactions, REACTION_GROUPS, reactionLabel, reactionWords, searchReactions, type Reaction } from "./reactions-data";
|
|
26
30
|
|
|
31
|
+
// labels:begin
|
|
32
|
+
/** Every word `Reactions` and `ReactionPicker` write themselves. Pass `labels` (any subset) to translate. */
|
|
33
|
+
export type ReactionLabels = {
|
|
34
|
+
/** The picker's accessible name (a `label` prop wins). */
|
|
35
|
+
pickReaction: string;
|
|
36
|
+
/** The picker's search field: its placeholder and its accessible name. */
|
|
37
|
+
searchEmoji: string;
|
|
38
|
+
/** What the picker says when the search finds nothing. */
|
|
39
|
+
noEmojiMatches: string;
|
|
40
|
+
/** The heading of this browser's row. */
|
|
41
|
+
frequentlyUsed: string;
|
|
42
|
+
/** A group's heading, by its English id in `REACTION_GROUPS` ("Smileys", "Hands", "Marks", "Work"). The id stays the key;
|
|
43
|
+
* a translated name is also searched (`searchReactions`). The emoji's own search words are English. */
|
|
44
|
+
groupName: (id: string) => string;
|
|
45
|
+
/** A picker button's accessible name where the picker puts reactions (the composer's names a button by the emoji and its
|
|
46
|
+
* search words alone): "Add 🎉 party tada celebrate", "Remove 👍 like thumbs up yes ok". */
|
|
47
|
+
pickReactionEmoji: (emoji: string, words: string, mine: boolean) => string;
|
|
48
|
+
/** The tooltip of the button that opens the picker (the reaction row's, and the team chat's action bar). */
|
|
49
|
+
addReaction: string;
|
|
50
|
+
/** The reaction row's "Add reaction" accessible name; `target` is the `target` prop, absent for none. */
|
|
51
|
+
addReactionTo: (target?: string) => string;
|
|
52
|
+
/** A chip's accessible name: its emoji, who put it (`names`, joined by ", ") and what a click does. */
|
|
53
|
+
reactionChip: (emoji: string, names: string, mine: boolean) => string;
|
|
54
|
+
};
|
|
55
|
+
|
|
56
|
+
export const REACTION_LABELS: ReactionLabels = {
|
|
57
|
+
pickReaction: "Pick a reaction",
|
|
58
|
+
searchEmoji: "Search emoji",
|
|
59
|
+
noEmojiMatches: "No emoji matches.",
|
|
60
|
+
frequentlyUsed: "Frequently used",
|
|
61
|
+
groupName: (id) => id,
|
|
62
|
+
pickReactionEmoji: (e, w, mine) => `${mine ? "Remove" : "Add"} ${e} ${w}`,
|
|
63
|
+
addReaction: "Add reaction",
|
|
64
|
+
addReactionTo: (target) => `Add a reaction to ${target ?? "this"}`,
|
|
65
|
+
reactionChip: (e, names, mine) => `${e}, ${names}. ${mine ? "Remove yours" : "Add yours"}`,
|
|
66
|
+
};
|
|
67
|
+
// labels:end
|
|
68
|
+
const words = (labels?: Partial<ReactionLabels>): ReactionLabels => (labels ? { ...REACTION_LABELS, ...labels } : REACTION_LABELS);
|
|
69
|
+
|
|
27
70
|
const RECENT_KEY = "gemboss-ui:reactions-recent";
|
|
28
71
|
const RECENT_MAX = 9;
|
|
29
72
|
|
|
@@ -47,16 +90,19 @@ export type ReactionsProps = {
|
|
|
47
90
|
/** Put or take back the viewer's emoji. The caller decides add or remove from its own state (a click on a chip that is
|
|
48
91
|
* `mine` takes it back); `toggleReaction` is the optimistic guess to draw before the server answers. */
|
|
49
92
|
onToggle?: (emoji: string) => void;
|
|
50
|
-
/** Who or what is reacted to, for screen readers: "the comment from Linh". */
|
|
93
|
+
/** Who or what is reacted to, for screen readers: "the comment from Linh" (default: `labels.addReactionTo()`'s "this"). */
|
|
51
94
|
target?: string;
|
|
52
95
|
/** Show "Add reaction" (default true). A signed-out reader sees the chips only. */
|
|
53
96
|
canReact?: boolean;
|
|
54
97
|
/** The text a signed-out reader's click should lead to instead (e.g. open sign-in); chips are buttons either way. */
|
|
55
98
|
onSignIn?: () => void;
|
|
56
99
|
className?: string;
|
|
100
|
+
/** The words (`REACTION_LABELS`, any subset), the picker's included. */
|
|
101
|
+
labels?: Partial<ReactionLabels>;
|
|
57
102
|
};
|
|
58
103
|
|
|
59
|
-
export function Reactions({ items, onToggle, target
|
|
104
|
+
export function Reactions({ items, onToggle, target, canReact = true, onSignIn, className, labels }: ReactionsProps) {
|
|
105
|
+
const t = words(labels);
|
|
60
106
|
const [open, setOpen] = useState(false);
|
|
61
107
|
const addRef = useRef<HTMLButtonElement>(null);
|
|
62
108
|
const pickerId = useId();
|
|
@@ -71,21 +117,21 @@ export function Reactions({ items, onToggle, target = "this", canReact = true, o
|
|
|
71
117
|
<div className="ui-reactions__row">
|
|
72
118
|
{items.map((r) => (
|
|
73
119
|
<button key={r.emoji} type="button" className={`ui-reaction${r.mine ? " is-mine" : ""}`} aria-pressed={r.mine}
|
|
74
|
-
title={r.names.join(", ")} aria-label={
|
|
120
|
+
title={r.names.join(", ")} aria-label={t.reactionChip(r.emoji, r.names.join(", "), r.mine)}
|
|
75
121
|
onClick={() => act(r.emoji)}>
|
|
76
122
|
<span className="ui-reaction__emoji">{r.emoji}</span>
|
|
77
123
|
<span className="ui-reaction__names">{reactionLabel(r.names)}</span>
|
|
78
124
|
</button>
|
|
79
125
|
))}
|
|
80
126
|
{canReact ? (
|
|
81
|
-
<button ref={addRef} type="button" className="ui-reaction-add" title=
|
|
127
|
+
<button ref={addRef} type="button" className="ui-reaction-add" title={t.addReaction} aria-label={t.addReactionTo(target)}
|
|
82
128
|
aria-expanded={open} aria-controls={open ? pickerId : undefined} onClick={() => setOpen((o) => !o)}>
|
|
83
129
|
<Icon name="reaction" size={18} />
|
|
84
130
|
</button>
|
|
85
131
|
) : null}
|
|
86
132
|
</div>
|
|
87
133
|
{open ? (
|
|
88
|
-
<ReactionPicker id={pickerId} items={items}
|
|
134
|
+
<ReactionPicker id={pickerId} items={items} labels={t}
|
|
89
135
|
onPick={(emoji) => { setOpen(false); act(emoji); addRef.current?.focus(); }}
|
|
90
136
|
onClose={() => { setOpen(false); addRef.current?.focus(); }} />
|
|
91
137
|
) : null}
|
|
@@ -101,15 +147,18 @@ export type ReactionPickerProps = {
|
|
|
101
147
|
/** Escape. */
|
|
102
148
|
onClose: () => void;
|
|
103
149
|
id?: string;
|
|
104
|
-
/** The group's accessible name. Default "Pick a reaction". */
|
|
150
|
+
/** The group's accessible name. Default `labels.pickReaction` ("Pick a reaction"). */
|
|
105
151
|
label?: string;
|
|
106
152
|
className?: string;
|
|
107
153
|
/** Where focus goes when it opens: the search (default), or the first emoji (under a finger, where a focused search
|
|
108
154
|
* brings the keyboard up over the picker). */
|
|
109
155
|
initialFocus?: "search" | "emoji";
|
|
156
|
+
/** The words (`REACTION_LABELS`, any subset): the search, "No emoji matches.", "Frequently used", the group headings. */
|
|
157
|
+
labels?: Partial<ReactionLabels>;
|
|
110
158
|
};
|
|
111
159
|
|
|
112
|
-
export function ReactionPicker({ items, onPick, onClose, id, label
|
|
160
|
+
export function ReactionPicker({ items, onPick, onClose, id, label, className, initialFocus = "search", labels }: ReactionPickerProps) {
|
|
161
|
+
const t = words(labels);
|
|
113
162
|
const [q, setQ] = useState("");
|
|
114
163
|
const [recent, setRecent] = useState<readonly string[]>(() => frequentReactions([]));
|
|
115
164
|
const search = useRef<HTMLInputElement>(null);
|
|
@@ -124,11 +173,11 @@ export function ReactionPicker({ items, onPick, onClose, id, label = "Pick a rea
|
|
|
124
173
|
const mine = (e: string) => Boolean(items?.some((r) => r.emoji === e && r.mine));
|
|
125
174
|
const btn = (e: string) => (
|
|
126
175
|
<button key={e} type="button" className="ui-reaction-picker__btn" title={reactionWords(e).split(" ")[0] || e}
|
|
127
|
-
aria-label={(items ?
|
|
176
|
+
aria-label={(items ? t.pickReactionEmoji(e, reactionWords(e), mine(e)) : `${e} ${reactionWords(e)}`).trim()}
|
|
128
177
|
aria-pressed={items ? mine(e) : undefined} onClick={() => onPick(e)}>{e}</button>
|
|
129
178
|
);
|
|
130
179
|
const grid = (list: readonly string[]) => <div className="ui-reaction-picker__grid">{list.map(btn)}</div>;
|
|
131
|
-
const found = q.trim() ? searchReactions(q) : null;
|
|
180
|
+
const found = q.trim() ? searchReactions(q, t.groupName) : null;
|
|
132
181
|
const onKeyDown = (ev: React.KeyboardEvent) => {
|
|
133
182
|
if (ev.key === "Escape") { ev.preventDefault(); ev.stopPropagation(); onClose(); return; }
|
|
134
183
|
const all = [...(body.current?.querySelectorAll<HTMLButtonElement>(".ui-reaction-picker__btn") ?? [])];
|
|
@@ -148,15 +197,15 @@ export function ReactionPicker({ items, onPick, onClose, id, label = "Pick a rea
|
|
|
148
197
|
all[Math.min(all.length - 1, at + step)]?.focus();
|
|
149
198
|
};
|
|
150
199
|
return (
|
|
151
|
-
<div id={id} className={["ui-reaction-picker", className].filter(Boolean).join(" ")} role="group" aria-label={label} onKeyDown={onKeyDown}>
|
|
152
|
-
<input ref={search} type="search" className="gemboss-field ui-reaction-picker__search" placeholder=
|
|
200
|
+
<div id={id} className={["ui-reaction-picker", className].filter(Boolean).join(" ")} role="group" aria-label={label ?? t.pickReaction} onKeyDown={onKeyDown}>
|
|
201
|
+
<input ref={search} type="search" className="gemboss-field ui-reaction-picker__search" placeholder={t.searchEmoji} aria-label={t.searchEmoji}
|
|
153
202
|
autoComplete="off" value={q} onChange={(e) => setQ(e.target.value)} />
|
|
154
203
|
<div ref={body} className="ui-reaction-picker__body">
|
|
155
|
-
{found ? (found.length ? grid(found) : <p className="ui-reaction-picker__empty">
|
|
204
|
+
{found ? (found.length ? grid(found) : <p className="ui-reaction-picker__empty">{t.noEmojiMatches}</p>) : (
|
|
156
205
|
<>
|
|
157
|
-
<p className="ui-reaction-picker__head">
|
|
158
|
-
{REACTION_GROUPS.map(([
|
|
159
|
-
<React.Fragment key={
|
|
206
|
+
<p className="ui-reaction-picker__head">{t.frequentlyUsed}</p>{grid(recent)}
|
|
207
|
+
{REACTION_GROUPS.map(([gid, list]) => (
|
|
208
|
+
<React.Fragment key={gid}><p className="ui-reaction-picker__head">{t.groupName(gid)}</p>{grid(list.map(([e]) => e))}</React.Fragment>
|
|
160
209
|
))}
|
|
161
210
|
</>
|
|
162
211
|
)}
|
package/src/team-chat-plain.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(function(y){"use strict";var L=y.gembossUI||(y.gembossUI={});if(L.teamChat)return;var W={reaction:'<path d="M16.5 10a6.5 6.5 0 1 1-6.5-6.5"/><path d="M7.5 11.8s.9 1.2 2.5 1.2 2.5-1.2 2.5-1.2"/><path d="M7.8 8.2h.01M12.2 8.2h.01"/><path d="M15 2.5v4M13 4.5h4"/>',emoji:'<circle cx="10" cy="10" r="6.5"/><path d="M7.5 11.8s.9 1.2 2.5 1.2 2.5-1.2 2.5-1.2"/><path d="M7.8 8.2h.01M12.2 8.2h.01"/>',reply:'<path d="M8 13.5 3.5 9 8 4.5M3.5 9h8a5 5 0 0 1 5 5v2"/>',thread:'<path d="M3 4.5h14v9H8.5L5 16.5v-3H3z"/><path d="M6.5 8h7M6.5 10.5h4.5"/>',chevronsDown:'<path d="M6 5.5l4 4 4-4M6 10.5l4 4 4-4"/>',hash:'<path d="M8 3.5 6.5 16.5M13.5 3.5 12 16.5M4 7.5h12.5M3.5 12.5H16"/>',lock:'<rect x="4.5" y="9" width="11" height="8" rx="1.5"/><path d="M7 9V6.5a3 3 0 0 1 6 0V9"/>',user:'<circle cx="10" cy="7" r="3.2"/><path d="M3.8 16.5c.8-2.8 3.3-4.5 6.2-4.5s5.4 1.7 6.2 4.5"/>',more:'<circle cx="4.5" cy="10" r="1"/><circle cx="10" cy="10" r="1"/><circle cx="15.5" cy="10" r="1"/>'},Y=["\u{1F44D}","\u2705"],G=["\u{1F44D}","\u2705","\u{1F64F}","\u{1F389}","\u{1F602}","\u2764\uFE0F","\u{1F440}","\u{1F64C}","\u{1F525}"],D=[["Smileys",[["\u{1F600}","grin smile happy"],["\u{1F603}","smile happy"],["\u{1F604}","smile laugh happy"],["\u{1F601}","grin beam"],["\u{1F606}","laugh squint"],["\u{1F605}","sweat smile relief"],["\u{1F602}","joy tears laugh lol"],["\u{1F923}","rofl rolling laugh"],["\u{1F60A}","blush smile"],["\u{1F607}","innocent halo"],["\u{1F642}","slight smile ok"],["\u{1F609}","wink"],["\u{1F60D}","heart eyes love"],["\u{1F970}","love hearts"],["\u{1F618}","kiss"],["\u{1F60B}","yum tasty"],["\u{1F61C}","wink tongue"],["\u{1F92A}","zany crazy"],["\u{1F917}","hug"],["\u{1F92D}","oops giggle"],["\u{1F914}","think hmm"],["\u{1F928}","raised eyebrow doubt"],["\u{1F610}","neutral"],["\u{1F636}","no words"],["\u{1F644}","eye roll"],["\u{1F60F}","smirk"],["\u{1F62C}","grimace awkward"],["\u{1F60C}","relieved"],["\u{1F634}","sleep tired"],["\u{1F637}","mask sick"],["\u{1F92F}","mind blown"],["\u{1F973}","party celebrate"],["\u{1F60E}","cool sunglasses"],["\u{1F913}","nerd"],["\u{1F615}","confused"],["\u{1F61F}","worried"],["\u{1F62E}","wow surprised"],["\u{1F632}","astonished"],["\u{1F633}","flushed embarrassed"],["\u{1F97A}","pleading please"],["\u{1F622}","cry sad"],["\u{1F62D}","sob crying"],["\u{1F631}","scream shock"],["\u{1F624}","huff frustrated"],["\u{1F621}","angry mad"],["\u{1F92C}","swear"],["\u{1F480}","dead skull"],["\u{1FAE0}","melting"],["\u{1FAE1}","salute"]]],["Hands",[["\u{1F44D}","like thumbs up yes ok"],["\u{1F44E}","dislike thumbs down no"],["\u{1F44C}","ok perfect"],["\u270C\uFE0F","peace victory"],["\u{1F91E}","fingers crossed luck"],["\u{1F91F}","love you"],["\u{1F918}","rock"],["\u{1F44F}","clap applause"],["\u{1F64C}","raise hands hooray"],["\u{1F450}","open hands"],["\u{1F91D}","handshake deal"],["\u{1F64F}","thanks please pray"],["\u{1F4AA}","strong muscle"],["\u{1F440}","eyes looking"],["\u{1FAF6}","heart hands"],["\u270D\uFE0F","writing"],["\u{1F44B}","wave hi bye"],["\u261D\uFE0F","point up"],["\u{1F447}","point down"],["\u{1F449}","point right"],["\u{1F448}","point left"],["\u{1F919}","call me"],["\u{1F590}\uFE0F","stop hand"],["\u{1F90C}","pinched"]]],["Marks",[["\u2764\uFE0F","heart love red"],["\u{1F9E1}","orange heart"],["\u{1F49B}","yellow heart"],["\u{1F49A}","green heart"],["\u{1F499}","blue heart"],["\u{1F49C}","purple heart"],["\u{1F5A4}","black heart"],["\u{1F4AF}","hundred perfect"],["\u2705","done check yes"],["\u2611\uFE0F","checked box"],["\u2714\uFE0F","check mark"],["\u274C","no cross wrong"],["\u2757","important exclamation"],["\u2753","question"],["\u26A0\uFE0F","warning"],["\u{1F525}","fire hot lit"],["\u2B50","star"],["\u2728","sparkles new"],["\u{1F4A1}","idea"],["\u{1F4CC}","pin"],["\u{1F680}","rocket ship launch"],["\u{1F3AF}","target goal"],["\u{1F197}","ok button"],["\u{1F195}","new"],["\u{1F534}","red circle urgent"],["\u{1F7E2}","green circle"],["\u{1F7E1}","yellow circle"],["\u2795","plus one add"]]],["Work",[["\u{1F389}","party tada celebrate"],["\u{1F38A}","confetti"],["\u{1F3C6}","trophy win"],["\u{1F947}","gold medal first"],["\u{1F381}","gift"],["\u2615","coffee"],["\u{1F37B}","cheers beer"],["\u{1F355}","pizza"],["\u{1F4C8}","chart up growth"],["\u{1F4C9}","chart down"],["\u{1F4B0}","money"],["\u{1F6D2}","cart shop"],["\u{1F4E6}","package order shipping"],["\u{1F9FE}","receipt invoice"],["\u{1F4DD}","note memo"],["\u{1F4C5}","calendar date"],["\u23F0","alarm time"],["\u23F3","waiting hourglass"],["\u{1F527}","fix wrench"],["\u{1F41B}","bug"],["\u{1F9EA}","test"],["\u{1F50D}","search look"],["\u{1F4AC}","comment chat"],["\u{1F4DE}","call phone"],["\u{1F4E7}","email"],["\u{1F512}","lock private"],["\u{1F517}","link"],["\u{1F5BC}\uFE0F","image picture"],["\u{1F4BB}","laptop computer"],["\u{1F4F1}","phone mobile"],["\u{1F648}","see no evil oops"],["\u{1F649}","hear no evil"],["\u{1F916}","robot bot ai"],["\u{1F9E0}","brain"],["\u{1F451}","crown vip"],["\u{1F48E}","gem diamond"]]]],A={channels:"Channels",conversation:"Conversation",back:"Back to channels",members:"Members",hideMembers:"Hide members",showMembers:"Show members",thread:"Thread",closeThread:"Close thread",replies:function(e){return e===1?"1 reply":e+" replies"},newMessages:"New messages",edited:"(edited)",someone:"Someone who has left",actionsFor:function(e){return"Actions for the message from "+e},react:function(e,t,n){return(n?"Remove":"Add")+" "+e+" on the message from "+t},moreReactions:function(e){return"More reactions for the message from "+e},reply:"Reply",replyTo:function(e){return"Reply to the message from "+e},replyInThread:"Reply in thread",replyInThreadTo:function(e){return"Reply in thread to the message from "+e},openThread:function(e,t){return"Open the thread, "+(e===1?"1 reply":e+" replies")+(t?", "+t:"")},jump:"Jump to the latest message",jumpNew:function(e){return"Jump to the latest message, "+e+" new"},message:"Message",send:"Send",attach:"Attach a file",emoji:"Emoji",pickEmoji:"Pick an emoji",stopReplying:"Stop replying",privateChannel:"private channel",directMessage:"direct message",mentioningYou:function(e){return e+" mentioning you"},unread:function(e){return e+" unread"},online:"Online",away:"Away",offline:"Offline"},x=Object.prototype.hasOwnProperty;function S(e){if(!e)return A;var t={},n;for(n in A)t[n]=A[n];for(n in e)x.call(e,n)&&(t[n]=e[n]);return t}var P=function(e){return typeof Node<"u"&&e instanceof Node},k=function(){return[].filter.call(arguments,Boolean).join(" ")};function i(e,t,n){var a=document.createElement(e),r;for(r in t)t[r]!==void 0&&t[r]!==null&&t[r]!==!1&&a.setAttribute(r,String(t[r]));return R(a,n)}function R(e,t){if(t==null||typeof t=="boolean"||t==="")return e;if(Array.isArray(t)){for(var n=0;n<t.length;n++)R(e,t[n]);return e}return e.appendChild(P(t)?t:document.createTextNode(String(t))),e}var pe=function(e){return e==null?void 0:String(e)},b=function(e,t){return t&&e.addEventListener("click",t),e},U=0;function _(e,t){var n=Number(t)||20,a=document.createElement("template");return a.innerHTML='<svg viewBox="0 0 20 20" width="'+n+'" height="'+n+'" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">'+(x.call(W,e)?W[e]:"")+"</g></svg>",a.content.firstChild}function I(e,t){var n=document.createElementNS("http://www.w3.org/2000/svg",e);for(var a in t)n.setAttribute(a,t[a]);return n}var fe=function(){try{return new RegExp("^\\p{L}","u")}catch{return/^[A-Za-zÀ-ɏͰ-ϿЀ-ӿ]/}}();function z(e){var t=String(e).trim().split(/\s+/).filter(Boolean),n=t.filter(function(r){return fe.test(r)}),a=n.length?n:t;return a.length?(a.length===1?a[0].slice(0,2):a[0][0]+a[a.length-1][0]).toUpperCase():"?"}function V(e){var t=0,n=String(e),a,r,l;for(a=0;a<n.length;a++)r=n.charCodeAt(a),r>=55296&&r<=56319&&a+1<n.length&&(l=n.charCodeAt(a+1),l>=56320&&l<=57343&&(r=(r-55296)*1024+(l-56320)+65536,a++)),t=t*31+r>>>0;return t%8}var he={24:"gb-avatar--24",32:"gb-avatar--32",40:"gb-avatar--40",56:"gb-avatar--56"};function E(e,t,n,a){return n=n===void 0?24:n,i("span",{class:k("gb-avatar",he[n],a),"data-tone":V(e),"aria-hidden":"true"},t?i("img",{class:"gb-avatar-img",src:t,alt:"",loading:"lazy",width:n,height:n}):z(e))}var M={},q=[];D.forEach(function(e){e[1].forEach(function(t){M[t[0]]=t[1],q.push(t[0])})});var Q=function(e){return typeof e=="string"&&x.call(M,e)},j=function(e){return x.call(M,e)?M[e]:""};function X(e){var t=String(e).trim().toLowerCase();return t?q.filter(function(n){return M[n].indexOf(t)>-1}):q.slice()}function Z(e){return e.length>2?e.slice(0,2).join(", ")+" +"+(e.length-2):e.join(", ")}var $="gemboss-ui:reactions-recent",B=9;function ee(e){var t=[];return e.concat(G).forEach(function(n){Q(n)&&t.indexOf(n)<0&&t.length<B&&t.push(n)}),t}function te(){try{var e=JSON.parse(y.localStorage&&y.localStorage.getItem($)||"[]");return Array.isArray(e)?e.filter(function(t){return typeof t=="string"&&j(t)!==""}).slice(0,B):[]}catch{return[]}}function ne(e){try{var t=[e].concat(te().filter(function(n){return n!==e})).slice(0,B);y.localStorage&&y.localStorage.setItem($,JSON.stringify(t))}catch{}}var F=function(e,t){return e.some(function(n){return n.emoji===t&&n.mine})};function O(e){var t=e.items,n=ee(te()),a=function(s){var d=t?F(t,s):!1;return b(i("button",{type:"button",class:"ui-reaction-picker__btn",title:j(s).split(" ")[0]||s,"aria-label":((t?(d?"Remove":"Add")+" ":"")+s+" "+j(s)).trim(),"aria-pressed":t?String(d):void 0},s),function(){e.onPick(s)})},r=function(s){return i("div",{class:"ui-reaction-picker__grid"},s.map(a))},l=function(s){return i("p",{class:"ui-reaction-picker__head"},s)},o=i("input",{type:"search",class:"gemboss-field ui-reaction-picker__search",placeholder:"Search emoji","aria-label":"Search emoji",autocomplete:"off",value:""}),u=i("div",{class:"ui-reaction-picker__body"}),g=function(){var s=o.value,d=s.trim()?X(s):null,c=[];d?c.push(d.length?r(d):i("p",{class:"ui-reaction-picker__empty"},"No emoji matches.")):(c.push(l("Frequently used"),r(n)),D.forEach(function(m){c.push(l(m[0]),r(m[1].map(function(v){return v[0]})))})),u.replaceChildren.apply(u,c)},p=i("div",{id:e.id,class:k("ui-reaction-picker",e.className),role:"group","aria-label":e.label==null?"Pick a reaction":e.label},[o,u]);return o.addEventListener("input",g),p.addEventListener("keydown",function(s){if(s.key==="Escape"){s.preventDefault(),s.stopPropagation(),e.onClose();return}var d=[].slice.call(u.querySelectorAll(".ui-reaction-picker__btn"));if(s.target===o){s.key==="Enter"&&(s.preventDefault(),d[0]&&d[0].click()),s.key==="ArrowDown"&&(s.preventDefault(),d[0]&&d[0].focus());return}var c=d.indexOf(document.activeElement);if(!(c<0)){var m=u.querySelector(".ui-reaction-picker__grid"),v=Math.max(1,Math.round((m?m.getBoundingClientRect().width:44)/44)),f={ArrowRight:1,ArrowLeft:-1,ArrowDown:v,ArrowUp:-v}[s.key];if(f){if(s.preventDefault(),c+f<0){o.focus();return}d[Math.min(d.length-1,c+f)]&&d[Math.min(d.length-1,c+f)].focus()}}}),g(),p}function ae(e){var t=e.items||[],n=e.target===void 0?"this":e.target,a=e.canReact===void 0?!0:e.canReact;if(!t.length&&!a)return null;var r=!1,l=null,o="gb-tc-rp"+ ++U,u=null,g=function(c){if(!a){e.onSignIn&&e.onSignIn();return}F(t,c)||ne(c),e.onToggle&&e.onToggle(c)},p=i("div",{class:"ui-reactions__row"},t.map(function(c){return b(i("button",{type:"button",class:"ui-reaction"+(c.mine?" is-mine":""),"aria-pressed":pe(c.mine),title:c.names.join(", "),"aria-label":c.emoji+", "+c.names.join(", ")+". "+(c.mine?"Remove yours":"Add yours")},[i("span",{class:"ui-reaction__emoji"},c.emoji),i("span",{class:"ui-reaction__names"},Z(c.names))]),function(){g(c.emoji)})})),s=i("div",{class:k("ui-reactions",e.className)},p),d=function(c,m){r=c,u.setAttribute("aria-expanded",String(r)),r?(u.setAttribute("aria-controls",o),l=O({id:o,items:t,onPick:function(v){d(!1,!0),g(v),u.focus()},onClose:function(){d(!1,!0),u.focus()}}),s.appendChild(l),m&&l.firstChild.focus()):(u.removeAttribute("aria-controls"),l&&l.remove(),l=null),m&&e.onOpenChange&&e.onOpenChange(r)};return a&&(u=i("button",{type:"button",class:"ui-reaction-add",title:"Add reaction","aria-label":"Add a reaction to "+n,"aria-expanded":"false"},_("reaction",18)),p.appendChild(b(u,function(){d(!r,!0)})),e.open&&d(!0,!1)),s}function re(e,t){var n=e.value.length,a=Math.min(t[0],n),r=Math.min(Math.max(t[1],a),n);return e.focus({preventScroll:!0}),e.setSelectionRange(a,r),[a,r]}function ge(e,t,n){var a=e.value,r=re(e,n),l=r[0],o=r[1];if(e.maxLength>=0&&a.length-(o-l)+t.length>e.maxLength)return!1;try{document.execCommand("insertText",!1,t)}catch{}return e.value===a&&(e.setRangeText(t,l,o,"end"),e.dispatchEvent(new Event("input",{bubbles:!0}))),!0}var me=function(){return typeof y.matchMedia=="function"&&y.matchMedia("(pointer: coarse)").matches};function be(e){var t=S(e.labels),n=e.textarea,a=e.button,r=null,l=[0,0],o=document.activeElement===n,u=e.host||n.closest&&n.closest(".gb-tc-composer__box")||n.parentNode,g="gb-tc-rp"+ ++U;a?(a.setAttribute("aria-expanded","false"),a.hasAttribute("aria-label")||a.setAttribute("aria-label",t.emoji)):a=i("button",{type:"button",class:"ui-btn ui-btn--ghost ui-btn--icon gb-tc-composer__emoji","aria-label":t.emoji,"aria-expanded":"false",disabled:n.disabled?"":void 0},_("emoji",20)),n.addEventListener("focus",function(){o=!0});var p=function(c){r&&!(c.target&&(r.contains(c.target)||a.contains(c.target)))&&s()};function s(){r&&(r.remove(),r=null,a.setAttribute("aria-expanded","false"),a.removeAttribute("aria-controls"),document.removeEventListener("pointerdown",p,!0),document.removeEventListener("focusin",p,!0))}function d(){var c=n.value.length;l=o?[n.selectionStart==null?c:n.selectionStart,n.selectionEnd==null?c:n.selectionEnd]:[c,c],r=O({id:g,className:"gb-tc-composer__emoji-pop",label:t.pickEmoji,onPick:function(v){s(),ne(v),ge(n,v,l)},onClose:function(){s(),re(n,l)}}),a.setAttribute("aria-expanded","true"),a.setAttribute("aria-controls",g),u.appendChild(r);var m=me()?r.querySelector(".ui-reaction-picker__btn"):r.firstChild;m&&m.focus(),document.addEventListener("pointerdown",p,!0),document.addEventListener("focusin",p,!0)}return b(a,function(){r?s():n.disabled||d()}),a}function ve(e){var t=e.read,n=e.of;if(n<=0)return null;var a=t>=n,r=Math.min(t,n)/n*Math.PI*2,l=I("svg",{viewBox:"0 0 14 14",width:"14",height:"14","aria-hidden":"true",focusable:"false"});return l.appendChild(I("circle",{cx:"7",cy:"7",r:"6",fill:a?"currentColor":"none",stroke:"currentColor","stroke-width":"1.4"})),a?l.appendChild(I("path",{class:"gb-tc-receipt__tick",d:"M4.2 7.2l1.9 1.9 3.7-4",fill:"none","stroke-width":"1.6","stroke-linecap":"round","stroke-linejoin":"round"})):t>0&&l.appendChild(I("path",{d:"M7 7 L7 1 A6 6 0 "+(r>Math.PI?1:0)+" 1 "+(7+6*Math.sin(r)).toFixed(2)+" "+(7-6*Math.cos(r)).toFixed(2)+" Z",fill:"currentColor"})),i("span",{class:k("gb-tc-receipt",a&&"gb-tc-receipt--all"),role:"img","aria-label":e.label,title:e.label},l)}function ye(e){var t={ArrowRight:1,ArrowLeft:-1}[e.key],n=[].slice.call(e.currentTarget.querySelectorAll("button:not([disabled]), summary, a[href]")).filter(function(l){return l.offsetParent!==null}),a=n.indexOf(document.activeElement);if(!(a<0)){var r=t?n[(a+t+n.length)%n.length]:e.key==="Home"?n[0]:e.key==="End"?n[n.length-1]:null;r&&(e.preventDefault(),r.focus())}}function _e(e){var t=S(e.labels),n=e.author||t.someone,a=e.reactions||[],r=e.editor!=null,l=!!(e.picking&&e.onReact),o=null,u=null,g=!1,p=function(){var h=e.time;return P(h)&&g?h.cloneNode(!0):(g=!0,h)},s=function(){return k("gb-tc-msg",e.grouped&&"gb-tc-msg--grouped",e.mentionsMe&&"gb-tc-msg--mention",e.highlight&&"gb-tc-msg--highlight",e.sending&&"gb-tc-msg--sending",e.failed&&"gb-tc-msg--failed",l&&"gb-tc-msg--active",r&&"gb-tc-msg--editing",e.className)},d=i("li",{id:e.id,class:s(),"data-msg-id":e.messageId,tabindex:"-1"},e.grouped?i("time",{class:"gb-tc-msg__hover-time",datetime:e.dateTime},p()):e.avatar!=null?e.avatar:E(n,e.avatarSrc,32,"gb-tc-msg__av")),c=i("div",{class:"gb-tc-msg__main"});e.replyTo&&c.appendChild(b(i("button",{type:"button",class:"gb-tc-quote","aria-busy":e.replyTo.busy||void 0},[i("span",{class:"gb-tc-quote__who"},e.replyTo.author||t.someone),i("span",{class:"gb-tc-quote__text"},e.replyTo.excerpt)]),e.replyTo.onOpen)),c.appendChild(e.grouped?i("span",{class:"gb-tc-sr"},[n,", ",p(),": "]):i("div",{class:"gb-tc-msg__who"},[i("span",{class:"gb-tc-msg__name"},n),e.badges,i("time",{class:"gb-tc-msg__time",datetime:e.dateTime},p())])),r?c.appendChild(i("div",{class:"gb-tc-msg__editor"},e.editor)):(e.body!=null||e.edited||e.receipt)&&c.appendChild(i("div",{class:"gb-tc-msg__body"},[e.body,e.edited?i("span",{class:"gb-tc-msg__edited"},t.edited):null,e.receipt])),e.status&&c.appendChild(i("p",{class:"gb-tc-msg__status",role:e.failed?"alert":void 0},e.status)),e.attachments&&c.appendChild(i("div",{class:"gb-tc-msg__files"},e.attachments)),e.extra&&c.appendChild(i("div",{class:"gb-tc-msg__extra"},e.extra));var m=function(h,C){e.onPickingChange&&e.onPickingChange(h,C)},v=a.length?ae({items:a,onToggle:e.onReact,canReact:!!e.onReact,target:"the message from "+n,open:e.reactionsPicking,onOpenChange:function(h){m("reactions",h)}}):null,f=e.thread,H=null;f&&f.count>0&&(H=b(i("button",{type:"button",class:"gb-tc-threadprev","aria-label":t.openThread(f.count,f.last==null?"":f.last)},[f.repliers&&f.repliers.length?i("span",{class:"gb-tc-threadprev__faces","aria-hidden":"true"},f.repliers.slice(0,3).map(function(h){return E(h.name,h.src,24)})):null,i("span",{class:"gb-tc-threadprev__count"},t.replies(f.count)),f.last?i("span",{class:"gb-tc-threadprev__last"},f.last):null]),f.onOpen)),R(c,[v,H]),d.appendChild(c);var N=function(h,C){l=h,d.className=s(),u&&u.setAttribute("aria-expanded",String(l)),l?(o=O({items:a,onPick:function(Re){N(!1,!0),e.onReact(Re),u.focus()},onClose:function(){N(!1,!0),u.focus()}}),c.insertBefore(o,v||H),C&&o.firstChild.focus()):o&&(o.remove(),o=null),C&&m("bar",l)};if(!r&&!e.sending&&(e.onReact||e.onReply||e.onOpenThread||e.moreActions)){var w=i("div",{class:"gb-tc-acts",role:"toolbar","aria-label":t.actionsFor(n)});e.onReact&&(Y.forEach(function(h){var C=F(a,h);w.appendChild(b(i("button",{type:"button",class:"gb-tc-act gb-tc-act--quick","aria-pressed":String(C),"aria-label":t.react(h,n,C)},h),function(){e.onReact(h)}))}),u=i("button",{type:"button",class:"gb-tc-act","aria-expanded":String(l),"aria-label":t.moreReactions(n),title:"Add reaction"},_("reaction",18)),w.appendChild(b(u,function(){N(!l,!0)}))),e.onReply&&w.appendChild(b(i("button",{type:"button",class:"gb-tc-act","aria-label":t.replyTo(n),title:t.reply},_("reply",18)),e.onReply)),e.onOpenThread&&w.appendChild(b(i("button",{type:"button",class:"gb-tc-act","aria-label":t.replyInThreadTo(n),title:t.replyInThread},_("thread",18)),e.onOpenThread)),R(w,e.moreActions),w.addEventListener("keydown",ye),d.appendChild(w)}return l&&N(!0,!1),d}function ke(e,t){return i("li",{class:"gb-tc-day"},t?i("time",{class:"gb-tc-day__label",datetime:t},e):i("span",{class:"gb-tc-day__label"},e))}function we(e){var t=S(e);return i("li",{class:"gb-tc-new"},i("span",{class:"gb-tc-new__label",role:"separator","aria-label":t.newMessages},t.newMessages))}function Ce(e){return e=e||{},ie(b(i("button",{type:"button",class:"gb-tc-jump"},_("chevronsDown",20)),e.onJump),e)}function ie(e,t){t=t||{};var n=S(t.labels),a=t.count===void 0?0:t.count,r=e.querySelector(".gb-tc-jump__n");return t.visible===void 0||t.visible?e.removeAttribute("hidden"):e.setAttribute("hidden",""),e.setAttribute("aria-label",a?n.jumpNew(a):n.jump),a?(r||(r=e.appendChild(i("span",{class:"gb-tc-jump__n","aria-hidden":"true"}))),r.textContent=a>99?"99+":String(a),e):(r&&r.remove(),e)}var Se={channel:"hash",private:"lock",dm:"user"},le={online:"gb-tc-presence gb-tc-presence--online",away:"gb-tc-presence gb-tc-presence--away",offline:"gb-tc-presence gb-tc-presence--offline"};function ce(e){var t=S(e.labels),n=e.kind===void 0?"channel":e.kind,a=e.unread===void 0?0:e.unread,r=e.mentions===void 0?0:e.mentions,l=[e.name,n==="private"?t.privateChannel:n==="dm"?t.directMessage:null,r?t.mentioningYou(r):null,a?t.unread(a):null].filter(Boolean).join(", "),o=[i("span",{class:"gb-tc-channel__glyph","aria-hidden":"true"},[n==="dm"&&e.avatar?E(e.avatar.name==null?e.name:e.avatar.name,e.avatar.src,24,"gb-tc-channel__av"):_(Se[n],16),n==="dm"&&e.online!==void 0?i("span",{class:le[e.online?"online":"offline"]}):null]),i("span",{class:"gb-tc-channel__name"},e.name),r?i("span",{class:"gb-tc-badge gb-tc-badge--mention","aria-hidden":"true"},"@"+r):null,a?i("span",{class:"gb-tc-badge","aria-hidden":"true"},a):null],u=k("gb-tc-channel",a>0&&"gb-tc-channel--unread");return i("li",null,b(e.href!==void 0?i("a",{class:u,href:e.href,"aria-current":e.active?"page":void 0,"aria-label":l},o):i("button",{type:"button",class:u,"aria-current":e.active?"true":void 0,"aria-label":l},o),e.onOpen))}function se(e,t,n,a){var r=(e.id==null?"gb-tc-s"+ ++U:e.id)+"-h";return i("div",{class:t[0],role:"group","aria-labelledby":r},[i("h3",{class:t[1],id:r},n),i("ul",{class:t[2]},(e.items||[]).map(function(l){return l&&!P(l)?a(l):l}))])}function Ee(e){return se(e,["gb-tc-rail__section","gb-tc-rail__heading","gb-tc-rail__list"],e.label,ce)}function Me(e){return se(e,["gb-tc-people__section","gb-tc-people__heading","gb-tc-people__list"],[e.label,e.count!==void 0?" \u2014 "+e.count:null],oe)}function oe(e){var t=S(e.labels),n=[i("span",{class:"gb-tc-person__av"},[e.avatar!=null?e.avatar:E(e.name,e.src,32),e.presence?i("span",{class:le[e.presence]},i("span",{class:"gb-tc-sr"},t[e.presence])):null]),i("span",{class:"gb-tc-person__text"},[i("span",{class:"gb-tc-person__name"},e.name),e.subtitle?i("span",{class:"gb-tc-person__sub"},e.subtitle):null]),e.role?i("span",{class:"gb-tc-person__role"},e.role):null],a=k("gb-tc-person",e.presence==="offline"&&"gb-tc-person--offline");return i("li",null,b(e.href!==void 0?i("a",{class:a,href:e.href,title:e.name},n):e.onSelect?i("button",{type:"button",class:a,title:e.name},n):i("div",{class:a,title:e.name},n),e.onSelect))}var J=function(e){return e instanceof Date?e:new Date(e)},ue={};function K(e,t){var n=J(e),a,r,l,o;if(t){if(a=ue[t],a===void 0){try{a=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric"})}catch{a=null}ue[t]=a}if(a&&!isNaN(n.getTime())){for(r={},l=a.formatToParts(n),o=0;o<l.length;o++)l[o].type!=="literal"&&(r[l[o].type]=Number(l[o].value));return[r.year,r.month,r.day]}}return[n.getFullYear(),n.getMonth()+1,n.getDate()]}function T(e,t){var n=K(e,t);return n[0]+"-"+n[1]+"-"+n[2]}function Te(e,t){var n=K(e,t),a=function(r){return(r<10?"0":"")+r};return n[0]+"-"+a(n[1])+"-"+a(n[2])}function Ae(e,t,n){t=t===void 0?new Date:t;var a=T(e,n),r=K(t,n),l;return a===r[0]+"-"+r[1]+"-"+r[2]?"Today":(l=new Date(Date.UTC(r[0],r[1]-1,r[2]-1)),a===l.getUTCFullYear()+"-"+(l.getUTCMonth()+1)+"-"+l.getUTCDate()?"Yesterday":null)}function xe(e,t){t=t||{};var n=t.groupWithinMs==null?5*60*1e3:t.groupWithinMs,a=-1,r=[],l,o=t.timeZone;if(t.isUnread){for(l=0;l<e.length;l++)if(t.isUnread(e[l])&&(t.meId==null||e[l].authorId!==t.meId)){a=l;break}}return e.forEach(function(u,g){var p=g>0?e[g-1]:void 0,s=J(u.at),d=!p||T(p.at,o)!==T(s,o);d&&r.push({kind:"day",key:T(s,o),date:s}),g===a&&r.push({kind:"new"}),r.push({kind:"message",message:u,grouped:!!(p&&!d&&g!==a&&u.authorId!=null&&p.authorId===u.authorId&&u.replyToId==null&&s.getTime()-J(p.at).getTime()<n)})}),r}L.teamChat={message:_e,readReceipt:ve,daySeparator:ke,newMessagesLine:we,jumpToLatest:Ce,updateJump:ie,channelSection:Ee,channelItem:ce,peopleSection:Me,personRow:oe,reactions:ae,reactionPicker:O,emojiButton:be,avatar:function(e){return E(e.name,e.src,e.size,e.className)},icon:_,rows:xe,dayKey:T,dayISO:Te,dayWord:Ae,LABELS:A,initialsOf:z,avatarTone:V,isReactionEmoji:Q,reactionWords:j,searchReactions:X,reactionLabel:Z,frequentReactions:ee,QUICK_REACTIONS:Y,SUGGESTED_REACTIONS:G,REACTION_GROUPS:D};function de(){!L.openModal&&y.console&&document.querySelector('script[src*="kit-plain"]')&&y.console.error("@gemboss/ui team-chat-plain.js: load it after kit-plain.js (kit-plain.js defines nothing when gembossUI exists)")}y.document&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",de,{once:!0}):de())})(typeof globalThis<"u"?globalThis:this);
|
|
1
|
+
(function(y){"use strict";var P=y.gembossUI||(y.gembossUI={});if(P.teamChat)return;var H={reaction:'<path d="M16.5 10a6.5 6.5 0 1 1-6.5-6.5"/><path d="M7.5 11.8s.9 1.2 2.5 1.2 2.5-1.2 2.5-1.2"/><path d="M7.8 8.2h.01M12.2 8.2h.01"/><path d="M15 2.5v4M13 4.5h4"/>',emoji:'<circle cx="10" cy="10" r="6.5"/><path d="M7.5 11.8s.9 1.2 2.5 1.2 2.5-1.2 2.5-1.2"/><path d="M7.8 8.2h.01M12.2 8.2h.01"/>',reply:'<path d="M8 13.5 3.5 9 8 4.5M3.5 9h8a5 5 0 0 1 5 5v2"/>',thread:'<path d="M3 4.5h14v9H8.5L5 16.5v-3H3z"/><path d="M6.5 8h7M6.5 10.5h4.5"/>',chevronsDown:'<path d="M6 5.5l4 4 4-4M6 10.5l4 4 4-4"/>',hash:'<path d="M8 3.5 6.5 16.5M13.5 3.5 12 16.5M4 7.5h12.5M3.5 12.5H16"/>',lock:'<rect x="4.5" y="9" width="11" height="8" rx="1.5"/><path d="M7 9V6.5a3 3 0 0 1 6 0V9"/>',user:'<circle cx="10" cy="7" r="3.2"/><path d="M3.8 16.5c.8-2.8 3.3-4.5 6.2-4.5s5.4 1.7 6.2 4.5"/>',more:'<circle cx="4.5" cy="10" r="1"/><circle cx="10" cy="10" r="1"/><circle cx="15.5" cy="10" r="1"/>'},W=["\u{1F44D}","\u2705"],Y=["\u{1F44D}","\u2705","\u{1F64F}","\u{1F389}","\u{1F602}","\u2764\uFE0F","\u{1F440}","\u{1F64C}","\u{1F525}"],R=[["Smileys",[["\u{1F600}","grin smile happy"],["\u{1F603}","smile happy"],["\u{1F604}","smile laugh happy"],["\u{1F601}","grin beam"],["\u{1F606}","laugh squint"],["\u{1F605}","sweat smile relief"],["\u{1F602}","joy tears laugh lol"],["\u{1F923}","rofl rolling laugh"],["\u{1F60A}","blush smile"],["\u{1F607}","innocent halo"],["\u{1F642}","slight smile ok"],["\u{1F609}","wink"],["\u{1F60D}","heart eyes love"],["\u{1F970}","love hearts"],["\u{1F618}","kiss"],["\u{1F60B}","yum tasty"],["\u{1F61C}","wink tongue"],["\u{1F92A}","zany crazy"],["\u{1F917}","hug"],["\u{1F92D}","oops giggle"],["\u{1F914}","think hmm"],["\u{1F928}","raised eyebrow doubt"],["\u{1F610}","neutral"],["\u{1F636}","no words"],["\u{1F644}","eye roll"],["\u{1F60F}","smirk"],["\u{1F62C}","grimace awkward"],["\u{1F60C}","relieved"],["\u{1F634}","sleep tired"],["\u{1F637}","mask sick"],["\u{1F92F}","mind blown"],["\u{1F973}","party celebrate"],["\u{1F60E}","cool sunglasses"],["\u{1F913}","nerd"],["\u{1F615}","confused"],["\u{1F61F}","worried"],["\u{1F62E}","wow surprised"],["\u{1F632}","astonished"],["\u{1F633}","flushed embarrassed"],["\u{1F97A}","pleading please"],["\u{1F622}","cry sad"],["\u{1F62D}","sob crying"],["\u{1F631}","scream shock"],["\u{1F624}","huff frustrated"],["\u{1F621}","angry mad"],["\u{1F92C}","swear"],["\u{1F480}","dead skull"],["\u{1FAE0}","melting"],["\u{1FAE1}","salute"]]],["Hands",[["\u{1F44D}","like thumbs up yes ok"],["\u{1F44E}","dislike thumbs down no"],["\u{1F44C}","ok perfect"],["\u270C\uFE0F","peace victory"],["\u{1F91E}","fingers crossed luck"],["\u{1F91F}","love you"],["\u{1F918}","rock"],["\u{1F44F}","clap applause"],["\u{1F64C}","raise hands hooray"],["\u{1F450}","open hands"],["\u{1F91D}","handshake deal"],["\u{1F64F}","thanks please pray"],["\u{1F4AA}","strong muscle"],["\u{1F440}","eyes looking"],["\u{1FAF6}","heart hands"],["\u270D\uFE0F","writing"],["\u{1F44B}","wave hi bye"],["\u261D\uFE0F","point up"],["\u{1F447}","point down"],["\u{1F449}","point right"],["\u{1F448}","point left"],["\u{1F919}","call me"],["\u{1F590}\uFE0F","stop hand"],["\u{1F90C}","pinched"]]],["Marks",[["\u2764\uFE0F","heart love red"],["\u{1F9E1}","orange heart"],["\u{1F49B}","yellow heart"],["\u{1F49A}","green heart"],["\u{1F499}","blue heart"],["\u{1F49C}","purple heart"],["\u{1F5A4}","black heart"],["\u{1F4AF}","hundred perfect"],["\u2705","done check yes"],["\u2611\uFE0F","checked box"],["\u2714\uFE0F","check mark"],["\u274C","no cross wrong"],["\u2757","important exclamation"],["\u2753","question"],["\u26A0\uFE0F","warning"],["\u{1F525}","fire hot lit"],["\u2B50","star"],["\u2728","sparkles new"],["\u{1F4A1}","idea"],["\u{1F4CC}","pin"],["\u{1F680}","rocket ship launch"],["\u{1F3AF}","target goal"],["\u{1F197}","ok button"],["\u{1F195}","new"],["\u{1F534}","red circle urgent"],["\u{1F7E2}","green circle"],["\u{1F7E1}","yellow circle"],["\u2795","plus one add"]]],["Work",[["\u{1F389}","party tada celebrate"],["\u{1F38A}","confetti"],["\u{1F3C6}","trophy win"],["\u{1F947}","gold medal first"],["\u{1F381}","gift"],["\u2615","coffee"],["\u{1F37B}","cheers beer"],["\u{1F355}","pizza"],["\u{1F4C8}","chart up growth"],["\u{1F4C9}","chart down"],["\u{1F4B0}","money"],["\u{1F6D2}","cart shop"],["\u{1F4E6}","package order shipping"],["\u{1F9FE}","receipt invoice"],["\u{1F4DD}","note memo"],["\u{1F4C5}","calendar date"],["\u23F0","alarm time"],["\u23F3","waiting hourglass"],["\u{1F527}","fix wrench"],["\u{1F41B}","bug"],["\u{1F9EA}","test"],["\u{1F50D}","search look"],["\u{1F4AC}","comment chat"],["\u{1F4DE}","call phone"],["\u{1F4E7}","email"],["\u{1F512}","lock private"],["\u{1F517}","link"],["\u{1F5BC}\uFE0F","image picture"],["\u{1F4BB}","laptop computer"],["\u{1F4F1}","phone mobile"],["\u{1F648}","see no evil oops"],["\u{1F649}","hear no evil"],["\u{1F916}","robot bot ai"],["\u{1F9E0}","brain"],["\u{1F451}","crown vip"],["\u{1F48E}","gem diamond"]]]],I={channels:"Channels",conversation:"Conversation",back:"Back to channels",members:"Members",hideMembers:"Hide members",showMembers:"Show members",thread:"Thread",closeThread:"Close thread",replies:function(e){return e===1?"1 reply":e+" replies"},newMessages:"New messages",edited:"(edited)",someone:"Someone who has left",actionsFor:function(e){return"Actions for the message from "+e},react:function(e,t,n){return(n?"Remove":"Add")+" "+e+" on the message from "+t},moreReactions:function(e){return"More reactions for the message from "+e},messageFrom:function(e){return"the message from "+e},reply:"Reply",replyTo:function(e){return"Reply to the message from "+e},replyInThread:"Reply in thread",replyInThreadTo:function(e){return"Reply in thread to the message from "+e},openThread:function(e,t){return"Open the thread, "+(e===1?"1 reply":e+" replies")+(t?", "+t:"")},jump:"Jump to the latest message",jumpNew:function(e){return"Jump to the latest message, "+e+" new"},message:"Message",send:"Send",attach:"Attach a file",emoji:"Emoji",pickEmoji:"Pick an emoji",stopReplying:"Stop replying",privateChannel:"private channel",directMessage:"direct message",mentioningYou:function(e){return e+" mentioning you"},unread:function(e){return e+" unread"},online:"Online",away:"Away",offline:"Offline",pickReaction:"Pick a reaction",searchEmoji:"Search emoji",noEmojiMatches:"No emoji matches.",frequentlyUsed:"Frequently used",groupName:function(e){return e},pickReactionEmoji:function(e,t,n){return(n?"Remove":"Add")+" "+e+" "+t},addReaction:"Add reaction",addReactionTo:function(e){return"Add a reaction to "+(e??"this")},reactionChip:function(e,t,n){return e+", "+t+". "+(n?"Remove yours":"Add yours")}},M=Object.prototype.hasOwnProperty;function _(e){if(!e)return I;var t={},n;for(n in I)t[n]=I[n];for(n in e)M.call(e,n)&&(t[n]=e[n]);return t}var U=function(e){return typeof Node<"u"&&e instanceof Node},C=function(){return[].filter.call(arguments,Boolean).join(" ")};function i(e,t,n){var a=document.createElement(e),r;for(r in t)t[r]!==void 0&&t[r]!==null&&t[r]!==!1&&a.setAttribute(r,String(t[r]));return O(a,n)}function O(e,t){if(t==null||typeof t=="boolean"||t==="")return e;if(Array.isArray(t)){for(var n=0;n<t.length;n++)O(e,t[n]);return e}return e.appendChild(U(t)?t:document.createTextNode(String(t))),e}var he=function(e){return e==null?void 0:String(e)},b=function(e,t){return t&&e.addEventListener("click",t),e},q=0;function k(e,t){var n=Number(t)||20,a=document.createElement("template");return a.innerHTML='<svg viewBox="0 0 20 20" width="'+n+'" height="'+n+'" aria-hidden="true" focusable="false"><g fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round">'+(M.call(H,e)?H[e]:"")+"</g></svg>",a.content.firstChild}function N(e,t){var n=document.createElementNS("http://www.w3.org/2000/svg",e);for(var a in t)n.setAttribute(a,t[a]);return n}var ge=function(){try{return new RegExp("^\\p{L}","u")}catch{return/^[A-Za-zÀ-ɏͰ-ϿЀ-ӿ]/}}();function z(e){var t=String(e).trim().split(/\s+/).filter(Boolean),n=t.filter(function(r){return ge.test(r)}),a=n.length?n:t;return a.length?(a.length===1?a[0].slice(0,2):a[0][0]+a[a.length-1][0]).toUpperCase():"?"}function V(e){var t=0,n=String(e),a,r,l;for(a=0;a<n.length;a++)r=n.charCodeAt(a),r>=55296&&r<=56319&&a+1<n.length&&(l=n.charCodeAt(a+1),l>=56320&&l<=57343&&(r=(r-55296)*1024+(l-56320)+65536,a++)),t=t*31+r>>>0;return t%8}var me={24:"gb-avatar--24",32:"gb-avatar--32",40:"gb-avatar--40",56:"gb-avatar--56"};function T(e,t,n,a){return n=n===void 0?24:n,i("span",{class:C("gb-avatar",me[n],a),"data-tone":V(e),"aria-hidden":"true"},t?i("img",{class:"gb-avatar-img",src:t,alt:"",loading:"lazy",width:n,height:n}):z(e))}var x={},B=[];R.forEach(function(e){e[1].forEach(function(t){x[t[0]]=t[1],B.push(t[0])})});var Q=function(e){return typeof e=="string"&&M.call(x,e)},A=function(e){return M.call(x,e)?x[e]:""},X={};R.forEach(function(e){e[1].forEach(function(t){X[t[0]]=e[0]})});var Z=function(e){return e.toLowerCase().normalize("NFD").replace(/[\u0300-\u036f]/g,"").replace(/\u0111/g,"d")};function $(e,t){var n=String(e).trim().toLowerCase();if(!n)return B.slice();var a=Z(n),r={};return t&&R.forEach(function(l){var o=t(l[0]);o!==l[0]&&Z(String(o)).indexOf(a)>-1&&(r[l[0]]=!0)}),B.filter(function(l){return x[l].indexOf(n)>-1||M.call(r,X[l])})}function ee(e){return e.length>2?e.slice(0,2).join(", ")+" +"+(e.length-2):e.join(", ")}var te="gemboss-ui:reactions-recent",F=9;function ne(e){var t=[];return e.concat(Y).forEach(function(n){Q(n)&&t.indexOf(n)<0&&t.length<F&&t.push(n)}),t}function ae(){try{var e=JSON.parse(y.localStorage&&y.localStorage.getItem(te)||"[]");return Array.isArray(e)?e.filter(function(t){return typeof t=="string"&&A(t)!==""}).slice(0,F):[]}catch{return[]}}function re(e){try{var t=[e].concat(ae().filter(function(n){return n!==e})).slice(0,F);y.localStorage&&y.localStorage.setItem(te,JSON.stringify(t))}catch{}}var J=function(e,t){return e.some(function(n){return n.emoji===t&&n.mine})};function L(e){var t=_(e.labels),n=e.items,a=ne(ae()),r=function(s){var c=n?J(n,s):!1;return b(i("button",{type:"button",class:"ui-reaction-picker__btn",title:A(s).split(" ")[0]||s,"aria-label":(n?t.pickReactionEmoji(s,A(s),c):s+" "+A(s)).trim(),"aria-pressed":n?String(c):void 0},s),function(){e.onPick(s)})},l=function(s){return i("div",{class:"ui-reaction-picker__grid"},s.map(r))},o=function(s){return i("p",{class:"ui-reaction-picker__head"},s)},u=i("input",{type:"search",class:"gemboss-field ui-reaction-picker__search",placeholder:t.searchEmoji,"aria-label":t.searchEmoji,autocomplete:"off",value:""}),p=i("div",{class:"ui-reaction-picker__body"}),d=function(){var s=u.value,c=s.trim()?$(s,t.groupName):null,h=[];c?h.push(c.length?l(c):i("p",{class:"ui-reaction-picker__empty"},t.noEmojiMatches)):(h.push(o(t.frequentlyUsed),l(a)),R.forEach(function(v){h.push(o(t.groupName(v[0])),l(v[1].map(function(g){return g[0]})))})),p.replaceChildren.apply(p,h)},f=i("div",{id:e.id,class:C("ui-reaction-picker",e.className),role:"group","aria-label":e.label==null?t.pickReaction:e.label},[u,p]);return u.addEventListener("input",d),f.addEventListener("keydown",function(s){if(s.key==="Escape"){s.preventDefault(),s.stopPropagation(),e.onClose();return}var c=[].slice.call(p.querySelectorAll(".ui-reaction-picker__btn"));if(s.target===u){s.key==="Enter"&&(s.preventDefault(),c[0]&&c[0].click()),s.key==="ArrowDown"&&(s.preventDefault(),c[0]&&c[0].focus());return}var h=c.indexOf(document.activeElement);if(!(h<0)){var v=p.querySelector(".ui-reaction-picker__grid"),g=Math.max(1,Math.round((v?v.getBoundingClientRect().width:44)/44)),w={ArrowRight:1,ArrowLeft:-1,ArrowDown:g,ArrowUp:-g}[s.key];if(w){if(s.preventDefault(),h+w<0){u.focus();return}c[Math.min(c.length-1,h+w)]&&c[Math.min(c.length-1,h+w)].focus()}}}),d(),f}function ie(e){var t=_(e.labels),n=e.items||[],a=e.canReact===void 0?!0:e.canReact;if(!n.length&&!a)return null;var r=!1,l=null,o="gb-tc-rp"+ ++q,u=null,p=function(c){if(!a){e.onSignIn&&e.onSignIn();return}J(n,c)||re(c),e.onToggle&&e.onToggle(c)},d=i("div",{class:"ui-reactions__row"},n.map(function(c){return b(i("button",{type:"button",class:"ui-reaction"+(c.mine?" is-mine":""),"aria-pressed":he(c.mine),title:c.names.join(", "),"aria-label":t.reactionChip(c.emoji,c.names.join(", "),c.mine)},[i("span",{class:"ui-reaction__emoji"},c.emoji),i("span",{class:"ui-reaction__names"},ee(c.names))]),function(){p(c.emoji)})})),f=i("div",{class:C("ui-reactions",e.className)},d),s=function(c,h){r=c,u.setAttribute("aria-expanded",String(r)),r?(u.setAttribute("aria-controls",o),l=L({id:o,items:n,labels:t,onPick:function(v){s(!1,!0),p(v),u.focus()},onClose:function(){s(!1,!0),u.focus()}}),f.appendChild(l),h&&l.firstChild.focus()):(u.removeAttribute("aria-controls"),l&&l.remove(),l=null),h&&e.onOpenChange&&e.onOpenChange(r)};return a&&(u=i("button",{type:"button",class:"ui-reaction-add",title:t.addReaction,"aria-label":t.addReactionTo(e.target),"aria-expanded":"false"},k("reaction",18)),d.appendChild(b(u,function(){s(!r,!0)})),e.open&&s(!0,!1)),f}function le(e,t){var n=e.value.length,a=Math.min(t[0],n),r=Math.min(Math.max(t[1],a),n);return e.focus({preventScroll:!0}),e.setSelectionRange(a,r),[a,r]}function be(e,t,n){var a=e.value,r=le(e,n),l=r[0],o=r[1];if(e.maxLength>=0&&a.length-(o-l)+t.length>e.maxLength)return!1;try{document.execCommand("insertText",!1,t)}catch{}return e.value===a&&(e.setRangeText(t,l,o,"end"),e.dispatchEvent(new Event("input",{bubbles:!0}))),!0}var ve=function(){return typeof y.matchMedia=="function"&&y.matchMedia("(pointer: coarse)").matches};function ye(e){var t=_(e.labels),n=e.textarea,a=e.button,r=null,l=[0,0],o=document.activeElement===n,u=e.host||n.closest&&n.closest(".gb-tc-composer__box")||n.parentNode,p="gb-tc-rp"+ ++q;a?(a.setAttribute("aria-expanded","false"),a.hasAttribute("aria-label")||a.setAttribute("aria-label",t.emoji)):a=i("button",{type:"button",class:"ui-btn ui-btn--ghost ui-btn--icon gb-tc-composer__emoji","aria-label":t.emoji,"aria-expanded":"false",disabled:n.disabled?"":void 0},k("emoji",20)),n.addEventListener("focus",function(){o=!0});var d=function(c){r&&!(c.target&&(r.contains(c.target)||a.contains(c.target)))&&f()};function f(){r&&(r.remove(),r=null,a.setAttribute("aria-expanded","false"),a.removeAttribute("aria-controls"),document.removeEventListener("pointerdown",d,!0),document.removeEventListener("focusin",d,!0))}function s(){var c=n.value.length;l=o?[n.selectionStart==null?c:n.selectionStart,n.selectionEnd==null?c:n.selectionEnd]:[c,c],r=L({id:p,className:"gb-tc-composer__emoji-pop",label:t.pickEmoji,labels:t,onPick:function(v){f(),re(v),be(n,v,l)},onClose:function(){f(),le(n,l)}}),a.setAttribute("aria-expanded","true"),a.setAttribute("aria-controls",p),u.appendChild(r);var h=ve()?r.querySelector(".ui-reaction-picker__btn"):r.firstChild;h&&h.focus(),document.addEventListener("pointerdown",d,!0),document.addEventListener("focusin",d,!0)}return b(a,function(){r?f():n.disabled||s()}),a}function _e(e){var t=e.read,n=e.of;if(n<=0)return null;var a=t>=n,r=Math.min(t,n)/n*Math.PI*2,l=N("svg",{viewBox:"0 0 14 14",width:"14",height:"14","aria-hidden":"true",focusable:"false"});return l.appendChild(N("circle",{cx:"7",cy:"7",r:"6",fill:a?"currentColor":"none",stroke:"currentColor","stroke-width":"1.4"})),a?l.appendChild(N("path",{class:"gb-tc-receipt__tick",d:"M4.2 7.2l1.9 1.9 3.7-4",fill:"none","stroke-width":"1.6","stroke-linecap":"round","stroke-linejoin":"round"})):t>0&&l.appendChild(N("path",{d:"M7 7 L7 1 A6 6 0 "+(r>Math.PI?1:0)+" 1 "+(7+6*Math.sin(r)).toFixed(2)+" "+(7-6*Math.cos(r)).toFixed(2)+" Z",fill:"currentColor"})),i("span",{class:C("gb-tc-receipt",a&&"gb-tc-receipt--all"),role:"img","aria-label":e.label,title:e.label},l)}function ke(e){var t={ArrowRight:1,ArrowLeft:-1}[e.key],n=[].slice.call(e.currentTarget.querySelectorAll("button:not([disabled]), summary, a[href]")).filter(function(l){return l.offsetParent!==null}),a=n.indexOf(document.activeElement);if(!(a<0)){var r=t?n[(a+t+n.length)%n.length]:e.key==="Home"?n[0]:e.key==="End"?n[n.length-1]:null;r&&(e.preventDefault(),r.focus())}}function we(e){var t=_(e.labels),n=e.author||t.someone,a=e.reactions||[],r=e.editor!=null,l=!!(e.picking&&e.onReact),o=null,u=null,p=!1,d=function(){var m=e.time;return U(m)&&p?m.cloneNode(!0):(p=!0,m)},f=function(){return C("gb-tc-msg",e.grouped&&"gb-tc-msg--grouped",e.mentionsMe&&"gb-tc-msg--mention",e.highlight&&"gb-tc-msg--highlight",e.sending&&"gb-tc-msg--sending",e.failed&&"gb-tc-msg--failed",l&&"gb-tc-msg--active",r&&"gb-tc-msg--editing",e.className)},s=i("li",{id:e.id,class:f(),"data-msg-id":e.messageId,tabindex:"-1"},e.grouped?i("time",{class:"gb-tc-msg__hover-time",datetime:e.dateTime},d()):e.avatar!=null?e.avatar:T(n,e.avatarSrc,32,"gb-tc-msg__av")),c=i("div",{class:"gb-tc-msg__main"});e.replyTo&&c.appendChild(b(i("button",{type:"button",class:"gb-tc-quote","aria-busy":e.replyTo.busy||void 0},[i("span",{class:"gb-tc-quote__who"},e.replyTo.author||t.someone),i("span",{class:"gb-tc-quote__text"},e.replyTo.excerpt)]),e.replyTo.onOpen)),c.appendChild(e.grouped?i("span",{class:"gb-tc-sr"},[n,", ",d(),": "]):i("div",{class:"gb-tc-msg__who"},[i("span",{class:"gb-tc-msg__name"},n),e.badges,i("time",{class:"gb-tc-msg__time",datetime:e.dateTime},d())])),r?c.appendChild(i("div",{class:"gb-tc-msg__editor"},e.editor)):(e.body!=null||e.edited||e.receipt)&&c.appendChild(i("div",{class:"gb-tc-msg__body"},[e.body,e.edited?i("span",{class:"gb-tc-msg__edited"},t.edited):null,e.receipt])),e.status&&c.appendChild(i("p",{class:"gb-tc-msg__status",role:e.failed?"alert":void 0},e.status)),e.attachments&&c.appendChild(i("div",{class:"gb-tc-msg__files"},e.attachments)),e.extra&&c.appendChild(i("div",{class:"gb-tc-msg__extra"},e.extra));var h=function(m,S){e.onPickingChange&&e.onPickingChange(m,S)},v=a.length?ie({items:a,onToggle:e.onReact,canReact:!!e.onReact,target:t.messageFrom(n),labels:t,open:e.reactionsPicking,onOpenChange:function(m){h("reactions",m)}}):null,g=e.thread,w=null;g&&g.count>0&&(w=b(i("button",{type:"button",class:"gb-tc-threadprev","aria-label":t.openThread(g.count,g.last==null?"":g.last)},[g.repliers&&g.repliers.length?i("span",{class:"gb-tc-threadprev__faces","aria-hidden":"true"},g.repliers.slice(0,3).map(function(m){return T(m.name,m.src,24)})):null,i("span",{class:"gb-tc-threadprev__count"},t.replies(g.count)),g.last?i("span",{class:"gb-tc-threadprev__last"},g.last):null]),g.onOpen)),O(c,[v,w]),s.appendChild(c);var D=function(m,S){l=m,s.className=f(),u&&u.setAttribute("aria-expanded",String(l)),l?(o=L({items:a,labels:t,onPick:function(Ie){D(!1,!0),e.onReact(Ie),u.focus()},onClose:function(){D(!1,!0),u.focus()}}),c.insertBefore(o,v||w),S&&o.firstChild.focus()):o&&(o.remove(),o=null),S&&h("bar",l)};if(!r&&!e.sending&&(e.onReact||e.onReply||e.onOpenThread||e.moreActions)){var E=i("div",{class:"gb-tc-acts",role:"toolbar","aria-label":t.actionsFor(n)});e.onReact&&(W.forEach(function(m){var S=J(a,m);E.appendChild(b(i("button",{type:"button",class:"gb-tc-act gb-tc-act--quick","aria-pressed":String(S),"aria-label":t.react(m,n,S)},m),function(){e.onReact(m)}))}),u=i("button",{type:"button",class:"gb-tc-act","aria-expanded":String(l),"aria-label":t.moreReactions(n),title:t.addReaction},k("reaction",18)),E.appendChild(b(u,function(){D(!l,!0)}))),e.onReply&&E.appendChild(b(i("button",{type:"button",class:"gb-tc-act","aria-label":t.replyTo(n),title:t.reply},k("reply",18)),e.onReply)),e.onOpenThread&&E.appendChild(b(i("button",{type:"button",class:"gb-tc-act","aria-label":t.replyInThreadTo(n),title:t.replyInThread},k("thread",18)),e.onOpenThread)),O(E,e.moreActions),E.addEventListener("keydown",ke),s.appendChild(E)}return l&&D(!0,!1),s}function Ce(e,t){return i("li",{class:"gb-tc-day"},t?i("time",{class:"gb-tc-day__label",datetime:t},e):i("span",{class:"gb-tc-day__label"},e))}function Ee(e){var t=_(e);return i("li",{class:"gb-tc-new"},i("span",{class:"gb-tc-new__label",role:"separator","aria-label":t.newMessages},t.newMessages))}function Se(e){return e=e||{},ce(b(i("button",{type:"button",class:"gb-tc-jump"},k("chevronsDown",20)),e.onJump),e)}function ce(e,t){t=t||{};var n=_(t.labels),a=t.count===void 0?0:t.count,r=e.querySelector(".gb-tc-jump__n");return t.visible===void 0||t.visible?e.removeAttribute("hidden"):e.setAttribute("hidden",""),e.setAttribute("aria-label",a?n.jumpNew(a):n.jump),a?(r||(r=e.appendChild(i("span",{class:"gb-tc-jump__n","aria-hidden":"true"}))),r.textContent=a>99?"99+":String(a),e):(r&&r.remove(),e)}var Re={channel:"hash",private:"lock",dm:"user"},se={online:"gb-tc-presence gb-tc-presence--online",away:"gb-tc-presence gb-tc-presence--away",offline:"gb-tc-presence gb-tc-presence--offline"};function oe(e){var t=_(e.labels),n=e.kind===void 0?"channel":e.kind,a=e.unread===void 0?0:e.unread,r=e.mentions===void 0?0:e.mentions,l=[e.name,n==="private"?t.privateChannel:n==="dm"?t.directMessage:null,r?t.mentioningYou(r):null,a?t.unread(a):null].filter(Boolean).join(", "),o=[i("span",{class:"gb-tc-channel__glyph","aria-hidden":"true"},[n==="dm"&&e.avatar?T(e.avatar.name==null?e.name:e.avatar.name,e.avatar.src,24,"gb-tc-channel__av"):k(Re[n],16),n==="dm"&&e.online!==void 0?i("span",{class:se[e.online?"online":"offline"]}):null]),i("span",{class:"gb-tc-channel__name"},e.name),r?i("span",{class:"gb-tc-badge gb-tc-badge--mention","aria-hidden":"true"},"@"+r):null,a?i("span",{class:"gb-tc-badge","aria-hidden":"true"},a):null],u=C("gb-tc-channel",a>0&&"gb-tc-channel--unread");return i("li",null,b(e.href!==void 0?i("a",{class:u,href:e.href,"aria-current":e.active?"page":void 0,"aria-label":l},o):i("button",{type:"button",class:u,"aria-current":e.active?"true":void 0,"aria-label":l},o),e.onOpen))}function ue(e,t,n,a){var r=(e.id==null?"gb-tc-s"+ ++q:e.id)+"-h";return i("div",{class:t[0],role:"group","aria-labelledby":r},[i("h3",{class:t[1],id:r},n),i("ul",{class:t[2]},(e.items||[]).map(function(l){return l&&!U(l)?a(l):l}))])}function Me(e){return ue(e,["gb-tc-rail__section","gb-tc-rail__heading","gb-tc-rail__list"],e.label,oe)}function Te(e){return ue(e,["gb-tc-people__section","gb-tc-people__heading","gb-tc-people__list"],[e.label,e.count!==void 0?" \u2014 "+e.count:null],de)}function de(e){var t=_(e.labels),n=[i("span",{class:"gb-tc-person__av"},[e.avatar!=null?e.avatar:T(e.name,e.src,32),e.presence?i("span",{class:se[e.presence]},i("span",{class:"gb-tc-sr"},t[e.presence])):null]),i("span",{class:"gb-tc-person__text"},[i("span",{class:"gb-tc-person__name"},e.name),e.subtitle?i("span",{class:"gb-tc-person__sub"},e.subtitle):null]),e.role?i("span",{class:"gb-tc-person__role"},e.role):null],a=C("gb-tc-person",e.presence==="offline"&&"gb-tc-person--offline");return i("li",null,b(e.href!==void 0?i("a",{class:a,href:e.href,title:e.name},n):e.onSelect?i("button",{type:"button",class:a,title:e.name},n):i("div",{class:a,title:e.name},n),e.onSelect))}var K=function(e){return e instanceof Date?e:new Date(e)},pe={};function G(e,t){var n=K(e),a,r,l,o;if(t){if(a=pe[t],a===void 0){try{a=new Intl.DateTimeFormat("en-US",{timeZone:t,year:"numeric",month:"numeric",day:"numeric"})}catch{a=null}pe[t]=a}if(a&&!isNaN(n.getTime())){for(r={},l=a.formatToParts(n),o=0;o<l.length;o++)l[o].type!=="literal"&&(r[l[o].type]=Number(l[o].value));return[r.year,r.month,r.day]}}return[n.getFullYear(),n.getMonth()+1,n.getDate()]}function j(e,t){var n=G(e,t);return n[0]+"-"+n[1]+"-"+n[2]}function xe(e,t){var n=G(e,t),a=function(r){return(r<10?"0":"")+r};return n[0]+"-"+a(n[1])+"-"+a(n[2])}function Ae(e,t,n){t=t===void 0?new Date:t;var a=j(e,n),r=G(t,n),l;return a===r[0]+"-"+r[1]+"-"+r[2]?"Today":(l=new Date(Date.UTC(r[0],r[1]-1,r[2]-1)),a===l.getUTCFullYear()+"-"+(l.getUTCMonth()+1)+"-"+l.getUTCDate()?"Yesterday":null)}function je(e,t){t=t||{};var n=t.groupWithinMs==null?5*60*1e3:t.groupWithinMs,a=-1,r=[],l,o=t.timeZone;if(t.isUnread){for(l=0;l<e.length;l++)if(t.isUnread(e[l])&&(t.meId==null||e[l].authorId!==t.meId)){a=l;break}}return e.forEach(function(u,p){var d=p>0?e[p-1]:void 0,f=K(u.at),s=!d||j(d.at,o)!==j(f,o);s&&r.push({kind:"day",key:j(f,o),date:f}),p===a&&r.push({kind:"new"}),r.push({kind:"message",message:u,grouped:!!(d&&!s&&p!==a&&u.authorId!=null&&d.authorId===u.authorId&&u.replyToId==null&&f.getTime()-K(d.at).getTime()<n)})}),r}P.teamChat={message:we,readReceipt:_e,daySeparator:Ce,newMessagesLine:Ee,jumpToLatest:Se,updateJump:ce,channelSection:Me,channelItem:oe,peopleSection:Te,personRow:de,reactions:ie,reactionPicker:L,emojiButton:ye,avatar:function(e){return T(e.name,e.src,e.size,e.className)},icon:k,rows:je,dayKey:j,dayISO:xe,dayWord:Ae,LABELS:I,initialsOf:z,avatarTone:V,isReactionEmoji:Q,reactionWords:A,searchReactions:$,reactionLabel:ee,frequentReactions:ne,QUICK_REACTIONS:W,SUGGESTED_REACTIONS:Y,REACTION_GROUPS:R};function fe(){!P.openModal&&y.console&&document.querySelector('script[src*="kit-plain"]')&&y.console.error("@gemboss/ui team-chat-plain.js: load it after kit-plain.js (kit-plain.js defines nothing when gembossUI exists)")}y.document&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",fe,{once:!0}):fe())})(typeof globalThis<"u"?globalThis:this);
|
package/src/team-chat.tsx
CHANGED
|
@@ -24,15 +24,17 @@ import "./team-chat.css";
|
|
|
24
24
|
import React, { useEffect, useId, useLayoutEffect, useRef, useState } from "react";
|
|
25
25
|
import { Icon } from "./icons";
|
|
26
26
|
import { Avatar } from "./portal";
|
|
27
|
-
import { ReactionPicker, Reactions, rememberRecent } from "./reactions";
|
|
27
|
+
import { REACTION_LABELS, ReactionPicker, Reactions, rememberRecent, type ReactionLabels } from "./reactions";
|
|
28
28
|
import { QUICK_REACTIONS, type Reaction } from "./reactions-data";
|
|
29
29
|
|
|
30
30
|
const cx = (...c: Array<string | false | null | undefined>) => c.filter(Boolean).join(" ");
|
|
31
31
|
const useIsoLayoutEffect = typeof window === "undefined" ? useEffect : useLayoutEffect;
|
|
32
32
|
|
|
33
33
|
// ── Words ──────────────────────────────────────────────────────────────────────────────────────────────────────────
|
|
34
|
-
/** Every word the components write themselves. Pass `labels` (any subset) to translate.
|
|
35
|
-
|
|
34
|
+
/** Every word the components write themselves. Pass `labels` (any subset) to translate. The reactions' and their picker's
|
|
35
|
+
* words (`ReactionLabels`: searchEmoji, noEmojiMatches, frequentlyUsed, groupName…) are here too: a message and the
|
|
36
|
+
* composer pass their `labels` on to the `Reactions` and the `ReactionPicker` they draw. */
|
|
37
|
+
export type TeamChatLabels = ReactionLabels & {
|
|
36
38
|
channels: string;
|
|
37
39
|
conversation: string;
|
|
38
40
|
back: string;
|
|
@@ -48,6 +50,8 @@ export type TeamChatLabels = {
|
|
|
48
50
|
actionsFor: (author: string) => string;
|
|
49
51
|
react: (emoji: string, author: string, mine: boolean) => string;
|
|
50
52
|
moreReactions: (author: string) => string;
|
|
53
|
+
/** What a message's reaction row reacts to, for its "Add reaction" (`addReactionTo`): "the message from Linh". */
|
|
54
|
+
messageFrom: (author: string) => string;
|
|
51
55
|
reply: string;
|
|
52
56
|
replyTo: (author: string) => string;
|
|
53
57
|
replyInThread: string;
|
|
@@ -71,6 +75,7 @@ export type TeamChatLabels = {
|
|
|
71
75
|
};
|
|
72
76
|
|
|
73
77
|
export const TEAM_CHAT_LABELS: TeamChatLabels = {
|
|
78
|
+
...REACTION_LABELS,
|
|
74
79
|
channels: "Channels",
|
|
75
80
|
conversation: "Conversation",
|
|
76
81
|
back: "Back to channels",
|
|
@@ -86,6 +91,7 @@ export const TEAM_CHAT_LABELS: TeamChatLabels = {
|
|
|
86
91
|
actionsFor: (a) => `Actions for the message from ${a}`,
|
|
87
92
|
react: (e, a, mine) => `${mine ? "Remove" : "Add"} ${e} on the message from ${a}`,
|
|
88
93
|
moreReactions: (a) => `More reactions for the message from ${a}`,
|
|
94
|
+
messageFrom: (a) => `the message from ${a}`,
|
|
89
95
|
reply: "Reply",
|
|
90
96
|
replyTo: (a) => `Reply to the message from ${a}`,
|
|
91
97
|
replyInThread: "Reply in thread",
|
|
@@ -536,11 +542,11 @@ export function Message(props: MessageProps) {
|
|
|
536
542
|
{attachments ? <div className="gb-tc-msg__files">{attachments}</div> : null}
|
|
537
543
|
{extra ? <div className="gb-tc-msg__extra">{extra}</div> : null}
|
|
538
544
|
{picking && onReact ? (
|
|
539
|
-
<ReactionPicker items={reactions}
|
|
545
|
+
<ReactionPicker items={reactions} labels={t}
|
|
540
546
|
onPick={(e) => { setPicking(false); onReact(e); reactBtn.current?.focus(); }}
|
|
541
547
|
onClose={() => { setPicking(false); reactBtn.current?.focus(); }} />
|
|
542
548
|
) : null}
|
|
543
|
-
{reactions.length ? <Reactions items={reactions} onToggle={onReact} canReact={Boolean(onReact)} target={
|
|
549
|
+
{reactions.length ? <Reactions items={reactions} onToggle={onReact} canReact={Boolean(onReact)} target={t.messageFrom(who)} labels={t} /> : null}
|
|
544
550
|
{thread && thread.count > 0 ? (
|
|
545
551
|
<button type="button" className="gb-tc-threadprev" aria-label={t.openThread(thread.count, thread.last ?? "")} onClick={thread.onOpen}>
|
|
546
552
|
{thread.repliers?.length ? (
|
|
@@ -559,7 +565,7 @@ export function Message(props: MessageProps) {
|
|
|
559
565
|
<button key={e} type="button" className="gb-tc-act gb-tc-act--quick" aria-pressed={mine(e)} aria-label={t.react(e, who, mine(e))} onClick={() => onReact(e)}>{e}</button>
|
|
560
566
|
)) : null}
|
|
561
567
|
{onReact ? (
|
|
562
|
-
<button ref={reactBtn} type="button" className="gb-tc-act" aria-expanded={picking} aria-label={t.moreReactions(who)} title=
|
|
568
|
+
<button ref={reactBtn} type="button" className="gb-tc-act" aria-expanded={picking} aria-label={t.moreReactions(who)} title={t.addReaction} onClick={() => setPicking((p) => !p)}>
|
|
563
569
|
<Icon name="reaction" size={18} />
|
|
564
570
|
</button>
|
|
565
571
|
) : null}
|
|
@@ -754,7 +760,7 @@ export function Composer({ onSend, value, defaultValue = "", onValueChange, plac
|
|
|
754
760
|
<Icon name="send" />
|
|
755
761
|
</button>
|
|
756
762
|
{emoji && emojiOpen ? (
|
|
757
|
-
<ReactionPicker id={popId} className="gb-tc-composer__emoji-pop" label={t.pickEmoji} initialFocus={emojiFocus}
|
|
763
|
+
<ReactionPicker id={popId} className="gb-tc-composer__emoji-pop" label={t.pickEmoji} initialFocus={emojiFocus} labels={t}
|
|
758
764
|
onPick={pickEmoji} onClose={() => { setEmojiOpen(false); backToField(); }} />
|
|
759
765
|
) : null}
|
|
760
766
|
</div>
|