Mapear componentes para códigos existentes

Os desenvolvedores podem personalizar o processo de geração de código fornecendo um mapeamento entre um pacote da IU e um componente de código existente em vez do código gerado. Isso é benéfico quando a implementação atual tem recursos que não podem ser obtidos pelo código gerado, como animação ou comportamento complexo (como um menu suspenso).

Os desenvolvedores especificam como mapear componentes usando um arquivo de mapeamento. Um arquivo de mapeamento informa ao gerador de código, no mínimo, como alcançar a função de composição desejada para que o código de cliente correto possa ser criado.

Diagrama da visão geral do componente mapeado

Veja um exemplo:

No Figma, um designer cria um componente Card que contém uma instância de um componente Play Bar, empacota os dois e os envia a um desenvolvedor.

Quando o desenvolvedor importa os pacotes de IU do Figma, dois diretórios são criados em ui-packages: card e play_bar. Ao criar o projeto, duas funções de composição são criadas: Card e PlayBar. Normalmente, como Card contém uma instância de Play Bar no Figma, no código a função de composição Card contém uma chamada para o elemento de composição PlayBar.

No entanto, o designer e o desenvolvedor querem que o Card use um elemento de composição, o MyExistingPlaybar, que tem uma funcionalidade difícil de descrever no Figma. Portanto, o desenvolvedor adiciona um arquivo de mapeamento chamado play_bar.map que mapeia o pacote de IU do play_bar para MyExistingPlaybar:

{
    "target": "MyExistingPlaybar",
    "package": "com.example.myApp"
}

Agora, quando o desenvolvedor cria o projeto, o Card chama MyExistingPlaybar, em vez de PlayBar. Observe que MyExistingPlaybar precisa ter os mesmos parâmetros que PlayBar, embora possa haver algumas diferenças, conforme descrito em Diretivas adicionais abaixo.

Arquivo de mapeamento

Nos projetos do Android Studio, os arquivos de mapeamento são adicionados em ui-package-resources/mappings ao lado da pasta ui-packages. O Relay vai buscar os arquivos de mapeamento durante a criação.

Como mapear arquivos na visualização do projeto

O nome de um determinado arquivo de mapeamento precisa corresponder ao nome da pasta do pacote de IU para o componente substituído. Portanto, o play_bar.map mapeia o pacote da IU na pasta ui-packages/play_bar para um componente de código.

Variantes mapeadas

Se um componente do Figma tiver variantes, o elemento gerado vai ter parâmetros de tipo enumerado que codificam a variante. Isso foi descrito no tutorial Como processar variantes de design. Se você quiser mapear um componente do Figma com variantes para um código existente, ele precisa ser mapeado para um elemento de composição que use os mesmos parâmetros que o elemento gerado, exceto que o parâmetro de tipo enumerado é substituído por um parâmetro de string chamado design. Por exemplo, suponha que há um componente do Figma chamado Chip com uma variante que tem a propriedade ChipType. A assinatura do elemento gerado pelo Chip vai ter esta aparência:

@Composable
fun Chip(
    modifier: Modifier = Modifier,
    chipType: ChipType = ChipType.Red,
    chipText: String
) { ... }

Se você quiser que o componente Chip do Figma seja mapeado para um MyChip de composição existente, a assinatura de MyChip vai precisar ser especificada desta forma, supondo que nenhum outras diretivas especificadas:

@Composable
fun MyChip
    modifier: Modifier = Modifier,
    design: String = "ChipType=Red",  // See note below
    chipText: String
) { ... }

Conceitualmente, isso sugere que o componente de código existente é capaz de ter as mesmas variantes de design que o componente do Figma.

Outras diretivas

Suponha a função de composição que queremos segmentar como a seguinte assinatura:

@Composable
fun MyChip(
    modifier: Modifier = Modifier,
    design: String = "ChipType=Red",
    description: String  // instead of chipText
) { ... }

Podemos adicionar um bloco fieldMappings que afeta o mapeamento dos parâmetros. Nesse caso, ele contém um mapeamento do parâmetro chipText no Chip para o parâmetro description em MyChip.

{
    "target": "MyChip",
    "package": "com.example.myApp",
    "fieldMappings": [
        {
            "type": "parameter",
            "source": "chipText",
            "target": "description"
        }
    ]
}

Os tipos para o bloco fieldMappings incluem:

  • type: parameter mapeia um campo do pacote da IU para um parâmetro de código.
    • source: nome do parâmetro conforme especificado no pacote da IU.
    • target: nome do parâmetro conforme especificado no componente do código de destino.
  • type: lambda mapeia um campo do pacote da IU para uma lambda de conteúdo.
    • source: nome do parâmetro conforme especificado no pacote da IU.
    • target: nome do parâmetro conforme especificado no componente do código de destino.
  • type: modifier mapeia um campo de pacote da IU para um método modificador. Observação: esse tipo de mapeamento está sendo concebido, principalmente o processamento de escopos do receptor.
    • source: nome do parâmetro conforme especificado no pacote da IU.
    • method: método no objeto modificador que precisa ser invocado no código gerado.
    • parameter: nome do parâmetro no método modificador especificado.
    • library: o nome do pacote qualificado a ser importado para acessar o método modificador.
    • scope: um dos dois valores para indicar o escopo do modificador:
    • any: o modificador pode ser usado em qualquer escopo de receptor.
    • relay: o modificador precisa ser usado no escopo do receptor do objeto RelayContainer do Relay.

Veja também