Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions .github/workflows/set-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,3 +69,12 @@ jobs:
- name: The gates' summary
if: always()
run: cat "$RUNNER_TEMP/gates/gates.json" 2>/dev/null || echo "no summary, a gate stopped the run"
# A gate that stops the run leaves only its own log; print the tail of
# every log so the failing check is named in the run, not only locally.
- name: The gates' logs when a gate failed
if: failure()
run: |
for f in "$RUNNER_TEMP"/gates/logs/*.log; do
[ -f "$f" ] || continue
echo "== $f"; tail -n 80 "$f"
done
17 changes: 17 additions & 0 deletions package/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,23 @@
The set `editor`, by its npm version `@simai-studio/editor`; component
versions in brackets.

## Unreleased

- `sf-editor` 1.2.4: over SIMAI Framework `ui-7fb26d395af2` a segmented
track folds into its dropdown when its labels do not fit (sf-segmented
1.6.0, C47). The heading level row keeps H1–H3 as a track at 1440:
«More» is a compact button (⋯) that opens the editor's menu with H4–H6,
and shows the chosen deeper level (H5) when there is one, instead of a
dropdown field whose label and chevron took the track's room.
- The probes follow the pair: a card title is 14 on a phone (C34, C89); the
accent section's roles are read outside the bg-primary place, whose own
primary and on-primary are its ink and fill (C42 (4)); the parity probe
measures the control a person sees when the level track is folded.
- `sf-editor` 1.2.5: the editor's menu (the block's ⋯, the heading level's
H4–H6) is drawn only while open (`sf-menu-context` with `popup`); before,
a closed menu that had entries stayed drawn at the window's bottom.
- Built over SIMAI Framework `ui-7fb26d395af2` (ui-source `8c13bf45aeca`).

## 1.1.1 — 2026-11-09

- `sf-editor` 1.2.3: over SIMAI Framework `ui-b4a77681f0a7` the 1/3 control
Expand Down
7 changes: 4 additions & 3 deletions package/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,10 @@ ui-source at the revision `framework.lock.json` pins (from git, never a
working tree), with this folder's `src/` and `tests/` laid over it. A file
here may not replace a ui-source file.

The pin is `a29cc9989beb`, the source of the released pair
`ui-b4a77681f0a7` (core.runtime 1.47.0), whose 1/3 control is 28 on a
desktop (C27); `ui-cb287da78ab1` was the first that carries the shadow
The pin is `8c13bf45aeca`, the source of the released pair
`ui-7fb26d395af2`, whose segmented track folds into its dropdown when its
labels do not fit (C47); `ui-b4a77681f0a7` was the first whose 1/3 control
is 28 on a desktop (C27), `ui-cb287da78ab1` was the first that carries the shadow
places (C20), `ui-d6f01121baca` was the first that names `sf-segmented`, the
ghost look and the C16 surface and state roles the editor reads; `ui-0c23f6a0af12` was the first whose Composition render takes
`options.embedded`, `ui-1e5ec795a1ce` the first whose name registry
Expand Down
4 changes: 2 additions & 2 deletions package/framework.lock.json
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
{
"schema": "simai.framework.product-package-source-lock",
"schema_version": 1,
"summary": "The ui-source revision the set editor is built and tested against: the overlay is ui-source at this revision with this folder's src/, tests/ and docs/ laid over it, and ui-builder's package build builds the same (standards simai.component-set 1.0.0 and simai.component-package 1.1.1). It is the source of the released SIMAI Framework pair ui-b4a77681f0a7 (simai/ui contracts/releases/ui-b4a77681f0a7.lock.json, build_inputs.source). The same commit is framework.source_revision in set.json.",
"summary": "The ui-source revision the set editor is built and tested against: the overlay is ui-source at this revision with this folder's src/, tests/ and docs/ laid over it, and ui-builder's package build builds the same (standards simai.component-set 1.0.0 and simai.component-package 1.1.1). It is the source of the released SIMAI Framework pair ui-7fb26d395af2 (simai/ui contracts/releases/ui-7fb26d395af2.lock.json, build_inputs.source). The same commit is framework.source_revision in set.json.",
"package": "editor",
"source": {
"repository": "simai/ui-source",
"revision": "a29cc9989bebace9a98c235b074ce23998ad39c6"
"revision": "8c13bf45aecaae2c31188b729ef4765fc91bffae"
}
}
2 changes: 1 addition & 1 deletion package/set.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
},
"framework": {
"core_runtime": ">=1.43.0",
"source_revision": "a29cc9989bebace9a98c235b074ce23998ad39c6"
"source_revision": "8c13bf45aecaae2c31188b729ef4765fc91bffae"
},
"requires_sets": [],
"families": [
Expand Down
4 changes: 3 additions & 1 deletion package/src/smart/editor/component.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"$comment": "The source of sf-editor's element plumbing (core/js/element-manifest.js); standard simai.smart-component 1.4, vocabulary 1.1.5. Part B of the owner's one-block-editor decision of 2026-11-03 (ui-control control/ui-editor/UNIFIED-BLOCK-EDITOR.md, control/decisions/2026-11-03-one-editor-part-a.md), on the Part A contracts of SIMAI Framework pair ui-a2ca21f06e0c. Written by hand in the 1.4 form on the shape of sf-editor-content; x-decisions says how each point was decided.",
"id": "smart.editor",
"tag": "sf-editor",
"version": "1.2.3",
"version": "1.2.5",
"kind": "leaf",
"family": "editor",
"settings": {
Expand Down Expand Up @@ -460,6 +460,8 @@
"storage: none. Every change is a change event with the whole Document; site blocks go out in block-save.",
"version 1.2.1 (2026-11-08): a patch (accessibility). The canvas draws the page Document with Composition render options.embedded (SIMAI Framework pair ui-0c23f6a0af12, ui-source #60), so the page's layout.page and a main region become <div data-sf-composition-landmark=\"main\"> inside the editor's own page instead of a second, nested main (axe landmark-main-is-top-level, landmark-no-duplicate-main). The canvas still counts that div as the page's main landmark, so around such a page it stays an unnamed group and the page's landmarks stay top level, as before. toHTML, the HTML a site prints, keeps the landmarks. A pair before it ignores the option. Settings, values and events are unchanged.",
"version 1.2.2 (2026-11-09): a patch (names). The editor writes the names of SIMAI Framework pair ui-d6f01121baca (core.runtime 1.42.0) instead of their dated aliases (removed 2027-01-01): sf-segmented with appearance track for sf-button-group with appearance segmented (relation cl-segmented, uses smart.segmented), appearance ghost for link on sf-button, and the C16 roles --sf-surface-page, --sf-surface-area, --sf-on-surface-container-variant, --sf-surface-state-hover, --sf-primary-state-select and --sf-shadow-card for --sf-surface-0, --sf-surface-1, --sf-on-surface-container--variant, --sf-surface-transparent-hover, --sf-primary-transparent-select and --sf-elevation-1--shadow. The drawing is the same. C20 (ui-source feat/c20-shadows, core.runtime 1.43.0, the pair after ui-d6f01121baca): the four floating panels (help, the floating block toolbar, the catalogue, the lock note) stand on the overlay place, --sf-surface-popup, --sf-shadow-overlay and --sf-on-surface-popup-variant, for --sf-elevation-2--surface, --sf-elevation-2--shadow and --sf-on-elevation-2--variant; the page sheet takes --sf-shadow-raised for --sf-shadow-card. Those former names stay until 2027-01-01; the overlay is the owner-approved C20 look. The set needs core.runtime 1.43.0 or newer. Over the pair ui-cb287da78ab1 (core.runtime 1.45.0, standard §4.4) the reference names one args object per action, whose schema is the action's `with` fields (ui-source 9d2eeb8e); the actions are the runtime's (elementFromManifest actions), which take that object and the fields in order alike. Settings, values and events are unchanged.",
"version 1.2.5 (2026-11-13): a patch. The editor's one menu (the block's ⋯ and the heading level's deeper steps) is an sf-menu-context with popup: it is drawn only while it is open through openFor(). Without popup a menu is drawn in place, so once it had entries it stayed drawn at the window's bottom after it closed. Settings, values and events are unchanged.",
"version 1.2.4 (2026-11-12): a patch (look, sf-segmented 1.6.0 C47). Over SIMAI Framework pair ui-7fb26d395af2 a segmented track folds into its dropdown when its labels do not fit the room it is given. The heading level row (H1–H3 and «More» at 1440) no longer had the room with «More» as a field: its label and chevron took 96 of the 258. «More» is now a compact button that opens the editor's menu with the deeper steps (H4–H6); when one of them is chosen the button shows it (tonal, «H5»), so the level stays in sight. The track keeps the rest of the row and stays a track at 1440. The value it writes and the events are unchanged.",
"version 1.2.3 (2026-11-09): a patch (sizes, C27 with C18/C19, DEV option A). Over SIMAI Framework pair ui-b4a77681f0a7 (core.runtime 1.47.0) the 1/3 control is 28 on a desktop (C27); the gutter's + and grip keep following --sf-ui-1/3--control-height (28 on a desktop, the phone step on a phone), with no local 24. The gutter stands in the canvas's start inset (--sf-editor-gutter-room grows with the ladder), never at a negative offset, so it stays inside the window at 1280, 1440 and 390; at 1440 the sheet is 788, the canvas beside the larger room. The gap between the gutter and its block is the gutter's end margin (--sf-editor-gutter-gap, --sf-space-1/4) read by the placement, for the 4 the script held. Settings, values and events are unchanged."
],
"x-rule": {
Expand Down
21 changes: 21 additions & 0 deletions package/src/smart/editor/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -1469,11 +1469,32 @@ class SfEditor extends EditorElement {
menu.openFor?.(button, {side: "block-end", align: "start"});
}

/** The deeper steps of a field (a heading's H4–H6) in the editor's menu, under their button. */
openStepsMenu(field, steps, anchor) {
const menu = this.querySelector(".sf-editor-menu");
if (!menu) return;
const current = String(field.value ?? "");
menu.entries = steps.map((step) => ({id: `step:${step.value}`, text: step.label, current: step.value === current}));
menu.dataset.for = this.model.selected ?? "";
this.stepsField = field;
const button = anchor?.querySelector?.(":scope > button, button") ?? anchor;
menu.openFor?.(button, {side: "block-end", align: "end"});
}

