Slot Options
<Page>
<Bar slot="header">...</Bar>
<Bar slot="footer" marginBottom="0">...</Bar>
<Sidebar slot="sidebar" >...</Sidebar>
<div>Page content here</div>
</Page>
The Simple Svelte Component Library that uses css variables & container queries to make your life easier.
Presenting the simple components you would expect to see in any modern component library.
Using svelte components is easy and supports a number of intuitive properties, such as:
<Button
bg="green"
fg="white"
width="64px"
height="64px">
Wow
</Button>
Our shorthand properties like bg and fg are just syntactic sugar for CSS
variables scoped to components, like --card-bg
and
--button-width
.
Because we use CSS variables, you can inject variables wherever you like in your component heirarchy, as in this nav bar with custom buttons:
<Bar --bar-bg="#333"
--button-bg="#333"
--button-fg="#eee"
--button-height="3rem">
<Button>Home</Button>
<Button>About</Button>
<Button>Contact</Button>
</Bar>
We use container queries out of the box, so you can adjust the layout of your components based on their size, rather than relying only on the viewport size. This "Card" has a sidebar, for example, but because the card is small, the sidebar will be in the "expander" small mode in the card, regardless of the screen size.
CSS Variables naturally flow down your component heirarchy, which makes them an ideal way to handle theming and styling in a modern component framework.
Contain has specific variables for each type of component, but those variables inherit smart defaults from some top-level settings by default.
The result is a modular system, where you can go in and customize, e.g., the padding on a button if your heart desires, but if you would like to keep everything sane and consistent, you can do so by tweaking a few top-level variables and letting inheritance do the rest.
So, for example, all elements with a border inherit the --border-radius
variable out of the gate, so if you just want your whole app to feel square,
you can set --border-radius
to 0
and be done
with it, but if you would like to get more granular, you can go in and
tweak --card-border-radius
and --button-border-radius
and so forth.
Here is a little text.
If you wrap an element in a
TextLayout
container, we will automatically apply some basic
typography for body text, headers, and so forth.
The TextLayout element uses some of the typographic styles that are applied at our top level component, which you can define anywhere in your project that you'd like to make changes.
The key to good typography is paying attention to the harmony and balance of three simple factors:
In this system, you can customize those three elements with --body-font-family
,
--line-width
and
--line-height
.
We take some pains to clean up the space around headings by default, so that headings are closer to the content they describe than the content that precedes them.
If you want to use background colors on your heading, you should add
some padding to them using the --heading-pad
variable,
which is unset by default (since our default headings don't have a
background color). I recommend trying one of the existing spacing
utility variables such as
var(--padding)
or var(--gap)
or var(--space)
to make sure the space around the heading will
harmonize with space elsewhere in your interface.
<TextLayout>
<h2>Typography</h2>
<p>And so on...</p>
<h3>More Headings</h3>
<blockquote>And so on</blockquote>
<p>And <q>so</q> on.</p>
</TextLayout>
The bar component is a simple flex container that can be used for menu bars, nav bars, footers, headers and more.
By default, the bar automatically spaces items out, but you can adjust that behavior either by adding left or right margins to children or by changing the CSS variables that control the justification on the flex container.
<Bar
--bar-bg="var(--material-color-light-blue-900)"
--bar-fg="var(--material-color-light-blue-100)"
>
<div>Left</div>
<div>Center</div>
<div>Right</div>
</Bar>
<div>More content after the bar...</div>
Try tweaking the variables for the Bar below
We provide a basic card component that can include optional header and footer slots.
Cards usually come with some box-shadow, coloring, and so forth, and have responsive sizing out of the box.
Here are some cards with and without headers inside resizable panes so you can see them acting responsively.
Cards can be set to fixedHeight true or false.
Tiles are flat, square containers that hold content.
They can be selectable or clickable to be used as buttons or checkboxes.
Just a basic tile.
Just a selectable tile.
Slide the pane to see responsive tiles at work
Look, a tile!
Look, a tile!
Our buttons are easily stylable with colors, padding,
<Button>Standard Button</Button>
<Button bg="transparent">Transparent Button</Button>
<Button>
Icon Button
<div slot="icon">▶</div>
</Button>
<Button primary={true}>Primary Button</Button>
<MiniButton bg="var(--material-color-deep-orange)" fg="white">+</MiniButton>
<Checkbox --checkbox-checked-bg="red" bind:checked={val}>Option</Checkbox>
Customize the style of our checkboxes
<radio --radio-button-checked-bg="red" bind:checked={val}>Option</radio>
Customize the style of our radioes
Our FormItem component is the heart of a simple approach to form layout. In a wide container, it puts labels side-by-side with inputs. In a narrow container, it puts labels above inputs. A number of CSS variables allow easy customization.
Out of the box, we auto-style inputs within a FormItem, so you don't need to import yet another custom component unless you want something fancy like a custom checkbox or select box.
You can turn off the global input styles by setting globalInputStyles to false.
Out of the box, we use nested labels for simple accessibility, so it's important that if you have a complex input, you have the first item in it the one you want focused when the user clicks the label.
<Container border --container-max-width="300px" --input-width="20em">
<FormItem>
<span slot="label">Name</span>
<input type="text" />
</FormItem>
<FormItem>
<span slot="label">Age</span>
<input type="number" min="16" max="130" />
</FormItem>
<FormItem>
<span slot="label">Level</span>
<input type="range" />
</FormItem>
<FormItem>
<Button primary>Add</Button>
</FormItem>
</Container>
Customize the style of our form items
Remember, because these are CSS variables, they don't have to be added at the FormItem component level but can be added higher up the heirarchy.
TabItem is basically syntactic sugar for a special button.
We provide an active= property to set it to active or not.
TabItem then overrides some of the button variables with tab variables which have their own defaults, specifically:
<TabItem active>TabItem</TabItem>
<TabItem>TabBar</TabItem>
<TabItem>Containers & Tabs</TabItem>
<TabItem>Overrides</TabItem>
The <Page>
component providers a simple full screen layout,
designed to be used with header/footer/sidebar or not.
The page defaults to full width and 100vh, but can take width and height properties to constrain it, as in the embedded demo page below.
<Page>
<Bar slot="header">...</Bar>
<Bar slot="footer" marginBottom="0">...</Bar>
<Sidebar slot="sidebar" >...</Sidebar>
<div>Page content here</div>
</Page>
The <SplitPane>
component makes it simple to create divided
content in resizable panes. Users can set the initial size by passing left and
right widths as props.
A min-size prop determines when the pane will "snap" to closed instead of shrunken.
Finally, panes automatically stack when placed in a small enough component.
<SplitPane leftWidth={2fr} rightWidth={1fr}>
<div slot="left">...</div>
<div slot="right">...</div>
</SplitPane>
Below are some nested split panes so you can see how they behave responsively.
Our basic dropdowns work well, even if the contents are longer than the contents of the page (see "long menu" example).
<Menu>
<span slot="label">Menu Title</span>
<li><button>Foo</button></li>
<li><button>Bar</button></li>
<li><button>Baz</button></li>
<li><button>Bang</button></li>
</Menu>
Our <Select>
element creates the select element we always
wish we had, with styling allowed inside of the <option> tag. On small
screens, we will fall back to acting like a standard select, but when there's
enough space for our custom element, we'll use a dropdown menu to render a select
button with markup allowed internally.
You selected John, aged 30!
<Select bind:value={val}>
<option value={1}>Option A</option>
<option value={2}><b>Strong</b> B</option>
<option value={3}><em>Fancy</em> C</option>
<option value={4}><span style="color:red">Red</span> D</option>
</Select>
Well look, they selected 2
Show off two way binding by changing the option here as well:
Here it is using the --select-width variable to constrain the select size.
<Select --select-width="80px" ...>
...
</Select>