3742 Commits
Author SHA1 Message Date
Bogdan Chadkin 274c8d84c2 experimental: adapt tailwind to webstudio breakpoints (#5244)
Ref https://github.com/webstudio-is/webstudio/issues/2651

There is an edge case which will prevent from converting breakpoints.
When there is no base breakpoint there is no value to fill with inverted
space. Though it should be very rare usecase. Need to test how often it
will create new breakpoints.
2025-06-09 15:32:52 +03:00
Bogdan Chadkin aea46aba6c feat: insert tag commands (#5248)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Added commands for all tags satisfying current tree



https://github.com/user-attachments/assets/6e7e29c4-1a9a-452d-a967-448e216e4703
2025-06-08 14:53:39 +03:00
Oleg Isonen 1e1edf7a65 feat: Built with webstudio badge check on publish (#5246)
## Description

<img width="351" alt="image"
src="https://github.com/user-attachments/assets/1afca5f0-da0f-4726-a29a-cd9ed2403967"
/>

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, 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:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-06-08 11:35:24 +02:00
Bogdan Chadkin 14e6ced695 feat: add replace with element command (#5242)
Ref https://github.com/webstudio-is/webstudio/issues/3632

This can be a nice addition and a way to migrate legacy components.


https://github.com/user-attachments/assets/8354d4bd-e60b-4cf3-b662-5c8e974d9537
2025-06-04 11:56:05 +03:00
Bogdan Chadkin 24180a2edb perf: improve instance selection performance (#5240)
We have html element mutations in a few places and each can add ~250ms
of repaint time on large projects. Here I got rid of it in two places

1. Collapsed logic enforced document height to preserve scroll position.
Instead I created an absolutely positioned div which enforced scroll
where collapsed elements are reset.
2. Scroll into view logic defined position absolute on scroll container.
Though it's not necessary on html element so just ignored it.
2025-06-01 14:42:10 +03:00
Bogdan Chadkin 68621fa363 feat: support <a> download attribute in preview (#5238)
Ref https://github.com/webstudio-is/webstudio/issues/5197

We prevented all link clicks. Though seems like download is safe to
proceed when url is relative (asset).
2025-05-28 22:16:23 +03:00
Bogdan Chadkin 04949cbc88 feat: wrap text with span element when droppping instances into it (#5237)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Here changed insertion logic to wrap rich text with span element instead
of Text component when drop into it. This is the last place which
creates legacy components.

Refactored tests with jsx to make them more readable.
2025-05-28 12:11:10 +03:00
Bogdan Chadkin 3d064f1b20 fix: paste markdown (#5235)
Async in html paste broke markdown because await was missing in onPaste.
2025-05-28 00:24:46 +03:00
Bogdan Chadkin 8b1063425c fix: prevent checkbox and radio changing in design mode (#5233)
User can click on checkboxes and radio inputs on canvas and make them
checked. We don't want this in design mode.
2025-05-26 18:51:43 +03:00
Bogdan Chadkin 57ea5da3d2 feat: download image when paste html with it (#5232)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now images will be downloaded when paste it in html to make them
accessible within project even when original one is no longer responds.



https://github.com/user-attachments/assets/2591e981-3ec1-40f8-bf50-19332c322332
2025-05-26 12:18:03 +03:00
Bogdan Chadkin 3506fe881f feat: add element component (#5231)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Here unflagged element component in components panel and html paste.

Additionally

- migrate link template to html element
- added :local-link state to links which is replaced with
[aria-current=page] when css is generated, sadly not yet supported in
any browser
- migrated many templates from legacy components to html elements
- put tailwind paste behind flag
2025-05-25 14:26:40 +03:00
Bogdan Chadkin 4dfdf50380 feat: migrate forms components to html elements (#5230)
Ref https://github.com/webstudio-is/webstudio/issues/3632

This is big one. So I switched to html elements whole forms section in
components. Though here I introduced some deviation from specification

**Textarea**

Initial value is represented as text content
```html
<textarea>content</textarea>
````

Though it is trickier to manage text content as state and all frameworks
rely on value property of textarea dom interface.

**Select**

Similar story. There is no value attribute and state is represented by
selected boolean attribute on options

```html
<select>
  <option value="value1" selected></option>
  <option value="value2"></option>
</select>
```

We replace selected attribute on option with value attribute on selected
when paste.

So basically all form elements are using "value" and "checked"
attributes which can be easily mapped to html and all frameworks.
2025-05-24 15:11:49 +03:00
Bogdan Chadkin e9e0fb7503 feat: add wrap in element command (#5228)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Here "Wrap in Element" is replacing "Wrap in Box" as more general
option.
2025-05-24 13:43:12 +03:00
Bogdan Chadkin de61cffde6 experimental: paste tailwind (#5217)
Ref https://github.com/webstudio-is/webstudio/issues/2651

Added "Paste Html With Tailwind Classes" command.

For now only tailwind 3 is supported.
Also fixed a few issues with css parser.


<img width="547" alt="Screenshot 2025-05-18 at 00 38 01"
src="https://github.com/user-attachments/assets/470b63e0-9b17-4769-8a65-679b90d73a89"
/>
2025-05-23 13:19:04 +03:00
Bogdan Chadkin 8b60ff7988 feat: infer states from tags in style panel (#5229)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now states are always inferred from tags. User action states work for
all tags.

<img width="233" alt="Screenshot 2025-05-22 at 19 27 18"
src="https://github.com/user-attachments/assets/f0dc6a07-8a01-4878-950e-61b6e489da7a"
/>
2025-05-22 21:16:40 +03:00
Bogdan Chadkin c630054c74 feat: use html elements for typography (#5226)
Html elements can completely replace legacy typography components. Here
replace component templates with element templates as part of sdk.

- moved content block to general section
- moved separator into typography section
- moved code text into typography section and used regular `<code>`
element for it
- made "Text Content" setting expandable
- fixed dragging templates onto canvas.

<img width="475" alt="Screenshot 2025-05-21 at 11 27 27"
src="https://github.com/user-attachments/assets/ab53c5ec-e51f-498d-b01b-cc7f2eb20c2d"
/>
<img width="515" alt="Screenshot 2025-05-21 at 11 27 20"
src="https://github.com/user-attachments/assets/0f560c26-7e51-4025-a487-6f7e4e3f43e3"
/>
2025-05-21 15:26:05 +03:00
Bogdan Chadkin 88c467c72a fix: make all radix components uncontrolled (#5227)
Here improved handling radix states by making all components
uncontrolled yet still synchronizing external state with local one.
2025-05-21 14:20:40 +03:00
Bogdan Chadkin 0c9b138bba feat: support GitHub flavored markdown paste (#5225)
Markdown paste now generate html elements. This unlocks us supporting
more features:

**strikethrough**

`~~text~~` -> <del>text</del>

**tables**

```
| Header 1   | Header 2   |
|------------|------------|
| Cell 1.1   | Cell 1.2   |
| Cell 2.1   | Cell 2.2   |
```

*autolinks*

```
The link is https://github.com
```

is converted to

```html
<p>This link is <a href="https://github.com">https://github.com</a></p>
```
<img width="559" alt="Screenshot 2025-05-20 at 16 44 53"
src="https://github.com/user-attachments/assets/48508140-9791-47f6-b1c1-3b2946dd5583"
/>

<img width="514" alt="image"
src="https://github.com/user-attachments/assets/dc19e67a-0067-458f-bf3c-64d9b73d02e3"
/>
2025-05-21 01:50:00 +03:00
Bogdan Chadkin fa875ab5c1 feat: use body element on new pages (#5222)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now new project and new page will have body element in the root instead
of body component.

<img width="422" alt="Screenshot 2025-05-20 at 00 15 37"
src="https://github.com/user-attachments/assets/aee568c5-f0e4-40f5-a5a3-e94fc765505d"
/>
2025-05-20 12:24:27 +03:00
Bogdan Chadkin e35de86421 experimental: add icons to html elements (#5219)
Ref https://github.com/webstudio-is/webstudio/issues/3632

<img width="281" alt="Screenshot 2025-05-18 at 18 37 16"
src="https://github.com/user-attachments/assets/0b95b674-c9fa-4f5d-b79d-b1ce6023dba8"
/>
2025-05-18 20:46:45 +03:00
Bogdan Chadkin 90aa42422d experimental: support html elements in content block (#5216)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now content block is relying on instances tags instead of component
names. Tested all cases. Should work smoothly.

Also dialog title now have placeholders inferred from tag as well
<img width="1025" alt="image"
src="https://github.com/user-attachments/assets/4c7817fb-cf68-4d61-a672-213b1e8d1cc7"
/>
2025-05-18 00:29:50 +03:00
Bogdan Chadkin 646c5b38e7 fix: normalize html attributes only when not defined by component (#5215)
Proper fix for https://github.com/webstudio-is/webstudio/pull/5211

Now props meta are available in component generator and can be used to
figure if prop is defined by component or comes from html attributes.
Added same logic in canvas and component generator.

Also got rid from no longer necessary registeredComponentPropsMetas
store since all props are described by component meta.
2025-05-17 10:11:56 +03:00
Bogdan Chadkin 0eea205bfc refactor: merge base and animation props with component metas (#5214)
Related https://github.com/webstudio-is/webstudio/pull/5211
2025-05-16 23:31:06 +03:00
Bogdan Chadkin 72345fb1fb refactor: merge radix props with component metas (#5213)
Related https://github.com/webstudio-is/webstudio/pull/5211

We moved html attributes away from props metas and have very little
actual props left in meta. It is safe to merge with component meta to
simplify access in both builder and CLI.

CLI size increase is not very significant

```diff
- 241.92kB
+ 256.64kB
```
2025-05-16 17:55:07 +03:00
Bogdan Chadkin d372aa386b experimental: customize initial attributes per tag (#5209)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now different tags can have own initial attributes. Here added initial
attributes to `<a>` and `<form>` which will be replaced with remix
components on publish. Also overriden href, download and target types
for links.

<img width="246" alt="Screenshot 2025-05-15 at 16 21 00"
src="https://github.com/user-attachments/assets/112c3c94-0c87-4fa5-936b-4def5cc4ee12"
/>
2025-05-16 14:59:10 +03:00
Bogdan Chadkin a44530b068 experimental: adapt tag control to html content model (#5208)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Here improved tag control to allow updating with tag satisfying content
model.

For example when ul has li it can only be changed to ol and menu. li
inside ul cannot be changed with anything.

Also switch to combobox when there is more than 10 satisfying tags.



https://github.com/user-attachments/assets/ad42bba7-9be1-4f50-9b1a-6f6cda52f3e5
2025-05-14 14:12:48 +03:00
Bogdan Chadkin 28e61f49bd experimental: add matching tag when insert element component (#5204)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now element does not provide default tag and instead builder will try to
find tag matching its parent.

This way we can insert element, give it "ul" tag
and then insert another element into it which will match only "li"


https://github.com/user-attachments/assets/3ea87624-9524-4f2e-91b2-d658d16d7a1b
2025-05-13 12:46:40 +04:00
Bogdan Chadkin a04af45fa3 experimental: support element component in rich text (#5203)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Now when element rich text component is detected all children like bold,
italic, link etc are created with element component.

Old rich text components are still using legacy rich text content
components.

<img width="571" alt="Screenshot 2025-05-12 at 12 47 43"
src="https://github.com/user-attachments/assets/82b1a36e-6efb-40c0-b77c-668a66da6724"
/>
2025-05-12 22:08:26 +04:00
Oleg Isonen 7f50fbe85c fix: Rewrite overflow clip and hidden description (#5201)
## Description

 Rewrite overflow clip and hidden description and move it to css-data

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, 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:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-05-11 17:16:53 +02:00
Bogdan Chadkin 535d87d391 experimental: allow pasting svg as html embed (for now) (#5200)
Now icons are added as HtmlEmbed component when paste html. This is
essential for tailwind paste which use a lot of icons.

<img width="342" alt="image"
src="https://github.com/user-attachments/assets/06bbe633-e2ae-4929-99c5-91040cda9472"
/>
<img width="431" alt="image"
src="https://github.com/user-attachments/assets/8c7e1b5c-42b4-4d6f-8039-5918175bad7e"
/>


```html
    <div
      style="display: flex; border: 1px solid #ccc; border-radius: 5px; overflow: hidden;"
    >
      <button
        style="background-color: #f8f8f8; border: none; padding: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center; border-right: 1px solid #ccc; font-family: sans-serif; font-size: 12px;"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          style="margin-right: 5px;"
        >
          <line x1="3" y1="12" x2="21" y2="12"></line>
          <line x1="3" y1="6" x2="21" y2="6"></line>
          <line x1="3" y1="18" x2="21" y2="18"></line>
        </svg>
        <span>Menu</span>
      </button>
      <button
        style="background-color: #f8f8f8; border: none; padding: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center; border-right: 1px solid #ccc; font-family: sans-serif; font-size: 12px;"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          style="margin-right: 5px;"
        >
          <circle cx="12" cy="12" r="10"></circle>
          <line x1="12" y1="8" x2="12" y2="16"></line>
          <line x1="8" y1="12" x2="16" y2="12"></line>
        </svg>
        <span>Add</span>
      </button>
      <button
        style="background-color: #f8f8f8; border: none; padding: 10px; cursor: pointer; display: flex; align-items: center; justify-content: center; font-family: sans-serif; font-size: 12px;"
      >
        <svg
          xmlns="http://www.w3.org/2000/svg"
          width="24"
          height="24"
          viewBox="0 0 24 24"
          fill="none"
          stroke="currentColor"
          stroke-width="2"
          stroke-linecap="round"
          stroke-linejoin="round"
          style="margin-right: 5px;"
        >
          <path d="M18 6L6 18"></path>
          <path d="M6 6L18 18"></path>
        </svg>
        <span>Close</span>
      </button>
    </div>
```
2025-05-11 16:34:02 +04:00
Oleg Isonen 7f77a04f67 feat: Use destructive button when deleting breakpoints (#5198)
## Description

1. What is this PR about (link the issue and add a short description)

## Steps for reproduction

1. click button
2. expect xyz

## Code Review

- [ ] hi @kof, 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:
0000)
- [ ] updated [test
cases](https://github.com/webstudio-is/webstudio/blob/main/apps/builder/docs/test-cases.md)
document
- [ ] added tests
- [ ] if any new env variables are added, added them to `.env` file
2025-05-11 11:53:53 +02:00
Bogdan Chadkin 8c91170f63 fix: allow deleting from input in preview mode (#5194)
Fixes
https://discord.com/channels/955905230107738152/1369211497590554675

Delete on canvas is separateed from the one in builder so we can safely
remove preventDefault to allow entering or deleting from inputs in
preview mode.
2025-05-11 13:51:17 +04:00
Bogdan Chadkin 29e455a9b7 fix: remove Text Content property from Image component (#5195)
Was accidentally added when rewriting content model.

Also fixed two other issues

- user can override text color in error boundary with global root
- text content property now have tooltip with description and it can be
reset

<img width="320" alt="Screenshot 2025-05-10 at 18 14 19"
src="https://github.com/user-attachments/assets/ffb16efc-e7b5-44d1-a214-0a9251e9eb9d"
/>
2025-05-11 01:10:27 +04:00
Bogdan Chadkin c7c7d668ba experimental: paste inline styles (#5189)
Ref https://github.com/webstudio-is/webstudio/issues/4404

Inline styles are easy to support and tailwind templates occasionally
use them for unsupported stuff. Also fixed space collapsing.



https://github.com/user-attachments/assets/35e7a8d7-ef5b-496c-9a6d-0b05e113e503
2025-05-08 12:58:06 +04:00
Bogdan Chadkin 59b6471c4f experimental: support paste html (#5185)
Ref https://github.com/webstudio-is/webstudio/issues/4404

Slightly reworked paste story. Now minimal API to insert html looks like
this

```js
const fragment = generateFragmentFromHtml(html);
insertWebstudioFragmentAt(fragment);
```

- attributes are casted to string, number and boolean types
- text is wrapped with spans when outside of rich text
- unsupported tags are ignored in result



https://github.com/user-attachments/assets/c8072d86-72bd-4446-a26a-e678b193f93e
2025-05-06 13:31:13 +04:00
Bogdan Chadkin 525804389f experimental: add Element component to builder (#5182)
Ref https://github.com/webstudio-is/webstudio/issues/3632

- Added template for Element component in builder
- Render Element component on canvas
- Labels are shown as html tags
- Element has div tag by default

<img width="276" alt="Screenshot 2025-05-04 at 03 17 53"
src="https://github.com/user-attachments/assets/2f55b5d0-b6a0-4152-968b-842f4fcd18ea"
/>
2025-05-05 11:15:14 +04:00
Bogdan Chadkin 655b887ab9 feat: support paste from other browsers (#5181)
Users started to build own marketplaces. And we found paste something
copied from other browser like firefox -> chromium based app doesn't
work. This is because OSs guarantee only text/plain to be stored in
system clipboard.

Here I changed copy paste logic to copy as text/plain and paste as both
application/json and text/plain if possible.
2025-05-04 18:41:00 +04:00
Bogdan Chadkin 06b39a5691 feat: hide transforms section for inline elements (#5180)
Transforms don't work when display: inline is used. Here we hide
transforms section just like "list item section" for non list tags.

Related video https://www.youtube.com/watch?v=KjpQF3nYGoc



https://github.com/user-attachments/assets/2f1c882f-c627-4e62-9e44-5284117d200a
2025-05-02 23:29:48 +04:00
Bogdan Chadkin 63c54fcad6 refactor: upgrade remix and react-router (#5177)
This should fix a few vulnerabilities we get from react-router and vite
2025-05-02 00:35:20 +04:00
Bogdan Chadkin 6f792e4aac refactor: bump radix (#5129)
https://www.radix-ui.com/primitives/docs/overview/releases#april-8-2025
2025-05-01 15:49:38 +04:00
Bogdan Chadkin c8cbf482bf refactor: upgrade to vite 6 (#5172)
Got rid of "module" export condition everywhere.
Seems like it has very poor usage everywhere.
2025-05-01 10:32:18 +04:00
Bogdan Chadkin 5551451bc4 fix: show description in attributes tooltip (#5173)
Description can be taken from attributes meta. Also moved binding
warning inside of tooltip to avoid layout shift after binding.

<img width="364" alt="Screenshot 2025-04-30 at 17 44 28"
src="https://github.com/user-attachments/assets/903d1309-e7af-4d2b-9aa9-7b36bda4f45d"
/>
2025-05-01 10:23:16 +04:00
Bogdan Chadkin a071280b3d perf: remove html attributes from component metas (#5170)
Now we use html attribute for all components. Now components like Box
with already set "className" property will be migrated to "class"
attribute. This cuts ~350kB in builder scripts. Total ~1MB after
removing both html and aria attributes.

```diff
- 5036    build/client/assets/
+ 4676    build/client/assets/
```

Attributes and properties now have the following order
- component properties
- tag attributes
- global html attributes
- role
- aria attributes
2025-04-30 11:12:42 +04:00
Bogdan Chadkin 0cbfc2db19 refactor: move animate property to sdk runtime (#5171)
Vite 6 is having troubles bundling app which depends on whole sdk. Plus
it may increase app bundle size.
2025-04-30 11:05:50 +04:00
7fa57b2c5b feat: add overflow clip in styles panel (#4914)
closes ( #4203 )

- added a new crop svg to icons package and generated the cropIcon
component.
- replaced the eye icon with the crop icon and also changed hidden to
clip in the overflow toggle group.

---------

Co-authored-by: Oleg Isonen <oleg008@gmail.com>
Co-authored-by: Bogdan Chadkin <opensource@trysound.io>
2025-04-29 16:21:06 +04:00
Bogdan Chadkin 6fa88d9711 refactor: render html attributes for all components (#5163)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Here enabled converting class -> className for all components with tags.
Now it does not affect anything though later will unlock using html
attributes instead of component props.

Also got rid from huge map with react properties and replaced it with a
set of proper aliases.
2025-04-29 15:40:43 +04:00
Bogdan Chadkin 452c50a41a refactor: upgrade vite for vitest and storybook (#5165)
Tough cookie. There is a problem with resolving react-remove-scroll,
figured it by reducing allowed amount of server conditions.
2025-04-29 14:17:42 +04:00
Bogdan Chadkin f13455394d feat: add descriptions to tags (#5164)
Ref https://github.com/webstudio-is/webstudio/issues/3632

Scraped descriptions from html spec to show in tag control.

<img width="297" alt="Screenshot 2025-04-26 at 12 46 21"
src="https://github.com/user-attachments/assets/444e319d-e24f-429e-b09d-1db95cc248d5"
/>
2025-04-26 17:04:31 +07:00
Bogdan Chadkin c1ec5beeb3 fix: rebind nested collection item properly (#5159)
Before parent collection item on nested collection was rebind with
nested collection item which lead to broken state

```
<Collection id="parent" data={[]} item="collectionItem">
  <Collection id="nested" data={collectionItem} item="collectionItem">
  </Collection
</Collection
```

```
collection.map(collectionItem =>
  // oops
  collectionItem2.map(collectionItem2 => {
  })
})
```
2025-04-25 21:05:54 +07:00
Bogdan Chadkin 3826ddd60c feat: add context menu to animations (#5162)
Now user can copy and paste specific animations between animation
groups.

<img width="370" alt="Screenshot 2025-04-24 at 23 41 34"
src="https://github.com/user-attachments/assets/cb183395-e880-44a0-b2d3-fbb922ea3f98"
/>
2025-04-25 17:18:30 +07:00