Use same well tested utility to slice and insert its copy for copy
paste. Moved most utilities inside of instance plugin and added more
tests for it.
## Steps for reproduction
1. play with copy paste
Ref https://github.com/webstudio-is/webstudio/issues/2532
Here added a "core" collection component to support iterating over json
arrays.
There is a lot of room for unification of all this logic though would
require building reactive tree abstraction.
Canvas automatically renders stub component for collection to make it
droppable. We can do the same for slot component.
Slot and Fragment eventually will go to "core" components too.
Added json/parameter prop types to embed template to support collection.
Fixed loosing focus while typing in json prop.
## Steps for reproduction
1. Drop collection component
2. play with it
We had db data validation enabled before but it made api requests very
slow. We disabled this validation and seems like there is no need to
enable again.
Also dropped all zod list types of our data because validation was the
only use case.
Here fixed the case when copy pasted form looses state and give errors
on submit.
Immerhin now converted to esm to work in tests.
Added tests for instances copy paste plugin.
The new logic is copy data sources as is if they are bound to copied
instances.
The new computeExpressionsDependencies used to detect if expression
depends on data sources outside of copied instances scope.
Here I removed "rich-text" type from components. Instead "container" can
be edited when has only text or rich text children.
And any time user can drop into editablle container which will wrap all
text and rich text children into "Span" component.
Had to implement position adjustment to consider text children which do
not have representation in navigator tree and canvas dnd.
Span has temporary SpanContainer name to not conflict with existinig
Span for styled text in rich text. Will rename in other PR when remove
no longer necessary components.
Here added two component restrictions to meta.
requiredAncestors prevent inserting components outside of required ones
here restricted ListItem to always be inside of List.
invalidAncestors prevent inserting components inside of invalid ones
here prevented nested buttons
Ref https://github.com/webstudio-is/webstudio-builder/issues/1569
Here we change template in meta to include current component instead of
implicitly creating it.
This way we can provide insert composition of components instead of
single one for example input+label. Or even wrap current component like
label>input.
Another usecase is ability to set local styles and props for current
component.
Note: review with hidden whitespaces
Added `allowedParentComponents: string[]` option to meta which prevents
dropping, inserting or pasting components into wrong parents. For
example ListItem now can be placed only inside of List component.
This will unlock better experience with compound radix components.
Now embed templates can define simplified version of our styles which is
useful for radix components and as AI output.
```
styles: [
{
property: 'backgroundColor',
value: { type: 'keyword', value: 'red' }
}
]
```
Ref https://github.com/webstudio-is/webstudio-builder/pull/1516
Here added new utility "tree template" to describe children in component
meta and generate instances from it while inserting.
Added simple template to form component as example.
InstancesItem is newer type introduced separately for gradual migration.
Not all legacy tree Instance is migrated away so we can finally use
better naming across whole system.
Here a little refactored copy paste instance plugin.
Now we copy all data including slots and tokens though paste write them
as is or do not write at all if already exist.
This let us to not do unnecessary patches for copy paste within project
while still have whole UI pasted in different project.
There is still a problem with pasting styles which always have different
breakpoint ids in each project. We will need to implement merging in
other PR.
One cyclic case I missed. When paste slot into itself as target then
check miss unresolved fragment inside. Here added additional check
before copying and covered with tests.
For slots show only settings panel.
Ref https://github.com/webstudio-is/webstudio-builder/issues/1116
Slot is copy pastable part of the tree which is always in sync. Kinda
like primitive components.
The idea is the following. Slot is copy pasted as any other instance
though its children are preserved as is without cloning with new ids.
This lead to the problem with multiple slot children. While copy paste
they are preserved as is though when add new child to slot, the other
instance of it will not get new child.
To workaround this we add another Fragment component which groups all
children into single one and new children are always reflected in all
slot copies.
## Description
Implements all design changes and accessibility for components add panel
https://user-images.githubusercontent.com/52824/227720011-344b31f8-ce17-4d13-ad4d-2d506ca3bcce.mp4
## Code Review
- [ ] hi @rpominov , I need you to do
- conceptual review (architecture, feature-correctness)
- detailed review (read every line)
- test it on preview
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio-builder/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example`
and the `builder/env-check.js` if mandatory
Here bit less straightfforward as lexical<>instances conversion is not
very straightfforward because lexical represents a few instances with
its formats.
To solve conversion complexity used almost same ancestor traverser as
before but finish once eiditing node is reached.
Pass instance selector for each webstudio-component ot identify selected
and editing instances.
- in many places root check can be replaced with selector.length === 1
- reparent and insert utilities now accept selectors
- findClosestDroppableTarget output end instead of last index and always
fallback to root
Label again started flickering because hovered instance and hovered
outline store changes have delay in between. Solution as before is to
provide all info with outline. Here I just passed both label and
component to get the shape for getInstanceLabel.
Removed react hook from instance hovering and refactored with instance
selectors.
With slots there can be same ids in one tree so we need new way to
address instances. Here I propose the list from target instance to the
root.
Now instead of computing parents by normalized tree (one instance of
slot can have many parents) we just access already computed list from
rendered tree.
This address can be computed when user click in dom which can be
traversed or it can be passed top-down with props.
The main con of this approach is collaboration. Reparanted instances on
by one user makes "selected address" stale. Though we have similar
situation with single id when instance is deleted.
Isolated mode for slots/components will make this problem less
noticable.
We found a bug a bug after release. Any instances changes on the page
erase instances of other pages.
Recently I migrated to normalized instances though didn't have time to
migrate utilities and just added patchInstancesMutable utility to
synchronize changes from denormalized rootInstance to normalized
instances.
Though after merging instances of all pages into single list this
synchronization started to clear instances not found in rootInstance.
To solve this I stopped clearing instances in patchInstancesMutable and
migrate delete instances utility to mutating normalized instances
directly.
Ref https://github.com/webstudio-is/webstudio-designer/issues/696
Previous findClosestNonInlineParent required additional check to handle
drag of root instance or editing non rich text.
Now we can simplify logic because we know exact component type of
matched instance.
Ref https://github.com/webstudio-is/webstudio-designer/issues/696
We no longer need to traverse tree to access parents. Index provide
precomputed map of instance to parent.
## Code Review
- [ ] hi @kof, I need you to do
- conceptual review (architecture, feature-correctness)
- test it on preview
- [ ] hi @istarkov, I need you to do
- detailed review (read every line)
## Before requesting a review
- [ ] made a self-review
- [ ] added inline comments where things may be not obvious (the "why",
not "what")
## Before merging
- [ ] tested locally and on preview environment (preview dev login:
5de6)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio-builder/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env.example`
and the `builder/env-check.js` if mandatory