354 Commits
Author SHA1 Message Date
Bogdan Chadkin f08fe859bb refactor: bump change-case (#2428)
Ref https://github.com/blakeembrey/change-case/releases

Change case in last major merged many packages into one to simplify
maintaining and usage. A few packages like title-case are still separate
as more rare case.

- replaced no-case with change-case (merged into change-case)
- replaced param-case with change-case (merged into change-case and
renamed to kebab (finally))
- replaced camelcase with change-case (has own camelcase utility)
- bumped title-case
2023-10-08 01:03:59 +04:00
Giuseppe b3dd7f18c4 feat: AI Operations (#2391)
Implements an operation-based system to accomplish a number of edit
tasks on a JSX+CSS representation of a selected Webstudio tree.

Every JSX element has the instance id as data-ws-id and therefore the
LLM knows what to edit.

The idea is to create a number of operations (aiOperations)
specs/schemas with Zod describing unique edit tasks, make a
discriminated union, convert them to JSON Schema. We then inject this
information and the current JSX+CSS in the LLM prompt asking the model
to generate an array of operations.

The LLM responds with an array of operations (aiOperations) to fulfill
the user request. We then process these doing the necessary
transformations to convert these to a Webstudio-friendly format
(wsOperations) and send them to the client where we apply them (see
applyOperations).

Some of these operations are going to be "intermediate" operations for
now.

Generating quality user interfaces might be challenging with LLMs.

Having to do so within a generic operations framework like the one
described above makes it even more challenging.

For this reason when it comes to generating user interfaces, the
Operation chain instead offers an operation called
generateTemplatePrompt that provides information about insertion point
in the existing UI and a prompt, possibly enhanced.

Another chain can use these information and a more sophisticated prompt
and model to then generate the user interface and return a
generateInsertTemplate wsOperation. Webstudio does exactly this in a
rest endpoint, using the template-generator chain with gpt4 instead of
gpt-3.5-turbo.
2023-10-06 09:07:59 +02:00
Giuseppe 2ca3907988 feat: JSX utils (#2396)
Adds utils to work with JSX and transform it to Webstudio Embed Template
as well as converting Tailwind styles to Webstudio Embed Template style
declarations and a fake `<HeroIcon>` component to `HtmlEmbed` with
inline SVG taken from heroicons (we will need this for ai).
2023-10-01 12:17:43 +02:00
Bogdan Chadkin 5482ec414a perf: drop internal data from generated sites (#2362)
Internal data structures like instances, props, data sources, assets and
pages no longer necessary in generated sites. Nanostores not longer used
to store them.

Now we have less dependencies and smaller runtime.
2023-09-29 16:22:09 +04:00
Bogdan Chadkin 22a1067ed6 refactor: move props logic to canvas (#2361)
Moved canvas props logic from react-sdk to builder. Added new context to
pass props store, not global because depends on params.
2023-09-25 14:17:40 +04:00
Bogdan Chadkin d25e97fe65 perf: generate pages paths (#2360)
Here generated a list of pages paths. It is used in link component to
switch to remix link internally when the link is app route.

Providing whole pages list can bloat runtime when there are many pages
or when there are many seo data so having single page per route should
be enough.

The list is always empty in builder because links are managed with
global interceptor. Ideally frameworks should uses navigation api and
distinct routes from other paths so we would not need to generate
anything.
2023-09-25 12:20:08 +04:00
Bogdan Chadkin 5f93ecb228 perf: generate page prop for links (#2357)
Moved links resolve into props normalizing which is called for whole
project before rendering converting page prop into string.

Remix links now check only if provided path matches any page. Ideally it
should be handled with navigation api to remove all complexity from
links components.

This will let us stop rendering props and assets data in generated
pages.

Also fixed links with hashes.
2023-09-24 20:07:15 +04:00
Bogdan Chadkin 45585c0565 perf: generate asset prop for links and images (#2356)
Before links and images required logic to traverse raw props data and
assets to resolve href and src. This can potentially affect rendering
performance and requires additional data to be stored in runtime.

Here pregenerated props with "asset" type as a first step. Images still
have to be aware of asset base url to trim it from resolved src but no
longer access to assets store. Links now interpret it as string url.

See fixtures for examples.
2023-09-22 17:48:12 +04:00
Bogdan Chadkin 2dbb1597f0 refactor: remove legacy page renderer (#2352)
- dropped InstanceRoot component
- dropped WebstudioComponent component
- dropped sdk-size-test package
- measure size in fixture package
2023-09-22 10:09:19 +04:00
Bogdan Chadkin fd19a3fac2 feat: switch CLI to jsx component generator (#2330)
Now CLI can produce more or less readable jsx components instead of data
and blackbox renderer.

Some generated code is no longer used and removed.
2023-09-21 17:35:54 +04:00
Bogdan Chadkin 2b52c53cbf Generate stories with new jsx component generator (#2322)
Here added "sdk-cli" package with "generate-stories" command which looks
for metas and generate stories from each one with template. This give us
more insight how component would look like on published sites.

Also removed old stories and added custom id support into embed template
to make stories ids stable.

Can be tested in local storybook
2023-09-17 17:59:54 +04:00
Bogdan Chadkin 1c7df48925 Pregenerate forms properties (#2323)
Here decoupled actions from props data in runtime by generating prepared
forms data. It will let us get rid of props after migrating to jsx
generator.
2023-09-17 12:15:56 +04:00
Bogdan Chadkin 706a590c2b Use new data sources in jsx component generator (#2318)
Here reused new data sources generator to produce
hurman readable page components and leverage builtin React.useState
instead of nanostores.
2023-09-16 14:31:13 +04:00
Bogdan Chadkin 75f72eeccf Drop legacy data sources from builder (#2319)
Here removed all left usages of previous data sources implementation and
removed no longer used expression utilities.
2023-09-16 14:17:10 +04:00
Bogdan Chadkin 8f00d5af2e Generate human readable data sources and actions (#2312)
Scope utility give us a way to generate more readable data sources and
actions. Here variables, expressions and actions are output into the
same map.

In the future same utility can be used to produce framework specific
stores like React.useState.

See fixtures for example.
2023-09-14 20:13:36 +04:00
Bogdan Chadkin f15ea30ae1 Add jsx component generator (#2291)
Here added jsx component generator. It allows us to have less tree
traversing and more clear output for debugging.

For now data sources are managed the old way with stores. In the future
we can switch to react `useState`.

In the future will be integrated into stories generator and cli
2023-09-14 00:02:58 +04:00
Bogdan Chadkin f67b0bd9b0 Expose form state change with action (#2295)
Internal data sources updates complicate code generation Here changed
forms too expose onStateChange action instead of implicit data source
update.

Added migration to add the action to every existing form. Tested locally
both new and migrated forms.
2023-09-12 17:33:50 +04:00
Ivan Starkov 53c97d8d18 Vercel image optimisation support (#2297)
## Description

CLI support of vercel image optimisation


## 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:
5de6)
- [ ] 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.example`
and the `builder/env-check.js` if mandatory
2023-09-11 21:03:02 +03:00
Bogdan Chadkin 88dd24ff7d Move pubsub from sdk to builder (#2280)
Pubsub is only used for builder/canvas communication while sdk is
responsible for rendering sites.
Here moved pubsub to builder. Now we can drop nanoevents from cli
dependencies.
2023-09-08 20:56:46 +04:00
Bogdan Chadkin 87e69b2e85 Move style schema into css-engine (#2251)
Css-data now responsible for generated data and parsers which requires
heavy dependencies like csstree and openai.

Here moved style schema into css-engine which makes is responsible for
own input representation. So now schema and serialization are co-located
in single package.

Cli install size

```diff
du -ck node_modules
- 42680
+ 35516
```
2023-09-06 15:55:41 +04:00
Bogdan Chadkin ee0e0f7e7a Drop prisma from cli (#2241)
Here moved types and utilities from project-build to sdk package. This
removed huge prisma from cli.

```
du -ck node_modules
137460
72464
```
2023-09-04 12:43:56 +04:00
Bogdan Chadkin 2ed1646dae Enforce local style source at the end (#2229)
Ref https://github.com/webstudio-is/webstudio/issues/1965

Tweaked logic and dnd to always put local style source in the end and
tokens before it.
2023-09-04 01:49:13 +04:00
Bogdan Chadkin 5794e8d1e7 Move app schema to sdk (#2237)
We are planning to decouple cli from prisma and all unrelated packages.
Here moved whole app schema into sdk package.
2023-09-03 22:27:30 +04:00
Bogdan Chadkin afc75f1d99 Drop unused db validation (#2231)
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.
2023-09-01 23:57:59 +04:00
Bogdan Chadkin f5882256b8 Move assets schema into sdk package (#2220)
We are planning to move all types necessary to represent generated site
into separate package. This way we will be able to make CLI as small as
possible.

Here moved only assets schema. Now we get rid of aws, sharp and one
prisma usage (project-build still use it)

```diff
- 99MB
+ 75MB
```
2023-08-31 19:39:20 +04:00
Bogdan Chadkin b6c4911e41 Remove generate-arg-types from direct dependencies (#2218)
Here moved PropMeta to react-sdk package. It was the only reason to
install generate-arg-types cli as direct dependency in all component
libraries.

This is the resulting install size of webstudio CLI. TypeScript and
react-docgen-typescript no longer installed.

```diff
- 141MB
+ 99MB
```
2023-08-31 15:59:45 +04:00
Bogdan Chadkin 2b0e9ae206 Remove assets stubbing (#2219)
We used to set undefined in assets map value to preserve the order
between uploading and uploaded states. Now we started sorting uploaded
assets by create time and stubbing no longer do anything useful.
2023-08-31 13:37:52 +04:00
Oleg Isonen 37bd008428 Update main webstudio repo links (#2210)
We renamed webstudio-builder to webstudio
2023-08-29 14:10:43 +04:00
Bogdan Chadkin c48f6613a8 Fix focus navigation in preview (#2179)
Ref https://github.com/webstudio-is/webstudio-builder/issues/2151
https://github.com/webstudio-is/webstudio-builder/pull/2112

Here splitted webstudio component wrapper for preview and canvas. This
allows us to have more granular control over preview behavior. For
example canvas requres all elements to be focusable for instance
selection to work. Prevew should be close to published sites and reflect
user experience.
2023-08-25 17:47:40 +04:00
Ivan Starkov ab436a6fc4 Fix new href property duplicated on unmount (#2170)
## Description

On onmount outdated onSave were used. What cause creation of additional
href property on instance.

- [x] - Fix duplication on unmount (1st commit)
- [x] - Fix save, to validate if multiple properties with same name
exists. (2nd commit)
- [x] - Use latest prop in resolveUrlProp (3rd commit)

Use hide whitespaces.

<img width="303" alt="image"
src="https://github.com/webstudio-is/webstudio-builder/assets/5077042/156fc5a4-c697-4b05-8caf-7a3b7fa29264">


## 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:
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
2023-08-25 10:36:14 +03:00
Ivan Starkov 61acb2395c Nav menu internals (#2153)
## Description

ref #2151

<img width="592" alt="image"
src="https://github.com/webstudio-is/webstudio-builder/assets/5077042/2cfb1294-1b2b-4dd1-b4b7-0fa7ed355c90">

<img width="585" alt="image"
src="https://github.com/webstudio-is/webstudio-builder/assets/5077042/f71b000f-272a-44cf-a783-378d64570102">


## 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:
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
2023-08-21 23:52:22 +03:00
Bogdan Chadkin 5e900ff2e8 Add component tokens support (#2147)
Ref https://github.com/webstudio-is/webstudio-builder/issues/2137

Here added static tokens support to meta. Id of resulting style source
become persistent like this "componentName:tokenName". Such token styles
are inserted only if style source with same id not exist. This way we
prevent breaking styles already changed by user.

Style source input now autocomplete global tokens and suggest to create
predefined component tokens.

Also disabled spell check in style source input.

<img width="244" alt="Screenshot 2023-08-20 at 17 18 37"
src="https://github.com/webstudio-is/webstudio-builder/assets/5635476/9572f5b1-6243-49fa-83be-a0315f104987">
2023-08-20 18:48:16 +04:00
Bogdan Chadkin 8bfdf3174f Release 0.87.1 (#2114) 2023-08-13 23:15:41 +04:00
Bogdan Chadkin b1ce0c1bc9 Export generateUtilsExport 2023-08-13 20:18:00 +04:00
Bogdan Chadkin f240c46027 Infer label from component name (#2106)
Here made meta.label optional to simplify adding new stuff. Most of the
time label is just a "humanized" version of component name. With radix
there is an additional action to strip namespace. But still would be
less repetition if the name is just inferred.
2023-08-13 13:12:51 +04:00
Bogdan Chadkin b8a7a40dd5 Add utilities generator to sdk (#2098)
Here moved code generation of utilities from saas into sdk.

Now InstanceRoot accepts utils object with these 3 fields

- indexesWithinAncestors,
- executeComputingExpressions,
- executeEffectfulExpression,

Generation utility can be shared between cli and saas to simplify
maintenance.
2023-08-12 17:04:37 +04:00
Ivan Starkov 7a8fd3db49 Radix Button (#2097)
## Description

Add radix button.


<img width="555" alt="image"
src="https://github.com/webstudio-is/webstudio-builder/assets/5077042/afd07b25-2592-4ed6-9788-dd880be2f22e">


## 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:
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
2023-08-12 15:30:00 +03:00
Bogdan Chadkin a737e03c8f Automatically open tab content on select in navigator (#2073)
Here added tabs hooks to auto select tab when its content is selected.
Added new utils to hook context getPropValue and indexesWithinAncestors.

Renamed instanceSelection to instancePath.

Had to pass all props in edit mode in webstudio component



https://github.com/webstudio-is/webstudio-builder/assets/5635476/1f1211bc-0ea4-4d21-9205-1439668e08b4
2023-08-10 22:02:25 +04:00
Bogdan Chadkin fdf22ab9e6 Add component hooks (#2069)
We want to control some builder behavior specific to some components.
For example set open state on dialog, collapsible etc when select in
navigator.

Here I added hooks to be called from builder and executed in canvas. For
now added 2 hooks onNavigatorSelect and onNavigatorDeselect.
2023-08-08 16:38:53 +04:00
Ivan Starkov 9a0536e852 Fix presets in radix (namespaces issue) (#2025)
## Description

Fix presets in case of namespaeces added `"` to selector
<img width="605" alt="image"
src="https://github.com/webstudio-is/webstudio-builder/assets/5077042/9b367c73-466e-4592-b45f-0b84660e423f">


Added presets to radix components


## 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:
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
2023-08-03 13:37:44 +03:00
Bogdan Chadkin 40e71b6c5b Simplify indexes within ancestors (#2021)
Here added dedicated field to meta to simplify computing and using
indexes.

```
{
  type: 'container',
  label: 'Tab Trigger',
  // this one
  indexWithinAncestor: 'Tabs'
}
```

Since it's single value, we no longer need to provide ancestor name in
runtime and no longer have bug with namespaces. Index now provided with
props.

```
getIndexWithinAncestorFromComponentProps(props): string | undefined
```
2023-08-01 22:40:16 +04:00
Bogdan Chadkin f751045e22 Add namespace prefix to constraints (#2020)
Ref
https://discord.com/channels/955905230107738152/1135965820602831036/1135965820602831036

This fixes the issue with adding any radix component. It got broken
because of unprefixed constraints.
2023-08-01 20:35:53 +04:00
Bogdan Chadkin 33a4b8dace Decouple data sources from props in templates (#2013)
Here changed the way we define data sources in embed templates. Now they
have separate section on instance. This way we will be able to use data
sources on styles or instances without binding them to props.

Also it's not more clear where data source is created vs where it is
only referenced.

```js
{
  type: 'instance',
  component: 'Form',
  dataSources: {
    state: { type: 'variable', initialValue: 'initial' },
    stateInitial: { type: 'expression', code: `state === 'initial'` }
  },
  props: [
    {
      type: 'dataSource',
      name: 'data-state',
      dataSourceName: 'state'
    }
  ],
  children: []
}
```
2023-08-01 16:59:07 +04:00
Bogdan Chadkin 4cfb0a9d62 Compute indexes within required ancestors (#2000)
Ref https://github.com/webstudio-is/webstudio-builder/pull/1516

Here added utility to compute indexes within ancestors. This should let
us easily co-locate tabs triggers and contents by their indexes.
2023-08-01 14:32:06 +04:00
Bogdan Chadkin ac735df3ce Render component templates in stories (#2009)
Here added utility to render component templates in stories as it will
work in published site without running builder.

It will help to be more confident in templates we write for components.
Especially with complex logic with variables and expressions.

Can be tested here
https://638affb61acca1e593c6e558-gxuvohlrer.chromatic.com/?path=/story/sdk-components-react-radix_components-collapsible--collapsible
2023-07-31 15:46:56 +04:00
Bogdan Chadkin 923a3868a1 Fix drag&drop on canvas (#2007)
Here fixed droping new components on canvas.
Template was used to check constraints but failed
when no template found. Fixed by using fallback.
2023-07-31 13:23:55 +04:00
Bogdan Chadkin 381a962437 Namespace component libraries (#2005)
Here added support for namespacing external libraries. Need this for
radix components to not prefix manually and have isolation in names in
case a few client libs are added an have collission in names or we add
native components with same names.
2023-07-30 21:14:57 +04:00
Bogdan Chadkin 6500e01397 Move getBrowserStyle utility into builder (#2004)
getBrowserStyle is used only inside of builder and should not be part of
sdk importable by all component libraries. It also depends on global
types which need to be included in every package dependent on react-sdk.
2023-07-30 20:56:29 +04:00
Bogdan Chadkin 9328961b87 Allow to disable components detaching (#1986)
Here added meta.detachable flag which allows when set to true disable
copying, dragging and deleting instances of this component without ts
parent instance.

This is necessary to constrain components based on external code and
prevent deleting hidden components user cannot add again.
2023-07-27 20:43:46 +03:00
Bogdan Chadkin 09d2b77151 Support effectful expression arguments (#1967)
Here added support for expression arguments to utilize callback based
state management. So for example Form component can expose onStateChange
action with "newState" value and update any variable with it. So all
state management inside form becomes prop and callback.

You can test it by pasting

<details>
<summary>You can test by pasting this template and clicking on
+</summary>

```ison
{
  "@webstudio/template": [
    {
      "type": "instance",
      "component": "Box",
      "props": [
        {
          "type": "number",
          "name": "data-count",
          "value": 0,
          "dataSourceRef": {
            "type": "variable",
            "name": "count"
          }
        }
      ],
      "styles": [
        {
          "property": "display",
          "value": { "type": "keyword", "value": "flex" }
        }
      ],
      "children": [
        {
          "type": "instance",
          "component": "Button",
          "props": [
            {
              "type": "action",
              "name": "onClick",
              "value": [
                {
                  "type": "execute",
                  "code": "count = count - 1"
                }
              ]
            }
          ],
          "children": [{ "type": "text", "value": "-" }]
        },
        {
          "type": "instance",
          "component": "Box",
          "props": [
            {
              "type": "string",
              "name": "data-count",
              "value": "",
              "dataSourceRef": {
                "type": "expression",
                "name": "countString",
                "code": "\"0\" + count"
              }
            }
          ],
          "styles": [
            {
              "state": "::before",
              "property": "content",
              "value": { "type": "unparsed", "value": "attr(data-count)" }
            }
          ],
          "children": []
        },
        {
          "type": "instance",
          "component": "Button",
          "props": [
            {
              "type": "action",
              "name": "onClick",
              "value": [
                {
                  "type": "execute",
                  "args": ["event"],
                  "code": "count = count + 1 + event"
                }
              ]
            }
          ],
          "children": [{ "type": "text", "value": "+" }]
        }
      ]
    }
  ]
}
```

</details>
2023-07-24 20:14:01 +03:00