DEV Community

Cover image for How to style a PCF like a standard Model Driven App control
Riccardo Gregori
Riccardo Gregori

Posted on

4

How to style a PCF like a standard Model Driven App control

After this article I had an interesting exchange with David Rivard on how to manually tweak the style of Fluent UI 9 controls to make it look like the standard, model-driven, ones.

In this post I will show the results of our try-and-errors, for future reference.

💥 The problem

By default, even if you implement a new Virtual PCF Control, the theme used by standard Model-Driven App controls differs from the one employed in Canvas Apps, and both, in turn, differ from the default theme of Fluent UI, used out of the box by the PCF controls.

Differences between standard theme and Canvas/Model Driven One

In the thread David suggested to apply the following attribute to my control:

  • appearance="filled-darker"

Effectively, that did the trick when the form is active, but not when the form/control is disabled 😠.

Active vs Inactive

💡 The solution

Stating from David suggestion, and after a lot of try-and-errors, I found the following workaround. I tested it with Input and Select controls, and it quite works.

🎨 Step 1 - Create a custom style

Using Fluent UI makeStyles function, create a custom style with the following content:

import { makeStyles } from '@fluentui/react-components';

const useStyles = makeStyles({
  filledDarker: {
    ...shorthands.borderStyle('solid'),
    ...shorthands.borderWidth('1px'),
    ...shorthands.borderColor(tokens.colorNeutralBackground1Hover),
    'border-radius': "4px !important",
    backgroundColor: tokens.colorNeutralBackground1Hover,
    color: tokens.colorNeutralForeground1 + " !important",
    cursor: 'default',
    minWidth: "50px",
    '> input': {
      ...shorthands.borderStyle('none'),
      color: tokens.colorNeutralForeground1 + " !important",
      cornerRadius: tokens.borderRadiusMedium,
      cursor: 'text',
    },
    '> select': {
      ...shorthands.borderStyle('none'),
      color: tokens.colorNeutralForeground1 + " !important",
      cursor: 'default',
    },
    '> span': {
      ...shorthands.borderStyle('none'),
      color: tokens.colorNeutralForeground1 + " !important",
      cornerRadius: tokens.borderRadiusMedium,
      cursor: 'default',
    }
  },
});
Enter fullscreen mode Exit fullscreen mode

📝 Step 2 - Apply the custom style to your control

Remember to apply both attributes:

  • className= to the style created above
  • appearance="filled-darker"
import * as React from 'react';
import { Input } from '@fluentui/react-components';

const MyComponent: React.FC = () => {

...

return (
    <Input 
      className={styles.filledDarker}
      appearance="filled-darker"
      ...
      />
  );
};
Enter fullscreen mode Exit fullscreen mode

🤔 Why does it "quite" works?

Standard controls, when disabled, have a nice dark-gray underline effect on focus:

Underline effect on disabled controls

I wasn't able to reproduce the same effect with my CSS.

🗨️ If you have any suggestion on how to make it work, drop a comment here! 💬

Heroku

Deploy with ease. Manage efficiently. Scale faster.

Leave the infrastructure headaches to us, while you focus on pushing boundaries, realizing your vision, and making a lasting impression on your users.

Get Started

Top comments (0)

Postmark Image

"Please fix this..."

Focus on creating stellar experiences without email headaches. Postmark's reliable API and detailed analytics make your transactional emails as polished as your product.

Start free

👋 Kindness is contagious

Engage with a wealth of insights in this thoughtful article, cherished by the supportive DEV Community. Coders of every background are encouraged to bring their perspectives and bolster our collective wisdom.

A sincere “thank you” often brightens someone’s day—share yours in the comments below!

On DEV, the act of sharing knowledge eases our journey and forges stronger community ties. Found value in this? A quick thank-you to the author can make a world of difference.

Okay