onMenuSelect(event) {
event.stopPropagation();
const menu = event.currentTarget;
const id = menu.dataset.for;
const action = event.detail?.entry?.id ?? event.detail?.id;
if (typeof action === "string" && action.startsWith("step:")) {
const field = this.stepsField;
this.stepsField = null;
if (!field || id !== this.model.selected) return;
const result = this.model.setParam(id, field.key, action.slice(5), this.breakpoint);
if (!result.ok) this.say(this.sfWord(`refused-${result.reason}`));
this.redraw();
return;
}
queueMicrotask(() => {
// The menu closes: the keys (⌘Z first) act where a person works, on the canvas.
if (action !== "build") this.canvasElement?.focus({preventScroll: true});
Expand Down
4 changes: 2 additions & 2 deletions package/src/smart/editor/js/templates/default.css
Original file line number Diff line number Diff line change
Expand Up @@ -1026,9 +1026,9 @@
min-inline-size: 0;
}

.sf-editor-switch-row > sf-dropdown > * {
/* «More» keeps its own width: the track takes the rest of the row. */
.sf-editor-switch-row > .sf-editor-more-steps > * {
flex: none;
inline-size: calc(var(--sf-ui-1\/2--control-height) * 3);
}


Expand Down
16 changes: 11 additions & 5 deletions package/src/smart/editor/js/templates/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ export function renderEditorTemplate(component) {
${component.lockNote ? html`<div class="sf-editor-lock-note" role="status"
style=${`inset-block-start:${component.lockNote.y + 12}px;inset-inline-start:${component.lockNote.x}px`}>
<sf-icon icon="lock" size="1/3"></sf-icon><span>${component.lockNote.text}</span></div>` : nothing}
<sf-menu-context class="sf-editor-menu" size="1/2" @sf-menu-context-select=${(event) => component.onMenuSelect(event)}></sf-menu-context>
<sf-menu-context class="sf-editor-menu" size="1/2" popup @sf-menu-context-select=${(event) => component.onMenuSelect(event)}></sf-menu-context>
<sf-editor-inline></sf-editor-inline>
${component.outputView ? outputModal(component, w) : nothing}
</div>
Expand Down Expand Up @@ -597,10 +597,16 @@ function fieldRow(component, field, w) {
const shown = all.slice(0, 3);
const rest = all.slice(3);
const inRest = rest.some((item) => item.value === String(value));
control = segmentedSwitch(field, shown, inRest ? "" : value, component, rest.length ? html`
<sf-dropdown class="sf-editor-more-steps" size="1/2" aria-label=${w("more-steps", {name: field.label})} placeholder=${w("more")}
.options=${rest.map((item) => ({value: item.value, text: item.label}))} .value=${inRest ? String(value) : ""}
@change=${(event) => component.onField(event, field)}></sf-dropdown>` : nothing);
// «More» is a compact button with the editor's menu, not a field: a field's
// label and chevron took the room the track needs to stay a track (it folds
// into a dropdown when its labels do not fit, sf-segmented 1.6.0). The chosen
// deeper step is the button's text, so the level stays in sight.
const chosen = rest.find((item) => item.value === String(value));
const label = w("more-steps", {name: field.label});
const open = (event) => component.openStepsMenu(field, rest, event.currentTarget);
control = segmentedSwitch(field, shown, inRest ? "" : value, component, !rest.length ? nothing : chosen
? html`<sf-button class="sf-editor-more-steps" size="1/2" appearance="tonal" text=${chosen.label} aria-label=${`${label}: ${chosen.label}`} title=${label} aria-haspopup="menu" @click=${open}></sf-button>`
: html`<sf-button-icon class="sf-editor-more-steps" size="1/2" appearance="ghost" scheme="on-surface-variant" icon="more_horiz" aria-label=${label} title=${w("more")} aria-haspopup="menu" @click=${open}></sf-button-icon>`);
} else if (field.choiceLabels.length && segmented(field)) {
// Alignment draws as the prototype's three icons; the words stay their names.
const icon = field.target === "align" ? ALIGN_ICONS : null;
Expand Down
10 changes: 5 additions & 5 deletions package/src/smart/editor/smart.manifest.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"schema_version": 2,
"id": "smart.editor",
"version": "1.2.3",
"version": "1.2.5",
"title": "Page editor",
"summary": "The one block editor of the SIMAI page: layout and text in one Composition Document, edited by depth. A click on text types, a click beside it chooses the block, Esc goes up and Enter down. One catalogue (Text and Blocks, groups, variants with pictures, search, favourites, recent) serves the + between blocks, / in text and the library; blocks move by the grip with drop lines or Alt+arrows, and a drop beside a block splits it into columns. The parameter panel says where every value comes from (type, theme, variant, block, screen) and sets values per screen; the Data tab binds a block to a host source through the source port. The block builder makes and changes site blocks everywhere; the site template is a separate, explicit edit. Rights and theme come from the host. One undo history; output as JSON, HTML and Markdown.",
"kind": "smart",
Expand Down Expand Up @@ -590,7 +590,7 @@
"source_artifacts": [
{
"path": "src/smart/editor/index.js",
"sha256": "7d10660bb1ae33aff903189c49f31c650a3cbf2089a4d5ff523161efc5763e5b"
"sha256": "cc362bd96b8444a3b572a6130de2a0649bfc94c5f9cb40d75ac7cadff93aa6b8"
},
{
"path": "src/smart/editor/js/model.mjs",
Expand All @@ -606,11 +606,11 @@
},
{
"path": "src/smart/editor/js/templates/default.js",
"sha256": "64e1cd32def3c19789d8a888b7dc7c2ffa33a87bd6b078519a9809c09484e3ae"
"sha256": "54b3216b7043cdedbd56aa96501157441dd8edfb156d59241bcac4839b003cbd"
},
{
"path": "src/smart/editor/js/templates/default.css",
"sha256": "094a0dd7b7a6a091f005a8fbe0ac0f9e5d9e387154609ef0177a739dca7c65c6"
"sha256": "7aa7080cdea1aa8151c583c588019f57fec9f2624eb70e04c5305a0636152161"
},
{
"path": "src/smart/editor/rule.js",
Expand All @@ -622,7 +622,7 @@
},
{
"path": "src/smart/editor/component.json",
"sha256": "c1c85ff233378ae60ccca226539aa522142fdd427e729c628f71e4fbded9b5a4"
"sha256": "d92053ed82913e679943ed92f21e6541d887826bf93057fc0203d279f47291bc"
},
{
"path": "src/smart/editor/lang/en.json",
Expand Down
Loading
Loading