API
AtomicStyle
API reference for the AtomicStyle type
type AtomicStyle<T>;
export type { AtomicStyle };AtomicStyle is the type of one style that came out of css.create. Its type argument can be written either way: the rule the style was created from, or the atomic class names the style holds. Both resolve to the same type, so a prop names the rule, which is the short form.
Where StyleProps and WithoutProperties say which properties a prop accepts, AtomicStyle says which properties a style has to set, down to the value it sets them to.
Requiring a property
import * as css from '@plumeria/core';
const styles = css.create({
tinted: { color: 'red' },
padded: { color: 'red', padding: 8 },
pinned: { position: 'absolute' },
});
type NeedsColor = css.AtomicStyle<{ color: string }>;
const a: NeedsColor = styles.tinted; // ok
const b: NeedsColor = styles.padded; // ok, setting more is allowed
const c: NeedsColor = styles.pinned; // Type error, no color is setThe type argument names what has to be there. Anything the style sets beyond it is accepted.
Reading a class name off the prop
Requiring a property is what makes it readable. A prop typed with Style is a list, so there is nothing to index; a prop typed with AtomicStyle hands the component the atomic class name for the property it named:
function Glyph({ glyphStyle }: { glyphStyle: css.AtomicStyle<{ color: string }> }) {
return <svg fill="currentColor" className={glyphStyle.color} />;
}
<Glyph glyphStyle={styles.tinted} /> // ok
<Glyph glyphStyle={styles.padded} /> // Type error, there is no color to readA nested block is read the same way:
function Hover({ s }: { s: css.AtomicStyle<{ ':hover': { color: string } }> }) {
return <span className={s[':hover'].color} />;
}Pinning a value
Because an atomic class name carries the value it was generated for, a literal in the type argument holds the style to it:
const layouts = css.create({
flex: { display: 'flex' },
grid: { display: 'grid' },
});
type MustBeFlex = css.AtomicStyle<{ display: 'flex' }>;
const a: MustBeFlex = layouts.flex; // ok
const b: MustBeFlex = layouts.grid; // Type error, display is gridWhat a created style shows
A created style is that map of class names, and an editor shows it as one:
const styles = css.create({
header: { padding: '6px 12px', color: 'red' },
});
// styles.header
Readonly<{
padding: css.AtomicClassNameFor<'padding', '6px 12px'>;
color: css.AtomicClassNameFor<'color', 'red'>;
}>styles.header.padding is the class name generated for padding: 6px 12px rather than the string '6px 12px', and the hover says which. Naming the rule describes the same type:
type Header = css.AtomicStyle<{ padding: '6px 12px'; color: 'red' }>;
const a: Header = styles.header; // okA nested block is a created style of its own, so it reads the same the whole way down.
Either kind of style
A dynamic style satisfies AtomicStyle too, as long as it sets the properties named:
const styles = css.create({
sized: (width: number) => ({ width, color: 'red' }),
});
const a: NeedsColor = styles.sized(120); // okWhen only a dynamic style will do, AtomicClassStyle says so. When it must not be one, StaticStyles does.
One style, not a list
Neither type is a style list. Arrays and the falsy members belong to Style and its narrowed forms:
const a: NeedsColor = [styles.tinted]; // Type error
const b: NeedsColor = false; // Type errorSo a styling prop still wants Style, StyleProps, WithoutProperties or StaticStyles. Reach for AtomicStyle when a prop takes exactly one style and has to know what is in it.
In a generated declaration file
An exported style carries the same map into a declaration file, so a package that ships styles compiles with declaration: true. A called style is written the same way, its entries named by AtomicClassStyleFor — the mark that keeps them out of StaticStyles:
export declare const styles: Readonly<{
readonly base: Readonly<{
color: css.AtomicClassNameFor<'color', 'red'>;
}>;
readonly sized: (width: number) => Readonly<{
width: css.AtomicClassStyleFor<'width', number>;
}>;
}>;Good to know
The type argument is a requirement where you write it, and the class names a style holds are what satisfy it. typeof styles.base names one exact style without writing out either form.