Security News
38% of CISOs Fear They’re Not Moving Fast Enough on AI
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
@battery/core
Advanced tools
Battery is a system to generate infinite, composable, atomic styles that eliminates code bloat and automatically documents itself.
A configurable machine that turns classnames into CSS. (Documentation is in progress)
I started working on Battery in an effort to have a way of auto-generating documentation for a custom Atomic CSS library. That eventually grew into a much more interesting tool which had the potential for so much more than auto-generating docs.
There's some distance between what Battery is capable of now and what I want it to be capable of in the future, but I'm hoping to narrow that gap sooner rather than later. Here's a list of things it can currently do, followed by a list of features that I'd love to add or extend out of this project.
Current features:
Dream features:
This repo is the brain of Battery, but it's meant to be used in conjunction with other tools. The most fleshed out of those tools are
These are one of the two core aspects of Battery's configuration. Your propConfig
's will house the vast majority of your naming convention.
The following are some examples of propConfig
's and what Battery will output given class names that match those configs.
Note: Some of these examples include references to Plugins which are the other core aspect of Battery. Feel free to read through this section and gloss over the plugins part as we will be covering them in detail later (or if you can't way, jump ahead and checkout how Plugins work)
const textAlign = {
cssProperty: 'text-align',
propName: 'text',
values: {
separator: '-',
values: {
left: 'left',
center: 'center',
right: 'right'
}
}
}
const input = ['text-left','text-center','text-right']
.text-left { text-align: left; }
.text-center { text-align: center; }
.text-right { text-align: right; }
const position = {
cssProperty: 'position',
propName: '',
values: {
values: {
static: 'static',
relative: 'relative',
absolute: 'absolute',
fixed: 'fixed',
sticky: 'sticky'
}
}
}
const input = ['static', 'relative', 'absolute', 'fixed', 'sticky']
.static { position: static; }
.relative { position: relative; }
.absolute { position: absolute; }
.fixed { position: fixed; }
.sticky { position: sticky; }
const zIndex = {
propName: 'z',
cssProperty: 'z-index',
enablePlugin: 'integers'
}
const input = ['z1', 'z20', 'z-10', 'z-999']
.z1 { z-index: 1; }
.z20 { z-index: 20; }
.z-10 { z-index: -10; }
.z-999 { z-index: -999; }
const backgroundColor = {
cssProperty: 'background-color',
propName: 'bg',
separator: '-',
values: {
separator: '-',
values: {
transparent: 'transparent'
}
},
enablePlugin: 'colors'
}
const input = ['bg-red', 'bg-green', 'bg-blue', 'bg-transparent']
.bg-red { background-color: #FF0000; }
.bg-green { background-color: #00FF00; }
.bg-blue { background-color: #0000FF; }
.bg-transparent { background-color: transparent; }
prop
: string (required)This sets which CSS property being configured by the object. This will be the property
part of the CSS declaration in the final atomic class.
propName
: stringThis sets the identifier in the classname to tell Battery which property the class is targeting.
propSeparator
: stringThis sets the separator between the propName
and the value
identifiers in the class.
values
: objectThis object allows you to manually set up values for your property
. This can be used for keyword
values as determined by the CSS spec, or it can be used when you can't easily create a plugin to handle generating these values.
Example
const alignItems = {
cssProperty: 'align-items',
propName: 'items',
values: {
separator: '-',
values: {
'start': 'flex-start',
'center': 'center',
'end': 'flex-end'
}
}
const input = [
'items-start',
'items-center',
'items-end'
]
.items-start { align-items: flex-start }
.items-center { align-items: center }
.items-end { align-items: flex-end }
values
: objectThe keys in this object set the indicator on the class and the value sets the value
for the CSS declaration to be paired with the property
set by the prop
on the root propConfig
separator
: stringThis sets the separator between the propName
and the value
identifiers in the class. Note: You can optionally rely on the propSeparator
if you want all of your values
to be separated using the same separator.
enablePlugin
: stringThis allows your classnames to take a predefined set of values based on a plugin in your config. The string in this section must match the configured name
of a plugin in your Battery Config.
pluginDefault
: booleanA propConfig
can to be set as the pluginDefault
. This allows Battery to determine which property
to set when it can't find a propName
. As the example below shows, this can be useful in the case of something like text-color
if you prefer not to have an indicator like text
to denote what the color is being applied to.
const color = {
cssProperty: 'color',
propName: '',
values: {
values: { transparent: 'transparent' }
},
pluginDefault: true,
enablePlugin: 'colors'
}
const input = ['red', 'green', 'blue', 'transparent']
.red { color: #FF0000; }
.green { color: #00FF00; }
.blue { color: #0000FF; }
.transparent { color: transparent; }
allowedValues
| disallowedValues :
string[]`These two options let you put constraints on a propConfig
to disallow some or most values from generating classes.
An example of where this can be useful is with a color plugin. This plugin could contain a lot of different colors, but not all of them should be used for all properties that accept a color value. If there are colors that you have determined should not be used for text due to legibility issues, you can add an array of disallowedValues
to your propConfig
so that Battery will filter those out before it generates the final list of classes
The allowedValues
option could be leveraged in the case where you only want to allow a small number of values from a plugin. A good example of this is plugin that outputs hard pixel values. These values are often used to magically position or size something. Using the following, you could limit the possible values to just a tiny subset for a property: allowedValues: [1px, 2px, 3px]
Plugins allow you to interpret various kinds of patterns in your classnames and output the desired CSS from matching with those patterns.
Value plugins are used to convert parts of a classname into the value of a CSS declaration.
pattern
This type of value plugin is designed to take a regex and will search the value section of the classname for a match. The matching value can the be outputted directly or processed before being set as the value in the atomic class.
Example plugin: Integers
const integersPlugin = {
name: 'integers',
type: 'pattern',
valueRegexString: '-?[0-9]{1,4}'
};
const flexShrink = {
cssProperty: 'flex-shrink',
propName: 'shrink',
enablePlugin: 'integers'
};
const input = ['shrink2', 'shrink-1'];
.shrink2 { flex-shrink: 2; }
.shrink-1 { flex-shrink: -1; }
Example plugin: Length Units
const lengthUnitsPlugin = {
name: 'lengthUnits',
type: 'pattern',
valueRegexString: '-?[0-9]{1,4}',
valueModifiers: [
{
name: 'percent',
indicator: 'p',
modifierFn: (value) => `${value}%`,
sampleValues: ['20', '50', '100', '-10', '66']
},
{
name: 'pixel',
indicator: 'px',
modifierFn: modifierFn: (value) => `${value/16}rem`,
sampleValues: ['1', '2', '3', '-2', '-5']
}
]
}
const width = {
cssProperty: 'width',
propName: 'w',
enablePlugin: 'lengthUnits'
}
const positionTop = {
cssProperty: 'top',
propName: 't',
enablePlugin: 'lengthUnits'
}
const fontSize = {
cssProperty: 'font-size',
propName: 'f-size',
propSeparator: '-'
enablePlugin: 'lengthUnits'
}
const input = ['t10px','t-25p','w50p','f-size-16px']
.t10px { top: 0.625rem }
.t-25p { top: -25% }
.w50p { width: 50% }
.f-size-16px { font-size: 1rem; }
Note: There are certain configuration options that are only available or necessary for specific plugin type
's
name
: stringThis sets a unique name so that you can enable a specific plugin inside of a propConfig
type
: stringThis give Battery an indication of how and when it needs to process a given part of a classname. The following are the accepted strings for plugin types.
pattern
lookup
classname
atrule
class
valueRegexString
: stringThis is a regex in the form of a string which is used to find valid matches in a classname's value portion. This matched value can be passed to a value modifier to process the value before it finally gets set as part of the declaration
valueModifiers
: object[]The value modifier array can contain a set of what are essentially sub plugins. These are used to transform a value based on a modifier on the end of that value.
These plugins allow you to modify the selector of a given atomic class. This can be used for everything from adding psuedo selectors like :focus
and :hover
, to creating a hover target pattern or something more complex.
Battery is intented to be used for more than generation. Your configs can also contain documentation. The following are all options that are used in the Battery Docs App.
propGroup
: stringThis groups certain properties under one heading so they can be found together in the Docs UI.
FAQs
Battery is a system to generate infinite, composable, atomic styles that eliminates code bloat and automatically documents itself.
We found that @battery/core demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 2 open source maintainers collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
CISOs are racing to adopt AI for cybersecurity, but hurdles in budgets and governance may leave some falling behind in the fight against cyber threats.
Research
Security News
Socket researchers uncovered a backdoored typosquat of BoltDB in the Go ecosystem, exploiting Go Module Proxy caching to persist undetected for years.
Security News
Company News
Socket is joining TC54 to help develop standards for software supply chain security, contributing to the evolution of SBOMs, CycloneDX, and Package URL specifications.