@axel669/windstorm
v0.5.0
Published
Windstorm is a library that allows element customization without needing to use css directly and without predefining hundreds or thousands of css classes with minor differences between a set of 20.
Downloads
336
Readme
Windstorm
Windstorm is a library that allows element customization without needing to use css directly and without predefining hundreds or thousands of css classes with minor differences between a set of 20.
Installation
Note: the version number is not necessary in the url, but is recommended. Including the version ensures that if updates are made to the library, any compatibility issues or bugs that get introduced won't affect existing pages, and also allows updates to be done when intended.
CDN Link (global variable)
<script src="https://esm.sh/@axel669/[email protected]/dist/browser.js?raw"></script>
CDN Link (module)
// Only scanning, no functions
import "https://esm.sh/@axel669/[email protected]"
// Import functions + scanning
import ws from "https://esm.sh/@axel669/[email protected]"
ws.x({...stuff})
Node Modules
npm add @axel669/windstorm
Usage
Windstorm can be used as a standalone script added to the page, or included in a bundle with other scripts/frameworks. Regardless of which form it's used in, windstorm should be included in the body of the page before the content that it will style in order to prevent FOUC. For static content, this means the script tag that uses it should not be async or defered. For content generated by a framework like React or Svelte, this should not be an issue as including windstorm in the build bundle will allow it to run before the framework adds DOM elements to the page.
Once added to the page, windstorm will scan all current elements, and any
elements added later for the ws-x
attribute, and generate the necessary css
immediately. Component css is automatically added to the head as well, so no
extra work is needed to use any of the components. Components that transform
standard tags will only work if the tag has the ws-x
on it (although the value
can be empty).
Many of the windstorm components expect some css variables defined by the theme to be present, so a theme should always be applied to the body.
<body ws-x="@@theme:tron">
<script src="https://esm.sh/@axel669/[email protected]/dist/browser.js?raw"></script>
Static content here
</body>
Any html elements that do not have the
ws-x
attribute are left alone, allowing windstorm to play nice with any other css lib (that I tried).
Macros and Markers
Information about how macros work and how to create them is on the Macros and Markers page.
ws-x Attribute
The ws-x
attribute is what windstorm will scan to apply styles to elements.
The attribute can have any number of macros and markers defined.
- Macro format:
[(<size>|)?<name>(:<states>)? (arg string)?]
- Marker format:
@@<marker>(:arg)?
Macros will apply specific styles and variables to whatever element they are defined on and are used to customize individual elements in specific ways. Custom macros can be defined, and are covered in the Macros and Markers documentation.
The states
for a macro are css states for controlling conditionally applied
styles (ex: :hover
). The size
modifier for a macro will make it apply styles
when certain screen size/orientation conditions are met.
| Size | Screen State | | --- | --- | | sm | width <= 600px | | md | width <= 1024px | | lg | width >= 1025px | | lnd | orientation: landscape | | prt | orientation: portrait |
Markers are bits of css that change how an element is presented in a large way (themes, making links appear as buttons, etc). Markers don't get processed by the macro system, so they can be made using standard css syntax.
<div ws-x="[@color teal] [w 100px]">
content
<!-- Regular border will use the --primary variable for color -->
<!-- border-color is changed on hover only to use the --color variable -->
<div ws-x="[b 1px solid @primary] [b.c:hover @color]">
other content
</div>
</div>
@app and ws-screen
The ws-screen component is designed to be a top level container for content that has consistent scrolling behavior for child elements across browsers and devices without the page resizing in weird ways from the various browser bars hiding and unhiding themselves from scrolling on mobile.
As such, the use of ws-screen is entirely optional as all components will work without it being used, and if the regular browser scrolling behavior is not an issue, then ws-screen can be skipped entirely.
If ws-screen is used, the body tag must have the @app
marker added to the ws-x
attribute. This will setup the css properties needed for ws-screen to control
the scrolling behavior more effectively.
<!-- Using ws-screen -->
<body ws-x="@@theme:tron @@app">
<script src="<windstorm>"></script>
<ws-screen>
<ws-paper ws-x="[$outline]">
<ws-flex>
<button ws-x="[$fill] [$color primary] [r 8px]">
Click Me!
</button>
<div ws-x="[w 100px] [h 200px] [bg.c teal]"></div>
</ws-flex>
</ws-paper>
</ws-screen>
</body>
<!-- Normal pages work fine -->
<body ws-x="@@theme:tron">
<script src="<windstorm>"></script>
<ws-paper ws-x="[$outline]">
<ws-flex>
<button ws-x="[$fill] [$color primary] [r 8px]">
Click Me!
</button>
<div ws-x="[w 100px] [h 200px] [bg.c teal]"></div>
</ws-flex>
</ws-paper>
</body>
API
Windstorm has a few utility functions for making dynamic ws-x declarations easier, and making custom functions simpler.
x(object)
The x
function takes in an object where each [key, value]
pair will be
converted into a valid string for the ws-x
attribute, including formatting
markers correctly. The value can take one of a few forms, and which form it takes
will affect the output:
- A string that will be used as the arg string
[key, value] -> "[key value]"
,[@@key, value] -> "@@key:value"
true
(boolean) will output the function without an arg string[key, true] -> "[key]"
,[@@key, true] -> "@@key"
null
,false
, orundefined
will output nothing, useful for making something that is toggled or catching when something isn't defined.[key, value] -> ""
// returns "@@button [$outline] [r 4px] [b 1px solid @main-color] [@var 10px]"
ws.x({
"@@button": true,
$outline: true,
r: "4px",
hide: false,
b: "1px solid @main-color",
"@var": "10px",
})