@webflow/webflow-cli 1.6.4 → 1.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +12 -0
- package/dist/index.js +836 -947
- package/dist/scaffolds/default/README.md +24 -0
- package/dist/scaffolds/default/package.json +15 -0
- package/dist/scaffolds/default/public/index.html +21 -0
- package/dist/scaffolds/default/public/styles.css +35 -0
- package/dist/scaffolds/default/src/index.ts +73 -0
- package/dist/scaffolds/default/tsconfig.json +8 -0
- package/dist/scaffolds/default/webflow.json +5 -0
- package/dist/scaffolds/react/README.md +19 -0
- package/dist/scaffolds/react/package.json +28 -0
- package/dist/scaffolds/react/public/index.html +13 -0
- package/dist/scaffolds/react/public/styles.css +23 -0
- package/dist/scaffolds/react/src/main.js +27 -0
- package/dist/scaffolds/react/webflow.json +5 -0
- package/dist/scaffolds/react/webpack.config.mjs +33 -0
- package/dist/scaffolds/typescript-alt/README.md +19 -0
- package/dist/scaffolds/typescript-alt/package.json +15 -0
- package/dist/scaffolds/typescript-alt/public/index.html +9 -0
- package/dist/scaffolds/typescript-alt/public/styles.css +35 -0
- package/dist/scaffolds/typescript-alt/src/index.ts +11 -0
- package/dist/scaffolds/typescript-alt/tsconfig.json +8 -0
- package/dist/scaffolds/typescript-alt/webflow.json +5 -0
- package/package.json +1 -1
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# Designer Extension Starter: TypeScript
|
|
2
|
+
|
|
3
|
+
This is an example Webflow Designer extension written in TypeScript that inserts a text emoji into an element selected within the Designer. Check out our [documentation](https://docs.developers.webflow.com/v2.0.0/docs/create-a-designer-extensions) for in-depth information about Designer Extension features and API.
|
|
4
|
+
|
|
5
|
+
## Developing
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
$ npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
The above command does a few things:
|
|
12
|
+
* Installs dependencies
|
|
13
|
+
* Watches for changes in the `src/` folder and recompiles your TypeScript files, outputting an `index.js` file under the `public/` folder
|
|
14
|
+
* Spins up a process that serves your extension files from under `public/`
|
|
15
|
+
|
|
16
|
+
The command outputs the URL under which your extension is being served. Use this as the “Development URL” for your app in the Webflow Designer’s Apps panel. You can then launch the extension from the same place.
|
|
17
|
+
|
|
18
|
+
## Deploying
|
|
19
|
+
|
|
20
|
+
```
|
|
21
|
+
$ npm run build
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
This will take the contents of the `./public` folder and prepare a `bundle.zip` file ready for you to upload as a Designer extension for your App.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wf-placeholder-name",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "npm install && tsc -p tsconfig.json && webflow extension bundle",
|
|
8
|
+
"dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\""
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@webflow/designer-extension-typings": "*",
|
|
12
|
+
"concurrently": "*",
|
|
13
|
+
"typescript": "*"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<link href="./styles.css" rel="stylesheet" />
|
|
6
|
+
</head>
|
|
7
|
+
|
|
8
|
+
<body>
|
|
9
|
+
<form id="extension-form">
|
|
10
|
+
<div>Choose a text element and select the emoji to insert</div>
|
|
11
|
+
<div id="emoji-container">
|
|
12
|
+
<button id="smile">😊</button>
|
|
13
|
+
<button id="wink">😉</button>
|
|
14
|
+
<button id="heart">😍</button>
|
|
15
|
+
<button id="cry">😭</button>
|
|
16
|
+
</div>
|
|
17
|
+
</form>
|
|
18
|
+
|
|
19
|
+
<script src="index.js" defer></script>
|
|
20
|
+
</body>
|
|
21
|
+
</html>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
form {
|
|
10
|
+
padding: 16px;
|
|
11
|
+
font-family: sans-serif;
|
|
12
|
+
text-align: center;
|
|
13
|
+
color: #fff;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
button {
|
|
17
|
+
color: #fff;
|
|
18
|
+
background: #0073e6;
|
|
19
|
+
padding: 4px 8px;
|
|
20
|
+
border: 2px solid #0073e6;
|
|
21
|
+
border-radius: 4px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
button:focus {
|
|
25
|
+
outline: none;
|
|
26
|
+
border-color: #1280ee;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
label > input[type="radio"] {
|
|
30
|
+
visibility: hidden;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#emoji-container {
|
|
34
|
+
margin-top: 1.5rem;
|
|
35
|
+
}
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
const emojiMap = {
|
|
2
|
+
smile: "😊",
|
|
3
|
+
wink: "😉",
|
|
4
|
+
heart: "😍",
|
|
5
|
+
cry: "😭",
|
|
6
|
+
};
|
|
7
|
+
|
|
8
|
+
// default to smile
|
|
9
|
+
let selectedEmoji = emojiMap.smile;
|
|
10
|
+
addButtonListeners();
|
|
11
|
+
|
|
12
|
+
document.getElementById("extension-form").onsubmit = async (event) => {
|
|
13
|
+
event.preventDefault();
|
|
14
|
+
|
|
15
|
+
// Get the current selected Element
|
|
16
|
+
const el = await webflow.getSelectedElement();
|
|
17
|
+
|
|
18
|
+
// If styles can be set on the Element
|
|
19
|
+
if (el && el.styles && el.configurable && el.children) {
|
|
20
|
+
//Get current element's style
|
|
21
|
+
const currentStyle = await el.getStyles();
|
|
22
|
+
|
|
23
|
+
// Get style
|
|
24
|
+
const emojiStyle = await createOrUseStyle("emoji-style");
|
|
25
|
+
|
|
26
|
+
// Create a new element that will display the text-emoji
|
|
27
|
+
const labelElement = await webflow.createDOM("span");
|
|
28
|
+
labelElement.setStyles([...currentStyle, emojiStyle]);
|
|
29
|
+
labelElement.setTextContent(selectedEmoji);
|
|
30
|
+
|
|
31
|
+
el.setChildren([...el.getChildren(), labelElement]);
|
|
32
|
+
await el.save();
|
|
33
|
+
} else {
|
|
34
|
+
alert("Please select a text element");
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
// Check if specified style exists. If not, create a new style
|
|
39
|
+
async function createOrUseStyle(styleName) {
|
|
40
|
+
// Check if this style exists to avoid duplicate styles
|
|
41
|
+
const style = await webflow.getStyleByName(styleName);
|
|
42
|
+
if (style) {
|
|
43
|
+
// Return existing style
|
|
44
|
+
return style;
|
|
45
|
+
} else {
|
|
46
|
+
// Create a new style, return it
|
|
47
|
+
const emojiStyle = webflow.createStyle(styleName);
|
|
48
|
+
emojiStyle.setProperties({ "background-color": "#FF00FF" });
|
|
49
|
+
return emojiStyle;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function handleEmojiClick(emoji) {
|
|
54
|
+
selectedEmoji = emoji;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function addButtonListeners() {
|
|
58
|
+
document.getElementById("smile").onclick = () => {
|
|
59
|
+
handleEmojiClick(emojiMap.smile);
|
|
60
|
+
};
|
|
61
|
+
|
|
62
|
+
document.getElementById("wink").onclick = () => {
|
|
63
|
+
handleEmojiClick(emojiMap.wink);
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
document.getElementById("heart").onclick = () => {
|
|
67
|
+
handleEmojiClick(emojiMap.heart);
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
document.getElementById("cry").onclick = () => {
|
|
71
|
+
handleEmojiClick(emojiMap.cry);
|
|
72
|
+
};
|
|
73
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Designer Extension Starter: React
|
|
2
|
+
|
|
3
|
+
Explore the [documentation](https://docs.developers.webflow.com/v2.0.0/docs/create-a-designer-extensions) for detailed information on Designer Extension features and API.
|
|
4
|
+
|
|
5
|
+
## Local Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This command installs dependencies, watches for changes in the `src/` folder, and serves your extension files from `./dist/`. Use the displayed URL as the "Development URL" in Webflow Designer's Apps panel to launch your extension.
|
|
12
|
+
|
|
13
|
+
## Build for Distribution
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This command prepares a `${bundleFile}` in the `./dist/` folder. Upload this `bundle.zip` file for distributing the App inside of your workspace or via the Marketplace.
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wf-placeholder-name",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"scripts": {
|
|
5
|
+
"dev": "npm install && concurrently \"webflow extension serve\" \"npm run watch-webpack\"",
|
|
6
|
+
"build": "npm run build-webpack && webflow extension bundle",
|
|
7
|
+
"watch-webpack": "webpack --config webpack.config.mjs --mode development --watch",
|
|
8
|
+
"build-webpack": "webpack --config webpack.config.mjs --mode production"
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@babel/preset-env": "^7.23.2",
|
|
12
|
+
"@babel/preset-react": "^7.22.15",
|
|
13
|
+
"@webflow/designer-extension-typings": "*",
|
|
14
|
+
"concurrently": "*",
|
|
15
|
+
"babel-loader": "^9.1.3",
|
|
16
|
+
"webpack": "^5.89.0",
|
|
17
|
+
"webpack-cli": "^5.1.4"
|
|
18
|
+
},
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"react-dom": "^18.2.0"
|
|
21
|
+
},
|
|
22
|
+
"babel": {
|
|
23
|
+
"presets": [
|
|
24
|
+
"@babel/preset-env",
|
|
25
|
+
"@babel/preset-react"
|
|
26
|
+
]
|
|
27
|
+
}
|
|
28
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="en">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="UTF-8" />
|
|
5
|
+
<title>My React App</title>
|
|
6
|
+
<link href="./styles.css" rel="stylesheet" />
|
|
7
|
+
</head>
|
|
8
|
+
|
|
9
|
+
<body>
|
|
10
|
+
<div id="root"></div>
|
|
11
|
+
<script src="./bundle.js"></script>
|
|
12
|
+
</body>
|
|
13
|
+
</html>
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
background: #333;
|
|
4
|
+
color: white;
|
|
5
|
+
display: flex;
|
|
6
|
+
flex-direction: column;
|
|
7
|
+
align-items: center;
|
|
8
|
+
justify-content: center;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
button {
|
|
12
|
+
color: #fff;
|
|
13
|
+
background: #0073e6;
|
|
14
|
+
padding: 4px 8px;
|
|
15
|
+
border: 2px solid #0073e6;
|
|
16
|
+
border-radius: 4px;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
button:focus {
|
|
20
|
+
outline: none;
|
|
21
|
+
border-color: #1280ee;
|
|
22
|
+
}
|
|
23
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import ReactDOM from "react-dom";
|
|
3
|
+
|
|
4
|
+
const App = () => {
|
|
5
|
+
const addText = async () => {
|
|
6
|
+
// Get the current selected Element
|
|
7
|
+
let el = await webflow.getSelectedElement();
|
|
8
|
+
|
|
9
|
+
// If text content can be set, update it!
|
|
10
|
+
if (el && el.configurable && el.setTextContent) {
|
|
11
|
+
el.setTextContent("hello world!");
|
|
12
|
+
await el.save();
|
|
13
|
+
} else {
|
|
14
|
+
alert("Please select a text element");
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<div>
|
|
20
|
+
<h1>Welcome to My React App!</h1>
|
|
21
|
+
<p>This is a basic React application.</p>
|
|
22
|
+
<button onClick={addText}> Add text </button>
|
|
23
|
+
</div>
|
|
24
|
+
);
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
ReactDOM.render(<App />, document.getElementById("root"));
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import path from "path";
|
|
2
|
+
import { fileURLToPath } from "url";
|
|
3
|
+
|
|
4
|
+
const filename = fileURLToPath(import.meta.url);
|
|
5
|
+
const dirname = path.dirname(filename);
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
entry: "./src/main.js",
|
|
9
|
+
output: {
|
|
10
|
+
filename: "bundle.js",
|
|
11
|
+
path: path.resolve(dirname, "public"),
|
|
12
|
+
},
|
|
13
|
+
module: {
|
|
14
|
+
rules: [
|
|
15
|
+
{
|
|
16
|
+
test: /\.js$/,
|
|
17
|
+
exclude: /node_modules/,
|
|
18
|
+
use: {
|
|
19
|
+
loader: "babel-loader",
|
|
20
|
+
},
|
|
21
|
+
},
|
|
22
|
+
{
|
|
23
|
+
test: /\.css$/,
|
|
24
|
+
use: ["style-loader", "css-loader"],
|
|
25
|
+
},
|
|
26
|
+
],
|
|
27
|
+
},
|
|
28
|
+
devServer: {
|
|
29
|
+
static: [{ directory: path.join(dirname, "public") }],
|
|
30
|
+
compress: true,
|
|
31
|
+
port: 3000,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
# Designer Extension Starter: TypeScript (Alt)
|
|
2
|
+
|
|
3
|
+
Explore the [documentation](https://docs.developers.webflow.com/v2.0.0/docs/create-a-designer-extensions) for in-depth information about Designer Extension features and API.
|
|
4
|
+
|
|
5
|
+
## Development
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm run dev
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
This command installs dependencies, watches for changes in the `src/` folder, recompiles TypeScript files, and serves your extension files from `${defaultPublicDir}/`. Use the displayed URL as the "Development URL" in Webflow Designer's Apps panel to launch your extension.
|
|
12
|
+
|
|
13
|
+
## Deployment
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
npm run build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
This command prepares a `${bundleFile}` in the `./public` folder. Upload this `bundle.zip` file for distributing the App inside of your workspace or via the Marketplace.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "wf-placeholder-name",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"private": true,
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"scripts": {
|
|
7
|
+
"build": "npm install && tsc -p tsconfig.json && webflow extension bundle",
|
|
8
|
+
"dev": "npm install && concurrently -r \"webflow extension serve\" \"tsc -p tsconfig.json --watch --preserveWatchOutput\""
|
|
9
|
+
},
|
|
10
|
+
"devDependencies": {
|
|
11
|
+
"@webflow/designer-extension-typings": "*",
|
|
12
|
+
"concurrently": "*",
|
|
13
|
+
"typescript": "*"
|
|
14
|
+
}
|
|
15
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
<link href="styles.css" rel="stylesheet" />
|
|
2
|
+
<form id="lorem">
|
|
3
|
+
<div>
|
|
4
|
+
Select a textual element in the Designer and press the button below to give
|
|
5
|
+
it some placeholder content.
|
|
6
|
+
</div>
|
|
7
|
+
<button>Lorem ipsum</button>
|
|
8
|
+
</form>
|
|
9
|
+
<script src="index.js"></script>
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
body {
|
|
2
|
+
margin: 0;
|
|
3
|
+
display: flex;
|
|
4
|
+
flex-direction: column;
|
|
5
|
+
align-items: center;
|
|
6
|
+
justify-content: center;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
form {
|
|
10
|
+
padding: 16px;
|
|
11
|
+
font-family: sans-serif;
|
|
12
|
+
text-align: center;
|
|
13
|
+
color: #fff;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
button {
|
|
17
|
+
color: #fff;
|
|
18
|
+
background: #0073e6;
|
|
19
|
+
padding: 4px 8px;
|
|
20
|
+
border: 2px solid #0073e6;
|
|
21
|
+
border-radius: 4px;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
button:focus {
|
|
25
|
+
outline: none;
|
|
26
|
+
border-color: #1280ee;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
label > input[type="radio"] {
|
|
30
|
+
visibility: hidden;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
#emoji-container {
|
|
34
|
+
margin-top: 1.5rem;
|
|
35
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
document.getElementById("lorem")!.onsubmit = async (event) => {
|
|
2
|
+
event.preventDefault();
|
|
3
|
+
const el = await webflow.getSelectedElement();
|
|
4
|
+
if (el && el.textContent) {
|
|
5
|
+
el.setTextContent(
|
|
6
|
+
"Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do " +
|
|
7
|
+
"eiusmod tempor incididunt ut labore et dolore magna aliqua.",
|
|
8
|
+
);
|
|
9
|
+
el.save();
|
|
10
|
+
}
|
|
11
|
+
};
|