The "Global build" section shows off how easy it can be the best.
More complicated stuff with modules might be harder especially when dealing with NPM build stuff, but it's generally pretty nice.
* Declarative: here is a UI that I designed ahead of time. I've set up these controls with these hooks. Your logic then plugs into my UI independent of it's design. (When myBtn is clicked, it fires MyCode::MyBtn() in your code).
* Inperative: here is my main.c. In my main(), I call a function createWindow and then createButton with various parameters (size, text caption, styling, etc) that returns a handle to the widget/window. I give a callback to my widgets. When that button is clicked, the callback is fired. I can call a function called destroyWidget with that handle and erase it.
Or, to simplify solely to definitions: in declarative UI, I create (or declare) the UI ahead of time and hook it into my logic. In imperative UI, the UI is rendered as requested (an imperative). The definitions are directly orthogonal to imperative vs declarative programming, in general.
As to "reactive", this is an independent descriptor that simply means that the UI adjusts to it's environment. It's usually used in the context of Web or mobile devices, since an Android app that appeared the same on Phones and Tablets would get a subpar experience for users on one or the other.
Given an imperative UI and a small amount of time (depending on the surface area of the API) I can create a declarative interface to it.
I cannot do the reverse given a declarative UI.
My observation of declarative UIs is that, sooner or later, due to necessity, they tend towards the inclusion of imperative elements ("If we are running as Super-User, then $FOO must be a button, else it must be a link to a page requesting Super-User privileges").
At the end the "declarative" UI is declarative for only the most trivial usages. Any non-trivial usage includes hacks or workarounds to implement conditional elements, loops (for collections of elements) and subcomponent specialisation (for element reuse).
if condition then ConditionalWidget1 else ConditionalWidget2
Where this if-statement is embedded in a declared UI/widget tree. That's hardly a hack in my opinion.
There are similar ways of building a dynamic list of widgets declaratively which don't feel hacky at all. For example, look at ListView.builder[0] in Flutter. You provide an array and a template function of how each element in the array should look and then you have your dynamic list of widgets. (Of course more complicated use cases require more complicated code, but it's still not hacky and fits well with the larger sstem.)
[0] https://docs.flutter.dev/cookbook/lists/long-lists
I might be misunderstanding your definition of declarative vs imperative but I don't think this way of building UIs is hacky in any sense.
AIUI, declarative is listing what you want, while imperative is listing the steps to get what you want. Naturally, I feel that extending a declaration with conditionals or looping constructs make that not-declarative anymore.
That's because, I feel, a conditional is a sequence of steps, not a declaration.
Hence I regard (perhaps incorrectly) that declarative syntax with support for conditionals is "hacky".
(The XAML way of expressing conditionals and loops does feel hacky to me since you need the code and markup to communicate with each other instead of expressing directly in code.)
Edit:
Here is a well-considered blog post from one of the Uno Platform contributors about UI-as-code vs markup if any are interested. https://platform.uno/blog/markup-vs-code-for-ui-angled-brack...
Because GP is criticizing Win32-style imperative UI code... and this is exactly what Delphi saves you from.
From a webdev point of view I love Vue...but it is a slow hard way to build UIs compared to Visual Basic, Delphi, or Swing.
MFC had a mix of generated code and handwritten code. Writing MFC code by hand was hell, and using a graphical IDE was nowhere as convenient as Visual Basic or anything by Borland.