-
Notifications
You must be signed in to change notification settings - Fork 1
DOM Rendering
By default, <Module>
and <Component>
will render a <div>
tag to the DOM. You can specify a different HTML tag to use by passing the tag name to a tag
prop:
<Module styles={styles} tag='section'>
<Component name='heading' tag='h3'>Heading</Component>
<Component name='text' tag='p'>Some text</Component>
</Module>
A Component with no name
prop will use the value of an existing tag
prop instead:
<Module styles={styles} tag='form'>
<Component tag='fieldset'>
<Component tag='label'>...</Component>
<Component tag='input'>...</Component>
</Component>
...
</Module>
This effectively lets you style tags (scoped to the Module) the same way you can style Components:
const styles = {
fieldset: {
// ...some styles
},
label: {
// ...some styles
},
input: {
// ...some styles
},
p: {
// ...some styles
}
}
Supplying a
href
prop without atag
prop will automatically render an anchor element
You can supply a React Component to render instead a div/HTML tag, as long as the Component you supply ultimatly renders something to the DOM (whatever Component you supply here must have a current
property on its ref
that has a DOM node as its value):
<Module styles={styles} component={MyReactComponent}>
...
</Module>
If you need to supply some props to this Component, you can pass the value as an array; the first item being your Component, and the second item being your props (as an object):
<Module styles={styles} component={[MyReactComponent, { myProp: 'myValue' }]}>
...
</Module>
This is useful for wrapping UI Modules you may take from third parties (e.g. react-table).
One of the goals of Lucid is to ensure the rendered DOM is still clean, predictable and readable. Lucid achives this by outputing classes that adhere to the BEM Naming Convention (and can be loosley configured).
Consider the following example:
export default () => (
<Module name='card'>
<Component name='title' large primary>Card Title</Component>
<Component name='content'>Card Content</Component>
</Module>
);
This would output HTML with the shown classes (the actual rendered HTML may have additional attributes):
<div class="card">
<div class="card__title card__title--large card__title--primary">Card Title</div>
<div class="card__content">Card Content</div>
</div>
By setting the singleClass option to true
you can change the above output to:
<div class="card">
<div class="card__title--large--primary">Card Title</div>
<div class="card__content">Card Content</div>
</div>
This means that there is benefit in using Lucid merely to create clean DOMs (i.e, without using the Styling aspect).
You can enable/disble the generation of classes when using Lucid.
Pass the
generateClasses
property to your module's configuration
const config = {
generateClasses: true,
...
}
const MyModule = () => (
<Module name='my-module' styles={...} config={config}>
<Component name='my-component'>My Component</Component>
</Module>
);
<div class="my-module">
<div class="my-module__my-component">My Component</div>
</div>
This option can be set globally by adding it to your theme
Props which have a boolean value of true
will be treated as modifieirs
.
const MyModule = () => (
<Module name='my-module' styles={...} config={config} alpha>
<Component name='my-component' fizz buzz>My Component</Component>
</Module>
);
<div class="my-module--alpha">
<div class="my-module__my-component my-module__my-component--fizz my-module__my-component--buzz">
My Component
</div>
</div>
Instead of generating separate classes for each modifier, you can instead generate a single class.
Pass the
singleClass
property to your module's configuration
const config = {
generateClasses: true,
singleClass: true,
...
}
...
<div class="my-module--alpha">
<div class="my-module__my-component--fizz--buzz">
My Component
</div>
</div>
This option can be set globally by adding it to your theme
You can customize both the Component glue (default: __
) and modifer glue (default: --
):
const config = {
generateClasses: true,
singleClass: true,
componentGlue: '_',
modifierGlue: ' '
...
}
const MyModule = () => (
<Module name='my-module' styles={...} config={config} fizz>
<Component name='my-component' foo bar>My Component</Component>
</Module>
);
<div class="my-module fizz">
<div class="my-module_my-component foo bar">My Component</div>
</div>
These options can be set globally by adding them to your theme
In order to keep bundle size down, the Lucid Components accept the following DOM-affecting props:
- Any valid event handler (camel-cased to support React) e.g
onClick
- Any
data-
attribute className
href
id
If you need to pass any other props/attributes to the rendered DOM node, you should pass them to the attributes
prop:
<Module styles={styles} tag='form' attributes={{ method: 'post'}}>
...
</Module>
Whilst this isn't the best DX (you'd ideally be able to pass attribute directly), it keeps the bundle size down as it avoids having to keep a list of valid HTML attributes in the source.
By default, Lucid will output a data-module
attribute for <Module>
s, and a data-component
attribute for <Component>
s and <SubComponent>
s:
const MyModule = () => (
<Module name='my-module'>
<Component name='my-component'>
<SubComponent name='my-subComponent'>
...
</SubComponent>
</Component>
</Module>
)
<SubComponents>
will also output a booleandata-sub-component
attribute
<div data-module="my-module">
<div data-component="my-component">
<div data-component="my-subComponent" data-sub-component>
...
</div>
</div>
</div>
To disable this feature, pass a generateDataAttributes
property to your module's configuration and set it to false
:
const config = {
generateDataAttributes: false,
...
}
This option can be set globally by adding it to your theme