Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Neste tutorial, você cria um componente de código deslizante linear que os usuários podem usar para alterar valores numéricos com um controle deslizante visual em vez de digitar os valores na coluna.
Você pode encontrar o código de exemplo para o componente de código do controle deslizante linear concluído no PowerApps-Samples/component-framework/LinearInputControl/.
Para criar um componente de código deslizante linear, conclua as seguintes etapas:
- Criar um novo projeto de componente
- Implementar o manifesto
- Implementar lógica de componente usando TypeScript
- Adicionar estilo aos componentes de código
- Criar componentes de código
- Empacotar seus componentes de código
- Adicionar seu componente de código a um aplicativo
Pré-requisitos
Para este tutorial, instale os seguintes componentes:
- Visual Studio Code (VSCode) (Verifique se a opção Adicionar ao PATH está selecionada)
- Node.js (a versão lts é recomendada)
- Microsoft Power Platform CLI (use o Power Platform Tools para Visual Studio Code ou Power Platform CLI para Windows)
- Ferramentas de build do .NET instalando uma das opções a seguir. No mínimo, selecione a carga de trabalho
.NET build tools:- Visual Studio 2022
- Visual Studio 2019
Observação
Talvez você prefira usar o SDK do .NET 6.x em vez das Ferramentas de Build para Visual Studio. Nesse caso, em vez de usar msbuild, use dotnet build.
Dica
Instale o Git para controle do código-fonte.
Criando um novo projeto de componente
Para este tutorial, comece em uma pasta localizada em C:\repos, mas você pode usar qualquer pasta desejada. Escolha uma pasta em que você deseja fazer o check-in do código.
Crie uma pasta chamada
LinearInput.Abra a pasta
LinearInputusando o Visual Studio Code.A maneira mais rápida de iniciar é usando uma janela de prompt de comando. Navegue até sua
LinearInputpasta e digitecode ..c:\repos\LinearInput>code .Esse comando abre seu projeto de componente no Visual Studio Code.
Abra um novo terminal dentro do Visual Studio Code usando Terminal ->Novo Terminal.
No prompt do terminal, crie um novo projeto de componente passando parâmetros básicos usando o comando pac pcf init .
pac pcf init --namespace SampleNamespace --name LinearInputControl --template field --run-npm-installO comando também executa o
npm installcomando para configurar as ferramentas de build do projeto.Running 'npm install' for you...Observação
Se você receber o erro
The term 'npm' is not recognized as the name of a cmdlet, function, script file, or operable program., instale node.js (a versão lts é recomendada) e todos os outros pré-requisitos.
Implementando o manifesto
O manifesto do controle é um arquivo XML que contém os metadados do componente de código. Ele também define o comportamento do componente de código. Neste tutorial, você criará esse arquivo de manifesto na LinearInputControl subpasta. Ao abrir o ControlManifest.Input.xml arquivo no Visual Studio Code, você verá que o arquivo de manifesto é predefinido com algumas propriedades. Para obter mais informações, consulte Manifesto.
O nó de controle define o namespace, a versão e o nome de exibição do componente de código.
A ferramenta gera o elemento de controle . Ele proporciona um bom ponto de partida para o seu controle.
Dica
Você pode achar o XML mais fácil de ler formatando-o para que os atributos apareçam em linhas separadas. Localize e instale uma ferramenta de formatação XML de sua escolha no Visual Studio Code Marketplace: pesquise extensões de formatação xml.
Os exemplos abaixo foram formatados com atributos em linhas separadas para facilitar a leitura.
| Attribute | Description |
|---|---|
namespace |
Namespace do componente de código. |
constructor |
Construtor do componente de código-fonte. |
version |
Versão do componente. Sempre que você atualizar o componente, atualize a versão para ver as alterações mais recentes no tempo de execução. |
display-name-key |
Nome do componente de código exibido na interface do usuário. |
description-key |
Descrição do componente de código exibido na interface do usuário. |
control-type |
O tipo de componente de código. Esse valor é um standard controle. |
Se você ignorar as áreas comentadas e formatar o documento, verá o manifesto que foi gerado para você:
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="SampleNamespace"
constructor="LinearInputControl"
version="0.0.1"
display-name-key="LinearInputControl"
description-key="LinearInputControl description"
control-type="standard">
<external-service-usage enabled="false">
</external-service-usage>
<property name="sampleProperty"
display-name-key="Property_Display_Key"
description-key="Property_Desc_Key"
of-type="SingleLine.Text"
usage="bound"
required="true" />
<resources>
<code path="index.ts"
order="1" />
</resources>
</control>
</manifest>
Neste ponto de partida, faça as seguintes alterações:
Adicionar elemento type-group
Adicione a definição de um elemento type-group nomeado numbers dentro do control elemento. Esse elemento especifica o valor do componente e pode conter valores inteiros, moeda, ponto flutuante ou decimal.
Substitua o external-service-usage elemento pelo type-group elemento, pois a external-service-usage funcionalidade não é usada por esse controle.
<control namespace="SampleNamespace"
constructor="LinearInputControl"
version="0.0.1"
display-name-key="LinearInputControl"
description-key="LinearInputControl description"
control-type="standard">
<external-service-usage enabled="false">
</external-service-usage>
<property name="sampleProperty"
display-name-key="Property_Display_Key"
description-key="Property_Desc_Key"
of-type="SingleLine.Text"
usage="bound"
required="true" />
<resources>
<code path="index.ts"
order="1" />
</resources>
</control>
Editar o elemento de propriedade
Edite o elemento sampleProperty gerado dentro do elemento . Esse elemento define as propriedades do componente de código, como o tipo de dados da coluna.
| Attribute | Description |
|---|---|
name |
Nome da propriedade. |
display-name-key |
Nome de exibição da propriedade que aparece na interface do usuário. |
description-key |
Descrição da propriedade que aparece na interface do usuário. |
of-type-group |
Use o of-type-group atributo para fazer referência ao nome de um grupo de tipos específico. Nesse caso, consulte o type-group denominado numbers que você criou na etapa anterior. |
usage |
Tem duas propriedades bound e input.- Propriedades vinculadas são vinculadas apenas ao valor da coluna. - As propriedades de entrada são associadas a uma coluna ou permitem um valor estático. |
required |
Define se a propriedade é necessária. |
Edite o nó da propriedade conforme mostrado no seguinte código:
<property name="sampleProperty"
display-name-key="Property_Display_Key"
description-key="Property_Desc_Key"
of-type="SingleLine.Text"
usage="bound"
required="true" />
Editar elemento de recursos
O nó de recursos define a visualização do componente de código. Ele contém todos os recursos que criam a visualização e o estilo do componente de código. O código é especificado como um elemento filho dentro do elemento resources.
O manifesto gerado já inclui uma definição do elemento de código com path e order valores de atributo definidos. Use esses valores. Na seção Adicionando estilo ao componente de código a seguir, você adiciona estilos CSS ao controle. Para dar suporte a essa etapa, edite o manifesto para adicionar enquanto ele estiver aberto.
Edite o nó de recursos para adicionar o seguinte elemento css:
Manifesto concluído
O arquivo de manifesto concluído deve ter esta aparência:
<?xml version="1.0" encoding="utf-8" ?>
<manifest>
<control namespace="SampleNamespace"
constructor="LinearInputControl"
version="0.0.1"
display-name-key="LinearInputControl"
description-key="LinearInputControl description"
control-type="standard">
<type-group name="numbers">
<type>Whole.None</type>
<type>Currency</type>
<type>FP</type>
<type>Decimal</type>
</type-group>
<property name="controlValue"
display-name-key="Control Value"
description-key="Control value description."
of-type-group="numbers"
usage="bound"
required="true" />
<resources>
<code path="index.ts"
order="1" />
<css path="css/LinearInputControl.css"
order="1" />
</resources>
</control>
</manifest>
Salve as alterações no arquivo
ControlManifest.Input.xml.Gere o arquivo
ManifestDesignTypes.d.tsusando o seguinte comando.npm run refreshTypesO resultado deve ser assim:
PS C:\repos\LinearInput> npm run refreshTypes > pcf-project@1.0.0 refreshTypes > pcf-scripts refreshTypes [12:38:06 PM] [refreshTypes] Initializing... [12:38:06 PM] [refreshTypes] Generating manifest types... [12:38:06 PM] [refreshTypes] Generating design types... [12:38:06 PM] [refreshTypes] SucceededPara ver os resultados, abra o
C:\repos\LinearInput\LinearInputControl\generated\ManifestTypes.d.tsarquivo para ver os tipos gerados:/* *This is auto generated from the ControlManifest.Input.xml file */ // Define IInputs and IOutputs Type. They should match with ControlManifest. export interface IInputs { controlValue: ComponentFramework.PropertyTypes.NumberProperty; } export interface IOutputs { controlValue?: number; }
Implementando a lógica do componente
Depois de implementar o arquivo de manifesto, implemente a lógica do componente usando TypeScript. Implemente a lógica do componente dentro do index.ts arquivo. Ao abrir o index.ts arquivo no Visual Studio Code, você verá que as quatro funções essenciais (init, updateView, getOutputs e destroy) são predefinidas. Agora, implemente a lógica para o componente de código.
Abra o index.ts arquivo no editor de código de sua escolha e faça as seguintes alterações:
- Adicionar propriedades para o controle
-
Adicionar a
refreshDatafunção como o manipulador de eventos -
Atualizar a
initfunção -
Editar a
updateViewfunção -
Editar a
getOutputsfunção -
Editar a
destroyfunção
Adicionar propriedades para o controle
export class LinearInputControl
implements ComponentFramework.StandardControl<IInputs, IOutputs>
{
/**
* Empty constructor.
*/
constructor() {}
Adicionar a refreshData função como o manipulador de eventos
public refreshData(evt: Event): void {
this._value = this.inputElement.value as any as number;
this.labelElement.innerHTML = this.inputElement.value;
this._notifyOutputChanged();
}
Atualizar a init função
public init(
context: ComponentFramework.Context<IInputs>,
notifyOutputChanged: () => void,
state: ComponentFramework.Dictionary,
container: HTMLDivElement
): void {
// Add control initialization code
}
Editar a updateView função
public updateView(context: ComponentFramework.Context<IInputs>): void {
// Add code to update control view
}
Editar a getOutputs função
Editar a destroy função
O arquivo completo index.ts deve ter esta aparência:
import { IInputs, IOutputs } from "./generated/ManifestTypes";
export class LinearInputControl
implements ComponentFramework.StandardControl<IInputs, IOutputs>
{
private _value: number;
private _notifyOutputChanged: () => void;
private labelElement: HTMLLabelElement;
private inputElement: HTMLInputElement;
private _container: HTMLDivElement;
private _context: ComponentFramework.Context<IInputs>;
private _refreshData: EventListenerOrEventListenerObject;
/**
* Empty constructor.
*/
constructor() {}
/**
* Used to initialize the control instance. Controls can kick off remote server calls
and other initialization actions here.
* Data-set values are not initialized here, use updateView.
* @param context The entire property bag available to control via Context Object;
It contains values as set up by the customizer mapped to property names defined
in the manifest, as well as utility functions.
* @param notifyOutputChanged A callback method to alert the framework that the
control has new outputs ready to be retrieved asynchronously.
* @param state A piece of data that persists in one session for a single user.
Can be set at any point in a controls life cycle by calling 'setControlState'
in the Mode interface.
* @param container If a control is marked control-type='standard', it will receive
an empty div element within which it can render its content.
*/
public init(
context: ComponentFramework.Context<IInputs>,
notifyOutputChanged: () => void,
state: ComponentFramework.Dictionary,
container: HTMLDivElement
): void {
// Add control initialization code
this._context = context;
this._container = document.createElement("div");
this._notifyOutputChanged = notifyOutputChanged;
this._refreshData = this.refreshData.bind(this);
// creating HTML elements for the input type range and binding it to the function which
// refreshes the control data
this.inputElement = document.createElement("input");
this.inputElement.setAttribute("type", "range");
this.inputElement.addEventListener("input", this._refreshData);
//setting the max and min values for the control.
this.inputElement.setAttribute("min", "1");
this.inputElement.setAttribute("max", "1000");
this.inputElement.setAttribute("class", "linearslider");
this.inputElement.setAttribute("id", "linearrangeinput");
// creating a HTML label element that shows the value that is set on the linear range control
this.labelElement = document.createElement("label");
this.labelElement.setAttribute("class", "LinearRangeLabel");
this.labelElement.setAttribute("id", "lrclabel");
// retrieving the latest value from the control and setting it to the HTMl elements.
this._value = context.parameters.controlValue.raw!;
this.inputElement.setAttribute(
"value",
context.parameters.controlValue.formatted
? context.parameters.controlValue.formatted
: "0"
);
this.labelElement.innerHTML = context.parameters.controlValue.formatted
? context.parameters.controlValue.formatted
: "0";
// appending the HTML elements to the control's HTML container element.
this._container.appendChild(this.inputElement);
this._container.appendChild(this.labelElement);
container.appendChild(this._container);
}
public refreshData(evt: Event): void {
this._value = this.inputElement.value as any as number;
this.labelElement.innerHTML = this.inputElement.value;
this._notifyOutputChanged();
}
/**
* Called when any value in the property bag has changed. This includes field values,
data-sets, global values such as container height and width, offline status, control
metadata values such as label, visible, etc.
* @param context The entire property bag available to control via Context Object;
It contains values as set up by the customizer mapped to names defined in the manifest,
as well as utility functions
*/
public updateView(context: ComponentFramework.Context<IInputs>): void {
// Add code to update control view
// storing the latest context from the control.
this._value = context.parameters.controlValue.raw!;
this._context = context;
this.inputElement.setAttribute(
"value",
context.parameters.controlValue.formatted
? context.parameters.controlValue.formatted
: ""
);
this.labelElement.innerHTML = context.parameters.controlValue.formatted
? context.parameters.controlValue.formatted
: "";
}
/**
* It is called by the framework prior to a control receiving new data.
* @returns an object based on nomenclature defined in manifest,
expecting object[s] for property marked as "bound" or "output"
*/
public getOutputs(): IOutputs {
return {
controlValue: this._value,
};
}
/**
* Called when the control is to be removed from the DOM tree.
Controls should use this call for cleanup.
* i.e. cancelling any pending remote calls, removing listeners, etc.
*/
public destroy(): void {
// Add code to cleanup control if necessary
this.inputElement.removeEventListener("input", this._refreshData);
}
}
Quando terminar, salve as alterações no index.ts arquivo.
Adicionando estilo ao componente de código
Desenvolvedores e criadores de aplicativos podem definir seu estilo para representar seus componentes de código visualmente usando CSS. O CSS permite que os desenvolvedores descrevam a apresentação de componentes de código, incluindo estilo, cores, layouts e fontes. O método de inicialização do componente de entrada linear cria um elemento de entrada e define o atributo de classe como linearslider. O estilo da linearslider classe é definido em um arquivo CSS separado. Você pode incluir recursos de componente adicionais, como arquivos CSS com o componente de código, para dar suporte a personalizações adicionais.
Importante
Ao implementar o estilo em seus componentes de código usando CSS, certifique-se de que o CSS está limitado ao seu controle, utilizando as classes CSS geradas automaticamente aplicadas ao elemento de contêiner DIV do componente.
Se o CSS tiver escopo global, ele provavelmente interromperá o estilo existente do formulário ou da tela em que o componente de código é renderizado.
Se você estiver usando uma estrutura CSS de terceiros, use uma versão dessa estrutura que já esteja com namespace ou envolva essa estrutura em um namespace manualmente ou usando um pré-processador CSS.
Crie uma nova
csssubpasta naLinearInputControlpasta.Crie um novo
LinearInputControl.cssarquivo dentro dacsssubpasta.Adicione o seguinte conteúdo de estilo ao
LinearInputControl.cssarquivo:.SampleNamespace\.LinearInputControl input[type=range].linearslider { margin: 1px 0; background:transparent; -webkit-appearance:none; width:100%;padding:0; height:24px; -webkit-tap-highlight-color:transparent } .SampleNamespace\.LinearInputControl input[type=range].linearslider:focus { outline: none; } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-webkit-slider-runnable-track { background: #666; height:2px; cursor:pointer } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-webkit-slider-thumb { background: #666; border:0 solid #f00; height:24px; width:10px; border-radius:48px; cursor:pointer; opacity:1; -webkit-appearance:none; margin-top:-12px } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-moz-range-track { background: #666; height:2px; cursor:pointer } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-moz-range-thumb { background: #666; border:0 solid #f00; height:24px; width:10px; border-radius:48px; cursor:pointer; opacity:1; -webkit-appearance:none; margin-top:-12px } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-ms-track { background: #666; height:2px; cursor:pointer } .SampleNamespace\.LinearInputControl input[type=range].linearslider::-ms-thumb { background: #666; border:0 solid #f00; height:24px; width:10px; border-radius:48px; cursor:pointer; opacity:1; -webkit-appearance:none; }Salve o arquivo
LinearInputControl.css.Observe que o
ControlManifest.Input.xmlarquivo já inclui ocssarquivo de recurso dentro do elemento de recursos porque essa etapa foi concluída na seção Implementando manifesto anteriormente.<resources> <code path="index.ts" order="1" /> <css path="css/LinearInputControl.css" order="1" /> </resources>
Observação
A estrutura de componentes do Power Apps usa recursos da Web RESX para gerenciar as cadeias de caracteres localizadas mostradas em qualquer interface do usuário. Os recursos para dar suporte à localização também são registrados no nó resources.
Este primeiro tutorial não inclui a funcionalidade de localização. A localização está incluída em outros tutoriais.
Para saber como localizar componentes de código usando resx recursos da Web, consulte o exemplo de API de Localização .
Construir componentes de código
Depois de concluir a adição do manifesto, da lógica do componente e do estilo, crie os componentes de código usando o seguinte comando:
npm run build
A saída deve ser semelhante ao seguinte resultado:
> pcf-project@1.0.0 build
> pcf-scripts build
[2:05:41 PM] [build] Initializing...
[2:05:41 PM] [build] Validating manifest...
[2:05:41 PM] [build] Validating control...
[2:05:42 PM] [build] Running ESLint...
[2:05:43 PM] [build] Generating manifest types...
[2:05:43 PM] [build] Generating design types...
[2:05:43 PM] [build] Compiling and bundling control...
[Webpack stats]:
asset bundle.js 6.56 KiB [emitted] (name: main)
./LinearInputControl/index.ts 4.9 KiB [built] [code generated]
webpack 5.75.0 compiled successfully in 2049 ms
[2:05:45 PM] [build] Generating build outputs...
[2:05:45 PM] [build] Succeeded
PS C:\repos\LinearInput\LinearInputcontrol>
O build gera um arquivo de declaração de tipo TypeScript atualizado na LinearInputControl/generated pasta.
O componente é compilado na out/controls/LinearInputControl pasta. Os artefatos do build incluem:
-
bundle.js– Código-fonte do componente empacotado. -
ControlManifest.xml– Arquivo de manifesto atual do componente que você carrega na organização do Microsoft Dataverse.
Observação
As regras de eslint podem afetar seu build, dependendo de como elas são configuradas. Se você receber um erro durante o build:
[12:58:30 PM] [build] Failed:
[pcf-1065] [Error] ESLint validation error:
C:\project\LinearInput\LinearInputControl\index.ts
10:26 error 'EventListenerOrEventListenerObject' is not defined no-undef
Verifique as regras de eslint em .eslintrc.json e defina as regras de lint como ["warn"]. Por exemplo, se você receber o erro:
error 'EventListenerOrEventListenerObject' is not defined no-undef
Em seguida, você pode abrir .eslintrc.json e editar as regras para adicionar um ["warn"] valor para a regra no-undef:
"rules": {
"no-unused-vars": "off",
"no-undef": ["warn"]
}
Depois de atualizar as regras de ESLint, seu controle deve ser compilado sem erros.
Depurar seu componente de código
Quando terminar de implementar a lógica do componente de código, execute o comando a seguir para iniciar o processo de depuração. Para mais informações, veja Depurar componentes de código.
npm start watch
A saída deve ser semelhante ao seguinte resultado:
> pcf-project@1.0.0 start
> pcf-scripts start "watch"
[2:09:10 PM] [start] [watch] Initializing...
[2:09:10 PM] [start] [watch] Validating manifest...
[2:09:10 PM] [start] [watch] Validating control...
[2:09:11 PM] [start] [watch] Generating manifest types...
[2:09:11 PM] [start] [watch] Generating design types...
[2:09:11 PM] [start] [watch] Compiling and bundling control...
[Webpack stats]:
asset bundle.js 6.56 KiB [emitted] (name: main)
./LinearInputControl/index.ts 4.9 KiB [built] [code generated]
webpack 5.75.0 compiled successfully in 2060 ms
[2:09:13 PM] [start] [watch] Generating build outputs...
[2:09:13 PM] [start] [watch] Starting control harness...
Starting control harness...
[Browsersync] Access URLs:
----------------------------
Local: http://localhost:8181
----------------------------
[Browsersync] Serving files from: C:\repos\LinearInput\out\controls\LinearInputControl
[Browsersync] Watching files...
Um navegador também é aberto na Área Restrita do Controle do PCF para que você possa ver o controle e testá-lo.
Empacotando seus componentes de código
Siga estas etapas para criar e importar um arquivo de solução :
Crie uma nova pasta chamada Soluções dentro da pasta LinearInputControl e vá para a nova pasta.
mkdir Solutions cd SolutionsCrie um novo projeto de solução na pasta LinearInputControl usando o comando pac solution init :
pac solution init --publisher-name Samples --publisher-prefix samplesObservação
Os valores publisher-name e publisher-prefix devem corresponder a um publicador de solução existente ou a um novo que você deseja criar em seu ambiente de destino.
Você pode recuperar uma lista de valores atuais executando esta consulta em seu ambiente de destino:
[Environment URI]/api/data/v9.2/publishers?$select=uniquename,customizationprefixPara obter mais informações, consulte Os dados de consulta usando a API Web.
A saída do comando pac solution init é semelhante a esta:
Dataverse solution project with name 'solutions' created successfully in: 'C:\repos\LinearInput\linearinputcontrol\solutions' Dataverse solution files were successfully created for this project in the sub-directory Other, using solution name solutions, publisher name Samples, and customization prefix samples. Please verify the publisher information and solution name found in the Solution.xml file. PS C:\repos\LinearInput\linearinputcontrol\solutions>Depois de criar o novo projeto de solução, adicione uma referência ao local do componente criado. Use o seguinte comando:
pac solution add-reference --path ..\..\Observação
O caminho que você fornece está relacionado à pasta soluções atual que você criou na pasta LinearInputControl . Você também pode fornecer um caminho absoluto.
A saída do comando será parecida com o seguinte:
Project reference successfully added to Dataverse solution project.Para gerar um arquivo zip do projeto de solução, quando estiver dentro do diretório do projeto de
cdsprojsolução, use o seguinte comando:msbuild /t:restoreOu, se você instalou o SDK do .NET 6, use:
dotnet buildExecute o seguinte comando novamente:
msbuildObservação
Se você receber o erro
Missing required tool: MSBuild.exe/dotnet.exe, adicioneMSBuild.exe/dotnet.exeà variável de ambiente Path ou useDeveloper Command Prompt for Visual Studio Code. Conforme mencionado em Pré-requisitos, você deve instalar ferramentas de build do .NET.Dica
Você verá a mensagem Não use a
evalfunção ou seus equivalentes funcionais ao criar o arquivo de solução usando omsbuildcomando e importá-lo para o Dataverse e executar o verificador de solução. Recompile o arquivo de solução usando o comandomsbuild/property:configuration=Release. Reimporte a solução no Dataverse e execute o verificador de solução. Para obter mais informações, consulte Depurar componentes de código.O arquivo zip da solução gerada está localizado na
Solution\bin\debugpasta.Importe manualmente a solução para o Dataverse usando o Power Apps quando o arquivo zip estiver pronto ou automaticamente usando as Ferramentas de Build do Microsoft Power Platform.
Observação
Publique manualmente as personalizações se você estiver importando a solução não gerenciada.
Adicionar seu componente de código a um aplicativo
Para adicionar um componente de código a um aplicativo, siga as etapas nestes artigos:
- Adicionar componentes a colunas e tabelas para aplicativos controlados por modelos
- Adicionar componentes de código a um aplicativo de tela
- Usar componentes de código em portais
Consulte também
Baixar componentes de exemplo
Conheça a estrutura de componentes do Power Apps
Visão geral das ferramentas e aplicativos usados com o ALM
Referência da API do Power Apps component framework
Visão geral do Power Apps component framework
Depurar componentes de código