4x: How to style widgets in typescript?

1410
2
04-26-2017 09:09 AM
DirkVandervoort
Occasional Contributor II

The sample for building a widget is a fine start: Custom Recenter Widget | ArcGIS API for JavaScript 4.3 All the style information is inline, which is...well, inline.

Now I want to add dijits to my widget: comboboxes, buttons, stuff. Styling is pretty intense and best handled someplace other than inline. Also, the css is available via CDN from dojo and ArcGIS.

When I compile the TypeScript below and drop it into my map app, the styling is, well, primitive. (Sorry, no jsbin).

Any clues on how to start building more complex and styled widgets that I can add to my map apps would be greatly appreciated. TIA

THE RESULT:

HTML:

                var styledStuff = new StyledStuff({
                    title: "This is the styled stuff",
                    subtitle: "And this is the sub styled stuff"
                });
                view.ui.add(styledStuff, "top-right");

TYPESCRIPT:

/// <amd-dependency path="esri/core/tsSupport/declareExtendsHelper" name="__extends" />
/// <amd-dependency path="esri/core/tsSupport/decorateHelper" name="__decorate" />

import {subclass, declared, property} from "esri/core/accessorSupport/decorators";
import Widget = require("esri/widgets/Widget");
import Button = require("dijit/form/Button");
import ComboBox = require("dijit/form/ComboBox");
import Memory = require("dojo/store/Memory");

import on = require("dojo/on");
import dom = require("dojo/dom");
import req = require("dojo/require");

import { renderable, jsxFactory } from "esri/widgets/support/widget";

const CSS = {
    base: "styledstuff"
};
interface Style {
  textShadow: string;
}

@subclass("esri.widgets.MapTitle")
class StyledStuff extends declared(Widget) {

    //--------------------------------------------------------------------
    //
    //  Properties
    //
    //--------------------------------------------------------------------

    //----------------------------------
    //  title
    //----------------------------------
    @property()
    @renderable()
    title: string;

    //----------------------------------
    //  subtitle
    //----------------------------------
    @property()
    @renderable()
    subtitle: string;

    //----------------------------------
    //  button
    //----------------------------------
    @property()
    @renderable()
    button: Button;

    //-------------------------------------------------------------------
    //
    //  Public methods
    //
    //-------------------------------------------------------------------
    render() {
        const title = this._getTitle();
        const subtitle = this._getSubtitle();
        const button = this._getButton();
        const comboBox = this._getComboBox();
        return (


           <div
                bind={this}
                class={CSS.base}>
                <p id="title" class="title">{title}</p>
                <p id="subtitle" class="subtitle">{subtitle}</p>
                <p><span><div id="progButtonNode"></div></span></p>
                <p><span><div id="progComboBoxNode"></div></span></p>
            </div>

        );
    }

    //-------------------------------------------------------------------
    //
    //  Private methods
    //
    //-------------------------------------------------------------------

    private _getTitle() {
        return this.title;
    }

    private _getSubtitle() {
        return this.subtitle;
    }
    private _getButton() {
        var myButton = new Button({
            label: "Click this button, man!",
            onClick: function(){
                alert("Please and thank you, man! ");
            }
        }, "progButtonNode");
        return myButton;
    }
    private _getComboBox() {
            var stateStore = new Memory({
        data: [
            {name:"Alabama", id:"AL"},
            {name:"Alaska", id:"AK"},
            {name:"American Samoa", id:"AS"},
            {name:"Arizona", id:"AZ"},
            {name:"Arkansas", id:"AR"},
            {name:"Armed Forces Europe", id:"AE"},
            {name:"Armed Forces Pacific", id:"AP"},
            {name:"Armed Forces the Americas", id:"AA"},
            {name:"California", id:"CA"},
            {name:"Colorado", id:"CO"},
            {name:"Connecticut", id:"CT"},
            {name:"Delaware", id:"DE"}
        ]
    });
    var comboBox = new ComboBox({
        name: "state",
        value: "California",
        store: stateStore,
        searchAttr: "name"
    }, "progComboBoxNode").startup();
        return comboBox;
    }
}

export = StyledStuff;‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍
0 Kudos
2 Replies
ThomasSolow
Occasional Contributor III

My feeling is that you can probably just add classes/ids to your HTML elements and reference a separate CSS file in your index.html (or whatever the entrypoint to your page is) as in: <link rel="stylesheet" href="xxx.css"> 


If you want to organize things nicely, you could make a different CSS file for each widget.  You could also add a class or an id to your widget's outer-most element and ensure that only children of that element are being affected by the css in each <widget>.css file. 

0 Kudos
DirkVandervoort
Occasional Contributor II

Yep: better to not bake the css into the TypeScript. What was I thinking? If I get the base css from a CDN:

<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/dojo/1.10.4/dijit/themes/claro/claro.css">

and

<body class="claro">
<div id="viewDiv"></div>
</body>

this yields

which gets me closer to the styling I am after. Now I can host some local css to pretty up the dijits.

0 Kudos