Skip to content

Commit

Permalink
feat(local-nav): add :actions option
Browse files Browse the repository at this point in the history
  • Loading branch information
kiaking committed Dec 16, 2024
1 parent ae465b5 commit 386e00e
Show file tree
Hide file tree
Showing 5 changed files with 154 additions and 8 deletions.
72 changes: 69 additions & 3 deletions docs/components/local-nav.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,27 @@ const title = [
</template>
```

### Page actions

You may define `:actions` to display page actions (buttons). The `:actions` prop accepts array of [`Action`](#action) object. The action object is the same as props for [`<SButton>`](button) except `:size` since the size is fixed to `small`, and an extra `onClick` function to handle the click event.

```vue
<script setup lang="ts">
const title = [
{ text: 'Page title' },
]
const actions = [
{ label: 'Edit title', onClick: () => { /* ... */ } },
{ label: 'About', onClick: () => { /* ... */ } }
]
</script>
<template>
<SLocalNav :title="title" :actions="actions" />
</template>
```

### Page navigation

You may define `:menu` to display a page navigation. The `:menu` props accepts "double nested" array, in order to create grouping of menu items.
Expand Down Expand Up @@ -94,6 +115,30 @@ interface Title {
}
```

### `Action`

```ts
import { type Component } from 'vue'
import { type Mode, type Tooltip, type Type } from '@globalbrain/sefirot/lib/components/SButton.vue'

export interface Action {
tag?: string
type?: Type
mode?: Mode
icon?: Component
leadIcon?: Component
trailIcon?: Component
iconMode?: Mode
label?: string
labelMode?: Mode
href?: string
loading?: boolean
disabled?: boolean
tooltip?: string | Tooltip
onClick?(): void
}
```

### `MenuItem`

The type of menu item.
Expand All @@ -114,6 +159,7 @@ interface Props {
avatar?: Avatar
title: Title[]
description?: string
actions?: Action[]
menu?: MenuItem[][]
}
```
Expand Down Expand Up @@ -149,7 +195,7 @@ interface Props {
/>
```

### `description`
### `:description`

Add description text under the title.

Expand All @@ -166,6 +212,26 @@ interface Props {
/>
```

### `:actions`

The actions of the page.

```ts
interface Props {
actions: Action[]
}
```

```vue-html
<SLocalNav
:title="[{ text: 'Page title' }]"
:actions="[
{ label: 'Edit title' },
{ label: 'About' }
]"
/>
```

### `:menu`

The menu of the page.
Expand All @@ -179,9 +245,9 @@ interface Props {
```vue-html
<SLocalNav
:title="[{ text: 'Page title' }]"
:menu="[
:menu="[[
{ text: 'Menu item 1', link: '/menu1' },
{ text: 'Menu item 2', link: '/menu2' }
]"
]]"
/>
```
20 changes: 18 additions & 2 deletions lib/components/SLocalNav.vue
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
<script setup lang="ts">
import { computed } from 'vue'
import SLocalNavActions, { type Action } from './SLocalNavActions.vue'
import SLocalNavAvatar from './SLocalNavAvatar.vue'
import SLocalNavDescription from './SLocalNavDescription.vue'
import SLocalNavMenu, { type MenuItem } from './SLocalNavMenu.vue'
import SLocalNavTitle, { type Title } from './SLocalNavTitle.vue'
export type { Title, MenuItem }
export type { Title, Action, MenuItem }
export interface Avatar {
image?: string | null
Expand All @@ -16,6 +17,7 @@ const props = defineProps<{
avatar?: Avatar
title: Title[]
description?: string
actions?: Action[]
menu?: MenuItem[][]
}>()
Expand All @@ -37,7 +39,10 @@ const normalizedMenu = computed(() => {
/>
</div>
<div class="title-bar-body">
<SLocalNavTitle :title="title" />
<div class="title-bar-title">
<SLocalNavTitle :title="title" />
<SLocalNavActions v-if="actions?.length" :actions="actions" />
</div>
<SLocalNavDescription v-if="description" :text="description" />
</div>
</div>
Expand Down Expand Up @@ -71,4 +76,15 @@ const normalizedMenu = computed(() => {
align-items: center;
gap: 16px;
}
.title-bar-body {
flex-grow: 1;
max-width: 100%;
}
.title-bar-title {
display: flex;
align-items: center;
gap: 24px;
}
</style>
56 changes: 56 additions & 0 deletions lib/components/SLocalNavActions.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<script setup lang="ts">
import { type Component } from 'vue'
import SButton, { type Mode, type Tooltip, type Type } from './SButton.vue'
export interface Action {
tag?: string
type?: Type
mode?: Mode
icon?: Component
leadIcon?: Component
trailIcon?: Component
iconMode?: Mode
label?: string
labelMode?: Mode
href?: string
loading?: boolean
disabled?: boolean
tooltip?: string | Tooltip
onClick?(): void
}
defineProps<{
actions: Action[]
}>()
</script>

<template>
<div class="SLocalNavActions">
<div v-for="action, i in actions" :key="i" class="action">
<SButton
size="small"
:type="action.type"
:mode="action.mode"
:icon="action.icon"
:lead-icon="action.leadIcon"
:trail-icon="action.trailIcon"
:icon-mode="action.iconMode"
:label="action.label"
:label-mode="action.labelMode"
:href="action.href"
:loading="action.loading"
:disabled="action.disabled"
:tooltip="action.tooltip"
@click="() => { action.onClick?.() }"
/>
</div>
</div>
</template>

<style scoped lang="postcss">
.SLocalNavActions {
display: flex;
flex-shrink: 0;
gap: 8px;
}
</style>
2 changes: 2 additions & 0 deletions lib/components/SLocalNavTitle.vue
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ defineProps<{
<style scoped lang="postcss">
.SLocalNavTitle {
display: flex;
flex-grow: 1;
width: 100%;
overflow: hidden;
}
Expand Down
12 changes: 9 additions & 3 deletions stories/components/SLocalNav.01_Playground.story.vue
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<script setup lang="ts">
import IconActivity from '~icons/ph/activity-bold'
import IconCurrencyCircleDollar from '~icons/ph/currency-circle-dollar-bold'
import IconGear from '~icons/ph/gear-bold'
import IconActivity from '~icons/ph/activity'
import IconCurrencyCircleDollar from '~icons/ph/currency-circle-dollar'
import IconGear from '~icons/ph/gear'
import SLocalNav from 'sefirot/components/SLocalNav.vue'
const title = 'Components / SLocalNav / 01. Playground'
Expand All @@ -12,6 +12,11 @@ const navTitle = [
{ text: 'Series A' }
]
const navActions = [
{ label: 'Edit title', onClick: () => {} },
{ label: 'About', onClick: () => {} }
]
const navMenu = [
[
{ icon: IconActivity, text: 'Overview', link: '#', active: true },
Expand All @@ -28,6 +33,7 @@ const navMenu = [
<Board :title="title" :docs="docs">
<SLocalNav
:title="navTitle"
:actions="navActions"
:menu="navMenu"
/>
</Board>
Expand Down

0 comments on commit 386e00e

Please sign in to comment.