@gemboss/ui 0.34.3 → 0.35.2
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 +69 -0
- package/catalog/editor.html +1 -1
- package/catalog/index.html +244 -119
- package/gemboss-ui.css +3 -3
- package/package.json +3 -1
- package/parts/components.css +2 -2
- package/parts/core.css +1 -1
- package/parts/shell.css +1 -1
- package/src/chat.css +1 -1
- package/src/collections.css +1 -1
- package/src/dialog.tsx +79 -21
- package/src/editor.css +1 -1
- package/src/index.ts +2 -0
- package/src/kit-plain.css +1 -1
- package/src/settings-dialog.css +1 -0
- package/src/settings-dialog.tsx +159 -0
- package/src/sheet.css +1 -0
- package/src/sheet.tsx +28 -0
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.35.2 (12/10/2026)
|
|
6
|
+
|
|
7
|
+
**A folded index table's title is a 24px target.** visual-gate on partner-radar's list pages (/companies, /invites, /posts,
|
|
8
|
+
12/10/2026) flagged `a.ui-table__title` at 20px at every narrow width (a link in a list is 24px at least, WCAG 2.5.8).
|
|
9
|
+
|
|
10
|
+
Fixed
|
|
11
|
+
- Folded (container ≤ 768px): `a.ui-table__title` gets `padding-block: 2px; margin-block: -2px` and is drawn above the line
|
|
12
|
+
under it (`position: relative; z-index: 1`). Its box is 24px, every line of the row stays where it was, and a press on the
|
|
13
|
+
2px it reaches into the next line is the link's. A press anywhere else on the row still opens it through the script
|
|
14
|
+
(kit-plain.js / IndexTable), not an overlay, so text in the row stays selectable. Unfolded (a table) nothing changes.
|
|
15
|
+
|
|
16
|
+
Also in this release: 0.35.1 (#4086), merged and not published until now.
|
|
17
|
+
|
|
18
|
+
## 0.35.1 (12/10/2026)
|
|
19
|
+
|
|
20
|
+
**The left column has one inset.** An editor's left column (`.gemboss-ec`) padded its parts differently: the chat 16px,
|
|
21
|
+
the Configure body and the tab row 12px, a PanelHeader 12px (Chris 12/10/2026, the funnel Studio: "cần consistency về
|
|
22
|
+
padding"). They now all read `--gemboss-ec-inset`, declared on `.gemboss-ec`: 16px, 12px at ≤640px (the chat's phone
|
|
23
|
+
value). Outside a `.gemboss-ec` each rule falls back to the value it had.
|
|
24
|
+
|
|
25
|
+
Changed
|
|
26
|
+
- `.gemboss-ec`: declares `--gemboss-ec-inset` in `chat.css`, on the chat's root class. A surface with `editor.css` and no
|
|
27
|
+
`chat.css` keeps each rule's fallback, the value it had.
|
|
28
|
+
- Every chat whose root is `.gemboss-ec`, not only an editor's (the admin's Assistant page, the operator chat): at ≤640px
|
|
29
|
+
the head's sides go from 16px to 12px, in line with its message list, which was 12px there already.
|
|
30
|
+
- `.gemboss-ec-head`, `.gemboss-ec-scroll` (chat.css), `.gemboss-ec-tabs` (sides), `.gemboss-ec-dock-body` (editor.css) read it.
|
|
31
|
+
- `.gemboss-ec > .gemboss-ei-head`: a PanelHeader in the column keeps the column's inset at its sides; floating, 12px.
|
|
32
|
+
- A docked inspector in the column (`.gemboss-ec .gemboss-ei--docked`): its head, tabs and pane read it too.
|
|
33
|
+
|
|
34
|
+
## 0.35.0 (12/10/2026)
|
|
35
|
+
|
|
36
|
+
**Sheet: a record opened beside its list.** The kit popup docked to the right edge (Chris 12/10/2026, partner-radar: "bấm
|
|
37
|
+
vào people của từng người nên trượt ra side popup"). README "Sheet".
|
|
38
|
+
|
|
39
|
+
**SettingsDialog: settings as one popup.** The admin's settings shape (rail of sections with a search box, the section on
|
|
40
|
+
the right), moved here from the admin's module CSS so GemWatcher and partner-radar stop copying it (Chris 12/10/2026,
|
|
41
|
+
"settings thì bật popup theo chuẩn của gemboss ui"). README "SettingsDialog".
|
|
42
|
+
|
|
43
|
+
Added
|
|
44
|
+
- `Sheet` (client), `sheet.css` (its own entry `./sheet.css`, loaded by the component; `gemboss-ui.css` unchanged).
|
|
45
|
+
- `SettingsDialog` (client), `settings-dialog.css` (its own entry `./settings-dialog.css`, loaded by the component).
|
|
46
|
+
- Catalog sections "Ngăn trượt cạnh phải" and "Hộp cài đặt".
|
|
47
|
+
- `packages/ui/weight-budget.json`: ceilings for `packages/ui/src/sheet.css` and `packages/ui/src/settings-dialog.css`.
|
|
48
|
+
|
|
49
|
+
Changed
|
|
50
|
+
- `Sheet` is `Dialog` with `ui-sheet` on it: one render tree and one hook (`useModalDialog`, dialog.tsx).
|
|
51
|
+
- `Dialog`: optional `subtitle` (its own `aria-describedby`, not part of the name) and `actions` (beside the title,
|
|
52
|
+
before ✕), the kit head's `.ui-modal__subtitle` / `.ui-modal__actions`; `focusPanel` (the popup takes focus on open).
|
|
53
|
+
Without them it renders exactly as before.
|
|
54
|
+
- Every modal kit popup holds the page behind still: `html:has(dialog.ui-modal:modal) { overflow: hidden }` (kit-plain.css),
|
|
55
|
+
one rule instead of one per component; `:modal`, so a dialog drawn open with the attribute (the catalog) does not lock.
|
|
56
|
+
- `useModalDialog` takes `returnFocusTo`: a selector focused on close when the opener left the screen (`<body>` counts as
|
|
57
|
+
gone).
|
|
58
|
+
- `Dialog`: a click on the backdrop closes it only when the press started there too (a text selection dragged out of the
|
|
59
|
+
panel and released over the scrim closed it); focus goes back to the opener without scrolling the page, also when the
|
|
60
|
+
popup is unmounted while open; `onClose` is read from a ref, so the listener is attached once.
|
|
61
|
+
|
|
5
62
|
## 0.34.3 (11/10/2026)
|
|
6
63
|
|
|
7
64
|
Fixed
|
package/README.md
CHANGED
|
@@ -1134,6 +1134,75 @@ A large popup can keep its subtitle and its own actions in the kit head instead
|
|
|
1134
1134
|
`gemboss-ui.css` and on the admin's sheets alone. `UI_MODAL_ROOT=<a 0.7.1 tree>` runs it against the old CSS, where
|
|
1135
1135
|
it is red.
|
|
1136
1136
|
|
|
1137
|
+
## Sheet (0.35.0): a record opened beside its list
|
|
1138
|
+
|
|
1139
|
+
Chris 12/10/2026 on partner-radar: a click on a person in a list should slide their profile out at the side, not
|
|
1140
|
+
leave the list. The package had a centred popup (`Dialog`), a command popup (`SearchDialog`), menus, the editor's
|
|
1141
|
+
`EditorDrawer` (the right shape, but no Escape, focus left behind, and it brings `editor.css`) and the assistant's side
|
|
1142
|
+
panel (the assistant's). `Sheet` is the kit popup docked to the right edge:
|
|
1143
|
+
|
|
1144
|
+
```tsx
|
|
1145
|
+
import { Sheet } from "@gemboss/ui";
|
|
1146
|
+
|
|
1147
|
+
<Sheet open={!!person} onClose={() => setPerson(null)} title={person?.name} subtitle="CRO agency · Plus"
|
|
1148
|
+
actions={person && <a className="ui-btn" href={`/partners/${person.id}`}>Open full profile</a>}>
|
|
1149
|
+
…the record's summary…
|
|
1150
|
+
</Sheet>
|
|
1151
|
+
```
|
|
1152
|
+
|
|
1153
|
+
It stays mounted while closed, so read the record with `?.` (or render it only while there is one: unmounted while
|
|
1154
|
+
open, focus still goes back to the row). `onClose` runs on every close, `open` turning false included, as `Dialog`'s
|
|
1155
|
+
does: keep it idempotent. A route that draws the sheet (Next's intercepting route) leaves `open` true and goes back in
|
|
1156
|
+
`onClose`; one that derives `open` from the URL must not navigate again in `onClose`.
|
|
1157
|
+
|
|
1158
|
+
| | |
|
|
1159
|
+
| --- | --- |
|
|
1160
|
+
| Markup | `<dialog class="ui-modal ui-sheet">` with the popup's own `ui-modal__head` (title, `__subtitle`, `__actions`, ✕), `__body`, `__foot` |
|
|
1161
|
+
| Behaviour | It is `Dialog` with `ui-sheet` on it (one render tree, one hook, `useModalDialog`): Escape, ✕ and a click on the backdrop close it (a press that STARTED on the backdrop: a selection dragged out of the panel does not), `onClose` hears each once, the page behind is inert and holds still (`html:has(dialog.ui-modal:modal) { overflow: hidden }` in kit-plain.css, one rule for every modal kit popup), the panel itself takes focus on open (not the head's first link), focus goes back to the row. The subtitle describes the popup (`aria-describedby`); the name is the title alone |
|
|
1162
|
+
| Size | the full height; 560 wide, `wide` 760, from 768px up; the whole screen below that; head, ✕ and buttons at the popup's density (README "Popup density") |
|
|
1163
|
+
| Motion | slides in from the right (200 ms); none under `prefers-reduced-motion` |
|
|
1164
|
+
| Scrim | `rgba(0,0,0,.3)`, lighter than the centred popup's `.5`: the list stays readable beside it |
|
|
1165
|
+
| CSS | `sheet.css`, its own entry, loaded by the component. Every selector is `dialog.ui-modal.ui-sheet…` ((0,2,1), so it holds whatever order the sheets load in) or the page lock. It lays itself out (no padding, border-box, a column whose body scrolls), so it works on a surface that loads `ui.css` alone; the head's subtitle and actions are styled by `kit-plain.css`. A plain-HTML surface links `@gemboss/ui/sheet.css` beside `gemboss-ui.css` and opens the markup with `showModal()`, never the `open` attribute (no scrim, page not inert) |
|
|
1166
|
+
|
|
1167
|
+
The body scrolls under a head that stays, and scrolling past its end does not scroll the list (`overscroll-behavior:
|
|
1168
|
+
contain`). `packages/ui/src/sheet-browser.test.tsx` measures it in Chromium; its negative control runs the same probe
|
|
1169
|
+
without `sheet.css` and finds the centred popup. Catalog section "Ngăn trượt cạnh phải".
|
|
1170
|
+
|
|
1171
|
+
## SettingsDialog (0.35.0): settings as one popup
|
|
1172
|
+
|
|
1173
|
+
The admin's Settings (apps/admin `SettingsDialog`): one popup over the app, the sections in a rail on the left with a
|
|
1174
|
+
search box, the chosen section on the right, the close button in the corner; under 861px the rail becomes one scrolling
|
|
1175
|
+
strip above the section and the popup is the whole screen. GemWatcher copied the admin's module CSS (#400) and
|
|
1176
|
+
partner-radar needed it too (Chris 12/10/2026, "settings thì bật popup theo chuẩn của gemboss ui"), so it lives here.
|
|
1177
|
+
|
|
1178
|
+
```tsx
|
|
1179
|
+
import { Icon, SettingsDialog } from "@gemboss/ui";
|
|
1180
|
+
|
|
1181
|
+
<SettingsDialog open={open} onClose={() => setOpen(false)} activeId={id} onSelect={setId}
|
|
1182
|
+
sections={[
|
|
1183
|
+
{ id: "general", group: "Workspace", title: "General", description: "Name and time zone.", icon: <Icon name="settings" size={16} /> },
|
|
1184
|
+
{ id: "members", group: "Account", title: "Members", href: "/settings/members", icon: <Icon name="users" size={16} /> },
|
|
1185
|
+
]}
|
|
1186
|
+
linkAs={Link} footLinks={[{ href: "/ops", title: "Jobs", icon: <Icon name="activity" size={16} /> }]}>
|
|
1187
|
+
{pane}
|
|
1188
|
+
</SettingsDialog>
|
|
1189
|
+
```
|
|
1190
|
+
|
|
1191
|
+
| | |
|
|
1192
|
+
| --- | --- |
|
|
1193
|
+
| What it owns | the shell only: the rail (search, groups, sections, foot links), the pane head (the active section's `title` and `description`, which is also the popup's name), the scrolling body, the corner ✕ |
|
|
1194
|
+
| What the surface owns | the sections and the active one's content (`children`): no settings, data or fetching here |
|
|
1195
|
+
| A section | a button (`onSelect(id)`, required by the types when any section has no `href`) or, with `href`, a link drawn with `linkAs` (a surface whose sections are routes; the active one carries `aria-current="page"`). An `activeId` that matches no section highlights and names nothing (no silent first section) |
|
|
1196
|
+
| Content | `children` in a measure: `measure="default"` 900px, `"form"` 662px (one column of fields), `"full"` the pane. A new section opens at its top |
|
|
1197
|
+
| Foot links | pages outside settings; following one closes the popup |
|
|
1198
|
+
| Search | matches title, description, `keywords` and group; "No setting matches “…”." when nothing does (`noMatch`) |
|
|
1199
|
+
| Behaviour | `<dialog class="ui-modal ui-modal--lg ui-settings">` opened through `useModalDialog` like `Dialog` and `Sheet`: Escape (one press, also with words in the search box), a press that starts on the backdrop, the inert page that holds still (`position: fixed`: `ui-modal--lg` alone made it absolute and jumped a scrolled page to the top), the popup takes focus on open and ✕ is last in the order; focus goes back to the opener, or to `returnFocusTo` (default `[data-settings-trigger]`) when the opener left the screen (a menu item). Each opening starts with an empty search |
|
|
1200
|
+
| Size | the workspace popup: `--gem-popup-workspace-w / -max / -h` (the admin's tokens; 96vw, 1680px, the height less 48 without them); 280px rail; sections 44px; under 861px the whole screen, the rail a strip |
|
|
1201
|
+
| CSS | `settings-dialog.css`, its own entry, loaded by the component. The search box is the kit's field made of parts (`gemboss-field gemboss-field--group` + `gemboss-field__bare`), the ✕ the kit popup's (`ui-modal__close`) |
|
|
1202
|
+
|
|
1203
|
+
`packages/ui/src/settings-dialog-browser.test.tsx` measures it in Chromium; its negative control runs without
|
|
1204
|
+
`settings-dialog.css` and finds no 280px rail. Catalog section "Hộp cài đặt".
|
|
1205
|
+
|
|
1137
1206
|
## Resizable panels
|
|
1138
1207
|
|
|
1139
1208
|
`ui-resizer` is the seam a person drags between two panels; `ui-resizing` on `<body>` is the drag in
|
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.35.2 · 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";
|