Skip to content

Commit

Permalink
feat(head): add SHead component
Browse files Browse the repository at this point in the history
  • Loading branch information
kiaking committed Jul 12, 2023
1 parent 4546cab commit 20d2f5e
Show file tree
Hide file tree
Showing 8 changed files with 160 additions and 0 deletions.
1 change: 1 addition & 0 deletions docs/.vitepress/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ function sidebar(): DefaultTheme.SidebarItem[] {
{ text: 'SButtonGroup', link: '/components/button-group' },
{ text: 'SCard', link: '/components/card' },
{ text: 'SFragment', link: '/components/fragment' },
{ text: 'SHead', link: '/components/head' },
{ text: 'SInputAddon', link: '/components/input-addon' },
{ text: 'SInputCheckbox', link: '/components/input-checkbox' },
{ text: 'SInputCheckboxes', link: '/components/input-checkboxes' },
Expand Down
40 changes: 40 additions & 0 deletions docs/components/head.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<script setup lang="ts">
import SHead from 'sefirot/components/SHead.vue'
import SHeadLead from 'sefirot/components/SHeadLead.vue'
import SHeadTitle from 'sefirot/components/SHeadTitle.vue'
</script>

# SHead

`<SHead>` denotes the title and start of a given section.

<Showcase
path="/components/SCard.vue"
story="/stories-components-scard-01-playground-story-vue"
>
<SHead>
<SHeadTitle>The head title</SHeadTitle>
<SHeadLead>Lorem ipsum dolor sit, amet consectetur.</SHeadLead>
</SHead>
</Showcase>
## Usage

`<SHead>` has 2 child components: `<SHeadTitle>` and `<SHeadLead>`. `<SHeadTitle>` is used to display the title text, and `<SHeadLead>` is used to display the lead text below the title.

```vue
<script setup lang="ts">
import SHead from '@globalbrain/sefirot/lib/components/SHead.vue'
import SHeadLead from '@globalbrain/sefirot/lib/components/SHeadLead.vue'
import SHeadTitle from '@globalbrain/sefirot/lib/components/SHeadTitle.vue'
</script>
<template>
<SHead>
<SHeadTitle>The head title</SHeadTitle>
<SHeadLead>Lorem ipsum dolor sit, amet consectetur.</SHeadLead>
</SHead>
</template>
```

Note that the `<SHeadLead>` component also styles `<a>` elements when it is passed so there is no need to style links manually.
5 changes: 5 additions & 0 deletions lib/components/SHead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<template>
<div class="SHead">
<slot />
</div>
</template>
22 changes: 22 additions & 0 deletions lib/components/SHeadLead.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<template>
<div class="SHeadLead">
<slot />
</div>
</template>

<style scoped lang="postcss">
.SHeadLead {
line-height: 24px;
font-size: 14px;
color: var(--c-text-2);
}
.SHeadLead :deep(a) {
color: var(--c-info-text);
transition: color 0.25s;
&:hover {
color: var(--c-info-text-dark);
}
}
</style>
14 changes: 14 additions & 0 deletions lib/components/SHeadTitle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<template>
<div class="SHeadTitle">
<slot />
</div>
</template>

<style scoped lang="postcss">
.SHeadTitle {
line-height: 32px;
font-size: 20px;
font-weight: 500;
color: var(--c-text-1);
}
</style>
14 changes: 14 additions & 0 deletions lib/mixins/Head.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type App } from 'vue'
import SHead from '../components/SHead.vue'
import SHeadLead from '../components/SHeadLead.vue'
import SHeadTitle from '../components/SHeadTitle.vue'

export function mixin(app: App): void {
app.mixin({
components: {
SHead,
SHeadLead,
SHeadTitle
}
})
}
41 changes: 41 additions & 0 deletions stories/components/SHead.01_Playground.story.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup lang="ts">
import SHead from 'sefirot/components/SHead.vue'
import SHeadLead from 'sefirot/components/SHeadLead.vue'
import SHeadTitle from 'sefirot/components/SHeadTitle.vue'
const title = 'Components / SHead / 01. Playground'
const docs = '/components/head'
function state() {
return {
title: 'The head title',
lead: 'Lorem ipsum dolor sit, amet consectetur.'
}
}
</script>

<template>
<Story :title="title" :init-state="state" source="Not available" auto-props-disabled>
<template #controls="{ state }">
<HstText
title="Title"
v-model="state.title"
/>
<HstText
title="Lead"
v-model="state.lead"
/>
</template>

<template #default="{ state }">
<Board :title="title" :docs="docs">
<div class="max-w-512">
<SHead>
<SHeadTitle v-if="state.title">{{ state.title }}</SHeadTitle>
<SHeadLead v-if="state.lead">{{ state.lead }}</SHeadLead>
</SHead>
</div>
</Board>
</template>
</Story>
</template>
23 changes: 23 additions & 0 deletions tests/components/SHead.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { mount } from '@vue/test-utils'
import SHead from 'sefirot/components/SHead.vue'
import SHeadLead from 'sefirot/components/SHeadLead.vue'
import SHeadTitle from 'sefirot/components/SHeadTitle.vue'

describe('components/SHead', () => {
describe('SHead', () => {
test('renders `SHead` element', () => {
const wrapper = mount(SHead)
expect(wrapper.find('.SHead').exists()).toBe(true)
})

test('renders `SHeadTitle` element', () => {
const wrapper = mount(SHeadTitle)
expect(wrapper.find('.SHeadTitle').exists()).toBe(true)
})

test('renders `SHeadLead` element', () => {
const wrapper = mount(SHeadLead)
expect(wrapper.find('.SHeadLead').exists()).toBe(true)
})
})
})

0 comments on commit 20d2f5e

Please sign in to comment.