Categories
Introduction
Categories can be used to organize similar states into one group (such as a button's Pressed and Unpressed states).
A category can contain one or more states. States within a category have special behavior:
If one state in a category explicitly sets a variable (such as X), then all other states in that category will also explicitly set the variable.
Each category can be set individually on an instance of a component or standard element. In other words, if a component has two categories, each category can be assigned to a state within that category independently.
Creating Categories
To create a new category:
Select a Screen, Component, or Standard element which should contain the new category
Right-click in the States tab in an empty space
Select the Add Category item\

Right click Add Category item Enter a name for the new category
After the new category is created it appears in the States tab as a folder.

Adding States to a Category
To add states to a category:
Right-click on the desired category
Select Add State\

Right click Add State item Enter a name for the new state
Once the state has been created it can be selected and variables can be changed to add them to the new state.
Categories Create Variables
Once a category is created, the screen, component, or standard element which contains the category is automatically given a variable for that category type. This variable can be assigned on the element itself or on instances of the element.
For example, consider a component with a category named ExampleCategory with two states: State1 and State2.

This component is given a variable named Example Category State.

This value can be assigned in the default state, making the selected state automatically set by default on the component.
For example, the DefaultComponent can select State1 as its Example Category State.

Doing so results in this value automatically being selected on new instances of the DefaultComponent.
States Set by Other States
Once a category is created, it adds a variable to the component. This variable behaves like any other variable including being able to be set by other states.
For example, consider a component with the following categories and states:
ColorCategory
Bright
Dark
SizeCategory
Big
Small
These states can be combined in a new category. For example, a category called CombinedCategory can be created which can include states such as BrightBig or DarkSmall which in turn sets category variables.

Explicit Values Across States in a Category
Normally, when a new category is created and new states are added, all states are empty - they do not assign any variables. The value displayed in the properties window is inherited from the default state.
For example, the following image shows a component with a state called State1 with no variables explicitly assigned. Notice all values are green:

As mentioned in the introduction, if a variable is explicitly set on one state in a category, then all other states in that category will that same variable set to its default. For example, if we set the X variable in the LeftSide state, the X variable in the RightSide state will become explicitly set (black instead of green).

Once the X variable is set on one state in a category, all other states in the same category will automatically have this value set - even new states:

Removing Variables from Categories
Variables can be removed from states, but this removal must be done at the category level rather than at the individual state. Doing so will remove all variables from all states within a category. To remove a variable in all states in a category:
Select the category itself (not the state)
Click the "X" button next to the variable
Confirm that you would like to remove the variable. Warning: this will remove the variable from all contained states.

This will remove the assignment of the variable from all states in the category.
GUM0002: Variable Reference Conflicts With Explicit Set
When a categorized state's VariableReferences row implies a value for a variable, and a parent element also has an explicit local value for the same variable, the explicit local value wins at lookup time. The reference is silently ineffective. Gum surfaces this with warning code GUM0002.
Example
UpgradeButton derives from Button. The author sets two things on UpgradeButton.DefaultState:
TextInstance.TextCategoryState = "Title"(the Title state on the inherited Label includes a VariableReference that resolvesFontSizeto e.g. 28).TextInstance.FontSize = 14(a plain explicit override).
These conflict. At lookup time, Gum walks the local explicit value first and returns 14. Changing TextCategoryState between values appears to do nothing for FontSize because the local override always wins.
How it got there
Most commonly: the author set FontSize interactively via a reference that has since been undone or changed, leaving the materialized scalar behind as an orphan. Hand edits and AI-authored XML can also produce this shape.
Fixing it
Decide which value you want and remove the other:
To let the state's reference drive
FontSize, delete the local explicitTextInstance.FontSizefrom the parent element's state.To keep the local explicit value, change or remove the reference inside the categorized state — or pick a
TextCategoryStatewhose effective value matches what you want.
Detection scope
The check fires for two cases, on every state of every Screen and Component:
A
VariableReferencesrow authored on the same state as a conflicting explicit scalar.A
VariableReferencesrow inherited via an active categorized-state assignment on an instance (theUpgradeButtonshape).
StandardElements are skipped — their references commonly evaluate to default values whose missing materialization is the correct on-disk state, not a conflict.
GUM0003: Category State Sets Its Own Category Selector
A category's selector variable (e.g. TextBoxCategoryState for the TextBoxCategory category) chooses which state in that category is active. When a state inside the category sets that same selector, the result is circular: applying the state re-drives the whole category, which re-applies a (possibly different) state and discards the original state's authored values. Gum surfaces this with warning code GUM0003.
Example
TextBox has a TextBoxCategory with states Enabled, Disabled, Highlighted, and Focused. The Focused state sets Border.ColorCategoryState = "Primary" (the normal cascade onto a child instance) — but it also sets TextBoxCategoryState = "Enabled". Selecting Focused immediately re-applies Enabled, so the border never shows the Focused colors.
How it got there
This is not normally hand-authored. It is usually materialized data: a tool pass that drives a category selector from a Forms property (for design-time preview) wrote the selector into whichever state was selected at the time, including the category's own states. The applier no longer does this — it only materializes into the default state — but projects edited before that fix can carry the orphaned assignments.
Fixing it
Remove the self-referential selector variable from the category's states. The selector belongs only on the default (uncategorized) state, where it picks the element's resting state; it should never appear inside the category it selects.
Detection scope
The check fires on every Screen and Component, for any state inside a category that sets that same category's selector. A state setting a child instance's selector (e.g. Border.ColorCategoryState, which carries a source object) is the intended cascade and is not flagged.
Last updated
Was this helpful?

