Tic Tac Toe - private components
A "web component" in Active CSS refers to a block of re-usable code containing its own HTML, optionally its own events, and optionally its own private variables.
Components can have private variable areas. You can have multiple non-private nested components all within a top-level private component and all the Active CSS variables can be shared within.
Assigning event scopes and variable scopes to a DOM area aligns with the web page object-oriented structure, and perhaps for web component variables makes more sense than other framework approaches, as other frameworks tend to scope variables per function. In our experience scoping per function for a large codebase can lead to confusion and complexity, unless you wrap all your functions in a wrapping container and set your shared variables in that scope, outside of the private functions. So that's what we've done here. You could call the outer private component in Active CSS the "wrapping function".
Events in a component always just apply to the component, so you can avoid using unnecessary IDs and classes in selectors to handle DOM manipulation by keeping the events inside the component. There is also a slight speed increase to using events in components, as the core only has to iterate over the component events, and it can ignore the rest of the page events.
In regular Active CSS config without components, the variable scope is the document itself. Variables are freely shared around the top-level config - they are in the document scope.
In a component, you can scope variables to the component with the "private" parameter when declaring the component. So variables are privately scoped to the component, and any non-private components beneath it in the element tree.
There are two methods for building private components in Active CSS.
First method: attach private component to a host element as a separate shadow DOM tree - see the Tic Tac Toe - shadow DOM components example to see how to do that. Variables and event selectors are limited to the component itself, and event bubbling follows the rules of event bubbling for shadow DOMs. This method aligns with the proposed native solution for web components, but limits you to component CSS because styles are not inherited through the document stylesheet.
Second method: attach component to a host element in the regular DOM tree. This allows you to keep your CSS in a regular stylesheet or a separate file. Variables and event selectors are limited to the component itself, although event bubbling does occur. You just need to make sure you use sensible names for your styling classes, so there is no chance of clashing CSS class names if you plan to re-use the component CSS in multiple websites, which is just common sense anyway. Variable names can be anything though - they are limited in scope to the component.
So this second method above is possibly a more practical option right now, as isolated CSS may not be something that you want, and shadow DOM support may not be universal enough yet.
Both methods are very easy to use, and they are not very different in implementation.
This second method is implemented in your config in mostly the same way as the shadow DOM method, except you use the word "private" instead of "shadow" as a parameter in the @component line. That is the only difference in implementation.
So here then is an example of the second method that has private events and variables, but does not use a shadow DOM.
Tic Tac Toe with human-like opponent
RUN IN FULL SCREEN MODE - START BY CLICKING ON A SQUARE