Skip to content

Component API guidelines

Callum Smith edited this page Apr 16, 2019 · 3 revisions

Input names

Do:

// Inputs should declare a type and initialize to some sane default value
@Input() items: Array<Object> = []; 
// string options should declare a union of all possible options
// and initialize to a default option
@Input() type: "single" | "multi" = "single"; 
// Inputs should prefer short, clear, names since their function should be
// obvious given the component they are attached to. 
// If not the component should be refactored.
@Input() open = false;
@Input() title = "";

Don't:

// what's the type? what's the default?
@Input() items;
// what possible options can we pass in?
@Input() type = "single";
// descriptive is good, however this is a sign the component may need 
// to be refactored, or broken down into composable sub-components.
@Input() isMenuOpen: boolean = false;

Item lists

Do:

@Input() items = [
    {
        content: "content here",
        // only for selectable item lists
        selected: false,
        // false or not including the property is the same behaviour
        disabled: false
        // other properties can be included. 
        // if there is a template the whole object should be passed to it.
    },
    {
        content: "more content",
        selected: true
    }
];

Don't:

@Input() myComponentItems = [
    "content",
    "more content"
];
@Input() alsoWrong = {
    item1: {}
    item2: {}
};

Nested item lists

Do:

@Input() items = [
    {
        content: "content here",
        // only for selectable item lists
        selected: false,
        // false or not including the property is the same behaviour
        disabled: false
        // other properties can be included. 
        // if there is a template the whole object should be passed to it.
    },
    {
        content: "more content",
        selected: true,
        // nested item lists follow the exact same conventions as
        // regular item lists however, they live within some parent item.
        items: [
            {
                content: "nested item",
                selected: false
            }
        ]
    }
];

Don't:

@Input() myComponentItems = [
    "content",
    "more content",
    [
        "something else"
    ]
];
@Input() alsoWrong = {
    item1: {
        subItems: {}
    }
    item2: {}
};

Component structure

Do:

@Component({
    // the component selector should be a kebab case translation of the
    // component class name prefixed with "ibm"
    selector: "ibm-foo",
    // templates should be inlined using ES6 template strings.
    // if the template grows too large, the component should
    // be refactored and/or split up. external html templates should
    // NOT be used.
    template: `
        <p>My Component</p>`,
    // styles should not be needed as styling will come from carbon-components,
    // however, in the rare case  that additional styling is required 
    // inline styles via the `styles` array may be used.
    styles: [
        `
        .foo
            color: blue;
        }
    ]
})
// the exported class should NOT be prefixed, or suffixed with Component
export class Foo {
    //...
}

Don't:

@Component({
    // should be a translation of the component class
    // should be prefixed with "ibm"
    selector: "some-component",
    // should be an inline template string
    templateUrl: "./my-component.component.html"
})
// the exported class should NOT be prefixed, or suffixed with Component
export class IBMFooComponent {
    //...
}