@gemboss/ui 0.39.0 → 0.40.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 CHANGED
@@ -2,6 +2,240 @@
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.40.0 (20/10/2026)
6
+
7
+ **A list's item edits in a popover** (item management IM1a, Chris 20/10/2026; GemPages 7.5's "Item management" read in its code).
8
+
9
+ Added
10
+ - `RepeaterList` `editIn="popover"`: the list stays one line per row; the row picked shows its controls in a layer under the list
11
+ (top layer, placed by `menu-layer.ts` `placeFloating`, as wide as the list), one row at a time. ✕, Escape (focus back on the
12
+ row) or the row clicked again close it; a click elsewhere does not (a row's controls open pickers and dialogs of their own).
13
+ A list of one row shows it in place, open (nothing to choose between). Without the popover API the row picked opens in
14
+ place. Default stays `inline`.
15
+ - `thumb(index)`: a 20px picture before the row's name (the admin passes the row's first image field).
16
+ - `onActive(index | null)`: the host hears the row picked, to show that item on the canvas.
17
+ - `packages/ui/src/editor-repeater.css`: the popover's placement and header, the picked row's outline, the picture (+220 B gzip,
18
+ 1,096 of its 1,384 B ceiling). The surface is the fleet's `gemboss-popover-surface`.
19
+
20
+ **A phone pays for the topbar once, and the full-screen assistant gets the whole width** (measured on the admin at 390×844,
21
+ 19/10/2026).
22
+
23
+ Fixed
24
+ - `.gemboss-platform-main` at ≤760px: `padding-top` is the 16px gutter (it was 56px). `margin-top: 56px` already clears the fixed
25
+ bar at every width, so a phone had 74px between the bar and a page's title.
26
+ - Full screen at ≤560px: the thread rail (`SessionRail`, one New chat button at that width) sits in the empty left of the
27
+ `.gb-dock-fullchrome` strip, a 44px circle at the strip's 8px/12px inset, instead of a 60px column beside the chat (330 of
28
+ 390px). CSS only: a surface that passes its own New chat through `fullActions` gets no second one. Above 560px nothing moves.
29
+
30
+ **`Switcher`: the nine-dot panel for any list, with illustrated tiles (GemCommunity's groups).**
31
+
32
+ Added
33
+ - `Switcher` (`SwitcherItem`, `SwitcherProps`): the dialog, search, groups, keys and phone sheet of `ServiceSwitcher`, for
34
+ items an app gives (`id`, `name`, `description`, `href`, `group`, `tint`, `badge`). A tile with `media` (`{ src }` an
35
+ image, `{ glyph }` an emoji drawn on its tint) is a card with the picture on top (`gb-svc__tile--media`,
36
+ `gb-svc__media`, 16:9); the groups holding cards lay out in 208px columns, two a row on a phone. `foot` puts the app's
37
+ own actions in the foot. Chris 20/10/2026: GemCommunity's group switcher "kèm hình ảnh minh hoạ, tên và description …
38
+ như các dịch vụ gemboss, gemcapture bấm vào icon lưới 9 chấm".
39
+
40
+ Changed
41
+ - `ServiceSwitcher` is now `Switcher` with the Gem services: the same markup as before (tests pin it).
42
+
43
+ **A competitor page's picture in the chat comes from the GemBoss admin, not from the market archive** (Chris 20/10/2026).
44
+
45
+ Changed
46
+ - `FLEET_IMAGE_HOSTS` (and chat-plain.js's copy) draws `https://admin.gemboss.ai/api/gemboss/market-image/…`, the admin's
47
+ signed picture door, and no longer lists the market archive's own host. GemBoss's tools now hand out admin URLs for
48
+ these pictures; the archive's host in this list put its name in every surface's bundle. A surface that draws the
49
+ archive's own pictures (its own dashboard) passes that host in `imageHosts`. An older answer that still holds an
50
+ archive URL shows the picture as a link, the rule for every host not on the list.
51
+
52
+ **The public site layer: one bar, one lockup size, one set of buttons for every public page** (Chris 20/10/2026: "có gemboss ui
53
+ thì có gemboss website ui"; two lockup sizes, site 18px and app 13.3px). Measured the same day: the logo name 18px on gemboss.ai
54
+ and the docs, 16px on news, 13.3px on the community home; the bar 65 / 57 / 69 / 56px.
55
+
56
+ Added
57
+ - `@gemboss/ui/site.css`, a new entry (1.0 KB gzip): `gb-site-header` (sticky, 64px, the 1132px column), `gb-brand--site` (the
58
+ lockup with an 18px name), `gb-site-nav` / `gb-site-link`, `gb-site-actions`, `gb-site-btn` `--primary` / `--secondary` (40px,
59
+ 36px in the bar, 44px under a finger), and the footer (`gb-site-footer`, `__grid`, `__col`, `__bottom`, `gb-site-wrap`). Values
60
+ are gemboss.ai's own; every colour a token, so the dark palette applies. README "The public site layer".
61
+ It stands alone: with only the tokens and site.css (no core), the site lockup is whole, for plain-HTML pages.
62
+ - `SiteHeader` and `SiteBrand` (`site.tsx`), which bring it. `SiteBrand` draws the same gem as `BrandLockup` and does not import
63
+ brand.tsx, so a public page never carries the ServiceSwitcher.
64
+ - Catalog section "Trang công khai"; `site.test.tsx` (markup, same gem, no rule on :root/html/body, no colour literal) and
65
+ `site-browser.test.tsx` (64px bar, 18px vs 13.3px, 44px controls at 390, no sideways scroll at 1280/390/320).
66
+
67
+ Changed
68
+ - The lockup's gem moved to `brand-gem.tsx` (`BrandGem`), shared by `BrandLockup` and `SiteBrand`. `BrandLockup` renders the
69
+ same markup as before.
70
+
71
+ **A colour not set is not black** (control standard §13b U7, Chris 20/10/2026). An empty colour drew a black swatch beside "Not set",
72
+ so a seller read a colour nobody chose.
73
+
74
+ Changed
75
+ - `ColorControl`: an empty value marks its swatch `data-empty` and opens it on white; `editor.css` draws the slash a picker draws for
76
+ "none" over it (`.gemboss-ei-swatch[data-empty]::-webkit-color-swatch`). A value the swatch cannot show is unchanged (black, off,
77
+ with the reason under it).
78
+ - `packages/ui/weight-budget.json`: `packages/ui/src/editor.css` 8,615 → 8,690 B gzip, Chris's OK on 20/10/2026. This rule is +45 B (8,665 measured); main
79
+ was already at 8,620, over the old ceiling, after two PRs that each passed it alone (#4701, #4648).
80
+
81
+ **The ? beside a label stays a 16px circle inside the page editor.**
82
+
83
+ Fixed
84
+ - `.gemboss-pageedit .gemboss-ec-dock-body`, `.gemboss-page-section-content` and `.gemboss-bundle-look .gemboss-ei-body` set every
85
+ button to 44px; the ? (`.gemboss-ei-help`) is now left out, as the inspector field's own 44px rule already left it out. It drew
86
+ 16x44, an oval beside every label in the page editor's Settings (measured 19/10/2026). Its target is its ring (::after).
87
+
88
+ **The team chat layer: GemCare's channel chat for every surface** (Chris 20/10/2026: bring GemCare's Slack-like channel chat to
89
+ GemCommunity, and make the two inherit the same UI so the next upgrade happens once). GemCare's look and behaviour (origin/main
90
+ 20/10/2026: public/assets/inbox.{html,css,js}) moved into the package; GemCare (plain HTML) and GemCommunity (React) draw the same thing.
91
+
92
+ Added
93
+ - `@gemboss/ui/team-chat.css`, a new entry (3.6 KB gzip, ceiling 4174): the screen (`gb-tc`, rail | conversation | right panel), the
94
+ rail (`gb-tc-rail`, `gb-tc-channel` with a kind glyph, `gb-tc-badge` and `--mention`), the head (`gb-tc-head`, back button, members
95
+ toggle), the list (`gb-tc-log` role=log, `gb-tc-day` sticky, `gb-tc-new`, `gb-tc-jump`), the message (`gb-tc-msg`, `--grouped`,
96
+ `--mention`, `--highlight`, `--sending`, `--failed`, `--active`, `--editing`; `gb-tc-quote`, `gb-tc-threadprev`, `gb-tc-receipt`, the action
97
+ bar `gb-tc-acts`), the composer (`gb-tc-composer`, one box: paperclip, a field that grows, send; "Replying to", files and mention
98
+ picker slots, "Also send to"), the thread panel (`gb-tc-thread`) and the people panel (`gb-tc-people`, sections "Online — n", rows
99
+ with a presence dot and a role chip, a 56px collapsed strip; usable on its own in an app shell's right column). Every colour a
100
+ `--gemboss-*` token (dark applies unchanged); no rule on :root/html/body. Reused, not redrawn: `Avatar` (portal.css), `Reactions`
101
+ (reactions.css), the kit's `ui-btn` / `ui-check`.
102
+ - The screen decides by its OWN width (container queries, not the viewport): > 1100px the right panel is a column (thread 380, people
103
+ 260 / 56); ≤ 1100px a drawer over the conversation with a scrim (the conversation keeps its width); ≤ 760px the channel list OR the
104
+ conversation (`data-view`), a back button, the panel a sheet over the chat. Under a finger every control is 44px; under a mouse the
105
+ rail and the action bar are 32px. The action bar is one tap away under a finger (the row takes focus) instead of a row of 44px
106
+ buttons under every message as in GemCare; the message list's own container query drops the quick reactions where it is narrow.
107
+ - React, props only (`team-chat.tsx`): `TeamChat`, `ChannelRail`, `ChannelSection`, `ChannelItem`, `ChatHeader`, `MessageList`,
108
+ `DaySeparator`, `NewMessagesLine`, `JumpToLatest`, `Message`, `ReadReceipt`, `Composer`, `ThreadPanel`, `PeoplePanel`, `PeopleSection`,
109
+ `PersonRow`; `TEAM_CHAT_LABELS` (every word, `labels` to translate). `TeamChat` holds focus in a drawer (focus in, the rest `inert`,
110
+ Escape / the scrim close it, focus back to the opener). `Composer`: Enter sends, Shift+Enter a new line, an IME composition is never cut.
111
+ - `teamChatRows`, `chatDayKey`, `chatDayWord` (`team-chat-data.ts`, plain TS): GemCare's rules for turns (same author, same day, < 5 min,
112
+ not a reply), day separators and the "New messages" line.
113
+ - Icons `hash`, `lock`, `reply`, `thread`, `paperclip`, `send`, `chevronLeft`, `chevronsDown`, `panelRight`.
114
+ - README "The team chat layer": the plain-HTML markup of every part, held to the React components by `team-chat-contract.test.tsx`.
115
+ Catalog section "Chat đội" (desktop with a thread, dark with people, the 1024 drawer, phone conversation and list, the people
116
+ panel alone). `team-chat.test.tsx` (markup, ARIA, states, the row rules, the stylesheet's rules) and `team-chat-browser.test.tsx`
117
+ (Chromium at 1366 / 1024 / 390 / 320: columns vs drawer, the screen's own width, list or conversation, no sideways scroll, 44px under
118
+ a finger, a tap shows the bar, Enter sends, contrast in light and dark; negative controls without the drawer and the finger blocks).
119
+
120
+ **A colour swatch that cannot show its value says why, under it** (Claude Design: a disabled control says why).
121
+
122
+ Added
123
+ - `swatchWhy(value)` (`@gemboss/ui/editor/swatch`): the reason, or null when the swatch shows the value. A theme token says which
124
+ one ("Theme color: Accent. Type a hex to use your own."), any other value that is not a 6-digit hex says it is kept as written.
125
+
126
+ Changed
127
+ - `ColorControl` draws that reason as a line under the swatch and its box (`.gemboss-ei-color-why`, 12/16 muted) and points the
128
+ swatch at it (`aria-describedby`); the swatch's title is the same sentence. It was a tooltip only, which a finger and the keys
129
+ never reach, and every colour the editors' toolbar picks is a token, so the swatch was grey after each one.
130
+
131
+ **Room between the settings, and one inset for the column** (Chris 20/10/2026: "khoảng cách giữa các dòng settings … dính tịt vào nhau",
132
+ "section settings padding 2 bên lại không đồng bộ với element settings", "chia cụm và các khoảng nghỉ"). Measured on the Canvas at 1280:
133
+ neighbouring fields of the element panel 0px apart (1,831 of 1,831 on the 71 kinds: the panel wraps each setting in a `<div>`, so each
134
+ field was a `:last-child` and lost its 12px); a section's settings 36px in from the column's edges where the element panel's are 16.
135
+
136
+ Changed
137
+ - Inside a collapsible group (`.gemboss-ei-grp`) the gap is the group's, between its items, whatever wraps a field: 12px, 8px under
138
+ the header, none above a hint. A `.gemboss-ei-group` holds its fields bare, and their own 12px applies.
139
+ - `.gemboss-ei-grp`, `.gemboss-ei-group`: 16px above and below (12): a pause between clusters, larger than the one between fields.
140
+ - `.gemboss-settings-body`: fields 12px apart (20), the label 6px above the box (4), as in a group. Docked in the Canvas's column it
141
+ drops its own 16px 20px, so the column's inset is the one: that rule is the Canvas's (admin `funnel-canvas.css`), as this file
142
+ is at its weight ceiling.
143
+
144
+ Removed
145
+ - `.gemboss-ei-group > .gemboss-ei-fld:last-child`: the same as `.gemboss-ei-fld:last-child`.
146
+
147
+ **The editor's frame at the kit's size under a mouse** (Chris 19/10/2026: "những cái button vẫn bị to hơn chuẩn của gemboss ui"). Every
148
+ control of the element panel was already on the standard (measured on all 71 kinds); the frame around it was not. Measured on the Canvas
149
+ at 1280: Publish 33px, 14 / 600, 20px in; Undo, Redo and ⋯ 32 × 36; ← and the panel toggle 30 × 30; the Settings · Chat tabs 38px, 12 / 600.
150
+
151
+ Changed
152
+ - `.gemboss-editor-tb-publish`: 28px (`--ui-btn-h`), 12 / 550 / 16, 12px in, as the kit's button; its caret 8px in. A narrow bar and a
153
+ finger keep their own rules.
154
+ - `.gemboss-pv-device` (the bar's icon buttons), `.gemboss-editor-back`, `.gemboss-editor-chat-toggle`: 28 × 28.
155
+ - `.gemboss-ec-tabs > [role="tab"]`: 28px, 12 / 550 / 16, 12px in (Polaris Tabs); 44px at 767 and below as before.
156
+
157
+ Removed
158
+ - The 36 × 32 box and 44px overlay the theme and page editors' icon buttons wore above 1000px: on 28px boxes 8px apart the overlays
159
+ would cross, and under a mouse the kit asks 28.
160
+
161
+ **A popup opened from a link draws no ring around itself.**
162
+
163
+ Fixed
164
+ - `.ui-modal:focus` has no outline. The panel takes focus on open and is never a Tab stop; Chrome drew its own ring
165
+ around the whole dialog when that focus came from a script with no click before it (every admin settings door, 19/10).
166
+
167
+ **Tabs, row buttons and the trail at Polaris sizes** (control standard U3b).
168
+
169
+ Changed
170
+ - `.gemboss-ei-tab` (an inspector's Settings / Advanced): 12px / 550 on a 16px line, 28px tall (it was 27px / 600).
171
+ - `RepeaterList`: a row's ↑ ↓ duplicate ✕ and its toggle at radius 8 (6); "+ Add item" is the kit's `.ui-btn` at full width (it
172
+ was a dashed box, 13px / 450).
173
+
174
+ **A field's buttons are Polaris buttons, and one touch rule** (control standard U3, research pickers-2026-10-16 §13b).
175
+
176
+ Changed
177
+ - `ChipButton` (Choose, Remove, Select image, Library, Clear, + Add…) is the kit's `.ui-btn`, a Polaris secondary button: 28px,
178
+ 12px / 550, radius 8, 44px under a finger. It was `.gemboss-ei-addchip`, a dashed pill (27px, 11px / 600, radius 999).
179
+ - The inspector's tabs, group heads, swatches and field controls grow to 44px on the kit's rule, `(pointer: coarse), (max-width:
180
+ 47.9975em)`, not on `(pointer: coarse)` alone: at 390px with a mouse the fields were 44px and the heads 20px.
181
+ - The "?" keeps its 16px circle under a finger and is pressed in a 44px ring (it grew into a 44px circle that pushed its label).
182
+
183
+ Removed
184
+ - `.gemboss-ei-addchip`: use `ChipButton` (or `.ui-btn`).
185
+
186
+ **A number box with its unit stays one line inside a field** (fix of U1). The admin's FieldRenderer puts `UnitField` straight
187
+ inside `.gemboss-ei-fld`, and its box is a `<label>`: the field's label rule (`.gemboss-ei-fld>label`, 0,1,1) beat the group's
188
+ `display:flex` (0,1,0), so the box was a block, 42px high with the unit under the value, a 6px label margin and the label's type
189
+ on the value. Measured on the section panel at 1280: 7 of 7 such boxes.
190
+
191
+ Fixed
192
+ - The label rules leave a field group out: `.gemboss-ei-fld>label:where(:not(.gemboss-field))`, same weight as before, in the
193
+ plain rule and the quiet one inside a group.
194
+
195
+ Changed
196
+ - `editor.css` 8.580 → 8.571 B gzip: two rules that repeated a selector (`.gemboss-pagepicker-list`, `.gemboss-platform-main:has(.gemboss-editor)`)
197
+ are one each, and `.gemboss-ei-gh:hover` is gone (it set the colour the header already has).
198
+
199
+ **Type at Polaris sizes in the panel** (control standard U2, research pickers-2026-10-16 §13b). Measured on the element panel at 1280:
200
+ 130 hints at 11px, and 215 "?" buttons drawn in the browser's 13.33px / 400.
201
+
202
+ Changed
203
+ - `.gemboss-ei-hint` 11px → Polaris bodySm **12px / 16px**, 4px under its control (Polaris help text's gap; it was 8).
204
+ - `.gemboss-ei-help` (the "?"): its `font` shorthand ended in `inherit`, which is not valid there, so the whole declaration was
205
+ dropped; now `650 10px/16px var(--gemboss-font-sans)`.
206
+ - `.gemboss-ei-gh-note` (a group header's aside) 10px / 500 → 12px / 450.
207
+ - `.gemboss-settings-field > span` (the section panel's and the page-settings sheet's field labels) 13px / 700, full colour → the
208
+ inspector's quiet label, 13px / 450 in `--gemboss-text-muted`, 4px above its control (it was 6).
209
+
210
+ **The panel's edges line up** (control standard U1, research pickers-2026-10-16 §13b; Chris 19/10/2026: "giờ méo, kích thước chưa
211
+ chuẩn polaris"). Measured on the element panel at 1280 before: 71 rows whose number box stopped short of the panel's right edge
212
+ because the unit sat outside it, swatches 34px beside 32px boxes, group titles 16px right of the labels under them.
213
+
214
+ Added
215
+ - **`UnitField`** (`editor/controls.tsx`): a number box with its unit INSIDE, as Polaris TextField's `suffix`. A
216
+ `label.gemboss-field.gemboss-field--group` around `.gemboss-field__bare` and `.gemboss-field__suffix`, so a click anywhere in the
217
+ box, the unit included, focuses it. Props: every `<input>` prop, plus `unit`, `className` and `style` for the box.
218
+ - `.gemboss-field__suffix` (`gemboss-field.css`): the unit's place in a field group, Polaris secondary text, 6px after the value.
219
+
220
+ Changed
221
+ - `ValueControl`'s box is a `UnitField` (`.gemboss-ei-value-box`, 7em: 91px at 13px, 112px at the phone's 16px), the unit inside.
222
+ - `.gemboss-ei-swatch` 34 → 32px, the height of the box beside it.
223
+ - `InspectorGroup`'s header: the disclosure mark sits at the END of the line, drawn as a chevron (two borders; down open, right
224
+ closed), so the title starts on the labels' edge. The ▾ / ▸ glyph stays in the markup for `editor-plain.js`, hidden.
225
+ - A field group whose text field is disabled is drawn disabled (50%, not-allowed) and does not react to hover; a disabled colour
226
+ swatch beside an editable box does not dim the box.
227
+
228
+ Removed
229
+ - `.gemboss-ei-suffix` (the unit beside the box): use `UnitField`.
230
+
231
+ **The section panel's groups are the inspector's** (control standard §13b U5). The band panel listed each element's options and
232
+ lists in native `<details>` (the browser's triangle, no divider); they are `InspectorGroup`s now.
233
+
234
+ Added
235
+ - `InspectorGroup`'s `attrs`: `data-*` attributes on the group itself (`.gemboss-ei-grp` / the static `section`), so a page that
236
+ finds a group by an attribute needs no wrapper. A wrapper made each group the `:last-child` of its own parent, and the divider
237
+ between groups (`.gemboss-ei-grp:last-child{border-bottom:none}`) never drew.
238
+
5
239
  ## 0.39.0 (19/10/2026)
6
240
 
7
241
  **A field of real pages for the sign-in panel, and an entrance for the screen.** Chris, on admin.gemboss.ai/login: