Skip to content

Add transition prop: CSS shorthand string, web emit, no-op decode elsewhere - #186

Merged
tiensonqin merged 1 commit into
mainfrom
devin/lui-transition
Oct 11, 2026
Merged

tiensonqin merged 1 commit into
mainfrom
devin/lui-transition

Conversation

@tiensonqin

Copy link
Copy Markdown
Collaborator

Summary

Adds a transition prop so the ~45 transition: declarations currently stranded in logseq's resources/css can migrate onto typed LUI props (logseq refactor/lui work). Follows the additive pattern from #185: schema entry → per-kind admission → Lui_protocol validation → ?transition on every admitted Lui_elements constructor → per-host decode.

The value is the CSS shorthand verbatim — "<property> <duration> [<easing>] [<delay>]", comma-separated list allowed:

Lui_elements.box ~transition:"opacity 0.15s ease" [ ... ]
Lui_elements.text ~transition:"background-color 0.15s ease, border-color 0.15s ease" [ ... ]
  • Admission mirrors the hover-*/state-channel table: every kind except root/tooltip/modal surfaces, plus restrictive kbd via its kindProperties entry — 64 constructors get ?transition.
  • Validation (Lui_protocol.transition_supported, mirrored in Rust/Swift/Kotlin): each segment needs a CSS <ident> property + 1–2 <time> tokens (s/ms, bare 0 allowed); remaining tokens must be ident or ident(args) (paren-aware tokenizing so cubic-bezier(0.4, 0, 0.2, 1) commas don't split segments). Garbage rejects via the existing Invalid_argument path.
  • Web: emits the string literally as transition: — the wire syntax is CSS shorthand.
  • gpui: no CSS transition engine and no lerp path for hover/pressed merges, so the value is validated at the wire boundary (P::Transition arm + transition_supported in validation.rs) but intentionally never applied — documented in style.rs.
  • apple/android: same admission + validation mirrors, never rendered (state changes apply instantly).
  • Regenerated artifacts: lui_protocol.mli, lui_wire_schema.ml, LUIWireSchema.swift, LuiWireSchema.kt, wire_schema.rs, protocol_rules.rs, lui_json_view.ml (?transition auto-decodes from v_str).
  • tools/gen_json_view.py: added flex_wrap/list_marker named arg types to the existing no-decoder skip set — the generator was un-runnable since Add CSS-adjacent capability props: sticky, display values, font-family, text-decoration, list-style, flex-wrap, hover fg/border #185 added them; required for regeneration. Both stay view-model-invisible, same as display.

Not included: a transform prop — element transforms need real work on gpui (element vs paint transform), so it stays out per the no-transform-engine rule.

Verified: dune build, dune runtest (107 tests, +transition assertions), node --test tooling/test/*.mjs (8/8), cargo check -p lui-core -p lui-gpui.

Link to Devin session: https://app.devin.ai/sessions/d768c1bf809c48a7a5dffaf7b1370941
Open in Devin Desktop: https://app.devin.ai/desktop/session/d768c1bf809c48a7a5dffaf7b1370941?variant=devin
Requested by: @tiensonqin

…ewhere

A new `transition` prop carries the CSS transition shorthand verbatim
(`"<property> <duration> [<easing>] [<delay>]"`, comma-separated list
allowed). Admission follows the hover-*/state-channel table: every
non-root, non-tooltip, non-modal kind, plus the restrictive kbd via its
kindProperties entry.

- schema/components.json: Transition / transition entry + kbd prop
- Lui_protocol: property variant, admission arms, and a minimal
  transition_supported validator (property ident + 1-2 <time> tokens,
  remaining tokens ident or ident(args); parens keep easing arg lists
  inside tokens and stop comma splits). Garbage is rejected through the
  existing invalid-argument path.
- Lui_ui/Lui_elements: setter + ?transition on the 64 admitted
  constructors; apply_universal applies it like the other universals.
- Web: emits literal `transition: <value>` (syntax IS CSS shorthand).
- gpui: no CSS transitions and no lerp path for hover/pressed merges, so
  the value is validated at the wire boundary (Rust mirror of the OCaml
  validator) and intentionally never applied — documented in style.rs.
- apple/android: same admission + validation mirrors, never rendered.
- Regenerated: protocol.mli, wire_schema.ml, LUIWireSchema.swift,
  LuiWireSchema.kt, wire_schema.rs, protocol_rules.rs, lui_json_view.ml.
- tools/gen_json_view.py: also skip the flex_wrap and list_marker named
  arg types (no JSON-view decoders) so the file is regenerable again.
- Tests: transition admission + shorthand acceptance/rejection cases.

Not in scope: a `transform` prop — element transforms need real work on
gpui (element vs paint transform), skipped per the no-transform-engine
rule.
@devin-ai-integration

Copy link
Copy Markdown
Contributor

I'll fix CI failures and address comments from users with write access. I'll skip comments containing "(aside)".

  • Disable automatic comment, CI, and merge conflict monitoring

@tiensonqin
tiensonqin merged commit 5a880c2 into main Oct 11, 2026
7 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant