Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions api/03-creating-extensions.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,8 @@ title: Creating Extensions
This document outlines how to write your own extensions for **Phoenix Code**.

## How to create a new Extension
Click on one of the links below and follow the instructions there to start:
* [Create an Extension](https://github.com/phcode-dev/extension-template)
* [Create a Node.js Extension](https://github.com/phcode-dev/extension-node-template)
Click on the link below and follow the instructions there to start:
[Create an Extension](https://github.com/phcode-dev/extension-template)

## API docs
Please refer to the links below for extension API docs and code references.
Expand Down
61 changes: 61 additions & 0 deletions api/04-creating-node-extensions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
---
title: Creating Node Extensions
---

This document outlines how to create node extensions for **Phoenix Code**.

## How to create a new Node Extension

To create a new node extension for Phoenix Code, use [this template](https://github.com/phcode-dev/extension-node-template). This template extension works in the browser as well as desktop builds. In browser, it will not use node, and node.js based functionalities are not available. Desktop builds can use node capabilities.

In desktop builds, there is an additional capability to execute node.js code. This is helpful if you want to extend the functionality of Phoenix Code using the vast npm library.

For creating extensions that do not need node, use: [https://github.com/phcode-dev/extension-template](https://github.com/phcode-dev/extension-template)


## Setting up node extensions

In package.json, add the following section

```
{
"nodeConfig": {
"nodeIsRequired": false,
"main": "node/index.js",
"npmInstall": "node/"
}
}
```

## nodeConfig Object

The nodeConfig object indicates that this is a Node extension.
### nodeIsRequired Field

Set this field to `true` if the extension relies on Node and won't function without it.
If set to `false` or omitted, the extension can still be loaded in browser versions of Phoenix code without Node support, but it will use Node in native builds.
It will be shown in the extension manager dialog in browser builds as well.

### main Field

Specifies the main entry point for the Node.js component of the extension.
Should point to the main JavaScript file for the Node part of the extension.
Example: "main": "node/index.js"

### npmInstall Field (Optional)

Specifies the path to run npm install when the user installs the extension from the extension manager.
It's advisable not to package node_modules inside the extension. Only the package lock file should be distributed.
Example: "npmInstall": "node/"

## Communicating between node.js and Phoenix Code

Use the [NodeConnector-API](https://docs.phcode.dev/api/API-Reference/NodeConnector) to call functions and send events between your node.js and Phoenix Code extension components.

This is available as a global object global.createNodeConnector.

[EventDispatcher-API](https://docs.phcode.dev/api/API-Reference/utils/EventDispatcher) is also available in the global context as global.EventDispatcher for event trigger/listen within node.


## Using this template
[Click Here](https://github.com/phcode-dev/extension-node-template/blob/main/README.md#using-this-template) for the instructions on how to use this template.
File renamed without changes.
File renamed without changes.
File renamed without changes.
323 changes: 323 additions & 0 deletions api/08-Extension-Quick-Start/Dialogs.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,323 @@
---
title: Dialogs and Buttons
---

## Adding a Dialog Box and Buttons

To add a dialog box, follow these steps:

1. **Import the required modules.**
Import the `Dialogs` and `DefaultDialogs` modules along with other necessary modules:

```jsx
const DefaultDialogs = brackets.getModule("widgets/DefaultDialogs"),
Dialogs = brackets.getModule("widgets/Dialogs");

// other modules you may require
const AppInit = brackets.getModule("utils/AppInit"),
CommandManager = brackets.getModule("command/CommandManager"),
Menus = brackets.getModule("command/Menus");

```

2. **Create a function to show the dialog**

To create a dialog you can use the specialized dialog APIs such as `Dialogs.showConfirmDialog`, `Dialogs.showInfoDialog` and `Dialogs.showErrorDialog` provided by the `Dialogs` module:


```jsx
function handleHelloWorld() {
Dialogs.showInfoDialog(
"hello", // Title
"world" // Message
);
}
```

The `Dialogs.showInfoDialog()` method is the preferred way to display information messages.

Similarly, you can use `Dialogs.showErrorDialog()` for error messages:

```jsx
function handleError() {
Dialogs.showErrorDialog(
"Error",
"Something went wrong!"
);
}
```

You can also close the dialog programmatically using the `Dialog.close()` method.

```jsx
function handleHelloWorld() {
const dialog = Dialogs.showInfoDialog(
"hello",
"world"
);

// Close the dialog after 2 seconds
setTimeout(() => {
dialog.close();
}, 2000);
}
```

This will automatically close the dialog after 2 seconds.

These specialized dialog methods handle the common use cases.

Click on the functions to read more about them : [showConfirmDialog()](https://docs.phcode.dev/api/API-Reference/widgets/Dialogs#showConfirmDialog), [showInfoDialog](https://docs.phcode.dev/api/API-Reference/widgets/Dialogs#showInfoDialog), [showErrorDialog](https://docs.phcode.dev/api/API-Reference/widgets/Dialogs#showErrorDialog).

If you require custom buttons or advanced functionality, you can use the generic `showModalDialog()` method.

[Click here](#creating-custom-dialog-boxes) to read more about creating custom dialog boxes.

3. **Register the command**
Register a command that will trigger the dialog:

```jsx
const MY_COMMAND_ID = "helloworld_sayhello";
CommandManager.register("Hello World", MY_COMMAND_ID, handleHelloWorld);
```

4. **Add the menu item**
Add a menu item that will execute the command:

```jsx
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
menu.addMenuItem(MY_COMMAND_ID);
```

Full Code Example:

```jsx
define(function (require, exports, module) {
"use strict";

// Brackets modules
const AppInit = brackets.getModule("utils/AppInit"),
DefaultDialogs = brackets.getModule("widgets/DefaultDialogs"),
Dialogs = brackets.getModule("widgets/Dialogs"),
CommandManager = brackets.getModule("command/CommandManager"),
Menus = brackets.getModule("command/Menus");

// Function to run when the menu item is clicked
function handleHelloWorld() {
Dialogs.showInfoDialog(
"hello",
"world"
);
}

// Register command
const MY_COMMAND_ID = "helloworld_sayhello";
CommandManager.register("Hello World", MY_COMMAND_ID, handleHelloWorld);

// Add menu item
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
menu.addMenuItem(MY_COMMAND_ID);

// Initialize extension
AppInit.appReady(function () {
console.log("hello world");
});
});
```

Expected Output:

When the menu item is clicked, a dialog box appears:

![Dialog box](./images/dialog.png)


## Creating Custom Dialog Boxes

While the specialized dialog methods like `showInfoDialog()`, `showConfirmDialog()` and `showErrorDialog()` cover the common use cases, you can also create more complex custom dialog boxes using `showModalDialog()`. Here's how:

```jsx
const dialog = Dialogs.showModalDialog(
DefaultDialogs.DIALOG_ID_INFO,
"Custom Dialog",
// Custom HTML content with CSS styling
'<div class="custom-dialog">' +
'<p style="text-align: center">This is a custom message</p>' +
'<input style="width: 97%" type="text" id="custom-input" placeholder="Enter some text...">' +
"</div>",
[
// For buttons
{
className: Dialogs.DIALOG_BTN_CLASS_PRIMARY,
id: Dialogs.DIALOG_BTN_OK,
text: "OK",
},
{
className: Dialogs.DIALOG_BTN_CLASS_NORMAL,
id: Dialogs.DIALOG_BTN_CANCEL,
text: "Cancel",
},
]
);
```

The `showModalDialog()` method provides more flexibility, allowing you to create custom dialog boxes with HTML content and buttons. However, it's recommended to use the specialized dialog APIs like `showInfoDialog()`, `showConfirmDialog()` and `showErrorDialog()` whenever possible, as they provide a simpler and more standardized interface for the most common dialog types.

Visual Reference

![Custom Dialog Box](./images/custom-dialog.png)

[Click Here](https://docs.phcode.dev/api/API-Reference/widgets/Dialogs#showModalDialog) to read more about `showModalDialog()`.

→ Each button object can have:

- `className`: Button styling class
- `id`: Button identifier
- `text`: Button label text

→ Available Button Classes:

- `Dialogs.DIALOG_BTN_CLASS_PRIMARY`: Primary action button
- `Dialogs.DIALOG_BTN_CLASS_NORMAL`: Normal button
- `Dialogs.DIALOG_BTN_CLASS_LEFT`: Left-aligned button

→ Common Button IDs:

- `Dialogs.DIALOG_BTN_OK`
- `Dialogs.DIALOG_BTN_CANCEL`
- `Dialogs.DIALOG_BTN_SAVE_AS`
- `Dialogs.DIALOG_BTN_DONTSAVE`
- `Dialogs.DIALOG_BTN_DOWNLOAD`

## Handle Button Clicks

You can handle button clicks using the dialog's promise:

```jsx
dialog.done(function (buttonId) {
if (buttonId === Dialogs.DIALOG_BTN_OK) {
const inputValue = $input.val();
alert("Input value: " + inputValue);
}
});
```

Complete Code Block with Custom Dialog Box and handling the button clicks.

```jsx
define(function (require, exports, module) {
"use strict";

const AppInit = brackets.getModule("utils/AppInit"),
DefaultDialogs = brackets.getModule("widgets/DefaultDialogs"),
Dialogs = brackets.getModule("widgets/Dialogs"),
CommandManager = brackets.getModule("command/CommandManager"),
Menus = brackets.getModule("command/Menus");

function showCustomDialog() {
const dialog = Dialogs.showModalDialog(
DefaultDialogs.DIALOG_ID_INFO,
"Custom Dialog",
// Custom HTML content
'<div class="custom-dialog">' +
'<p style="text-align: center">This is a custom message</p>' +
'<input style="width: 97%" type="text" id="custom-input" placeholder="Enter some text...">' +
"</div>",
[
{
className: Dialogs.DIALOG_BTN_CLASS_PRIMARY,
id: Dialogs.DIALOG_BTN_OK,
text: "OK"
},
{
className: Dialogs.DIALOG_BTN_CLASS_NORMAL,
id: Dialogs.DIALOG_BTN_CANCEL,
text: "Cancel"
}
]
);

// Get dialog element and ensure input is accessible
const $dlg = dialog.getElement();
const $input = $dlg.find("#custom-input");

if (!$input.length) {
console.error("Failed to find input element in dialog");
return;
}

// Handle dialog button clicks
dialog.done(function (buttonId) {
if (buttonId === Dialogs.DIALOG_BTN_OK) {
const inputValue = $input.val();
alert("Input value: " + inputValue);
}
});
}

// Register command
const MY_COMMAND_ID = "test_customdialog";
CommandManager.register("Show Custom Dialog", MY_COMMAND_ID, showCustomDialog);

// Add menu item
const menu = Menus.getMenu(Menus.AppMenuBar.FILE_MENU);
menu.addMenuItem(MY_COMMAND_ID);

// Initialize extension
AppInit.appReady(function () {
console.log("Custom dialog extension loaded");
});
});
```

Visual Reference

![Custom-dialog-box-gif](./images/custom-dialog-box-gif.gif)


## Adding a button on Status Bar

1. Import the `StatusBar` module.

```jsx
const StatusBar = brackets.getModule("widgets/StatusBar");
```


2. Register the command.

Register the command that will trigger the clicking.

```jsx
var MY_COMMAND_ID = "helloworld_sayhello";
CommandManager.register("Hello World", MY_COMMAND_ID, handleHelloWorld);
```


3. Add the button to the StatusBar.

To add the button to StatusBar, use `addIndicator()` :-


```jsx
StatusBar.addIndicator(
MY_COMMAND_ID, // unique ID for this indicator
$("<div>Test</div>").click(handleHelloWorld), // Optional DOMNode for the indicator
true, // show the indicator
"hello-world-status", // CSS class
"tooltip", // tooltip text
);
```

→ The parameters of the `addIndicator()` method :-

| Param | Type | Description |
| --- | --- | --- |
| id | `string` | Registration id of the indicator to be updated. |
| [indicator] | `DOMNode` or `jQueryObject` | Optional DOMNode for the indicator |
| [visible] | `boolean` | Shows or hides the indicator over the statusbar. |
| [style] | `string` | Sets the attribute "class" of the indicator. |
| [tooltip] | `string` | Sets the attribute "title" of the indicator. |
| [insertBefore] | `string` | An id of an existing status bar indicator. The new indicator will be inserted before (i.e. to the left of) the indicator specified by this parameter. |

> For a detailed description, refer to [this link](https://docs.phcode.dev/api/API-Reference/widgets/StatusBar).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added api/08-Extension-Quick-Start/images/dialog.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading