Skip to content

Commit

Permalink
Refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
DarkGhostHunter committed Nov 19, 2023
1 parent de8baeb commit 3ca2c6f
Show file tree
Hide file tree
Showing 7 changed files with 142 additions and 122 deletions.
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
<template>
<UFeed :feed="feed" :indicators="false">
<template #body="{ item }">
<div class="space-y-2">
<div class="text-xl">
{{ item.title }}
</div>
<div class="px-3 py-2 text-gray-100 text-sm font-mono ring-1 ring-gray-800 rounded bg-gray-950 shadow">
&gt; {{ item.description }}
</div>
<template #description="{ item }">
<div class="px-3 py-2 text-gray-100 text-sm font-mono ring-1 ring-gray-800 rounded bg-gray-950 shadow">
&gt; {{ item.description }}
</div>
</template>
</UFeed>
Expand Down
25 changes: 25 additions & 0 deletions docs/components/content/examples/FeedExampleSlotTitle.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<template>
<UFeed :feed="feed" :indicators="false">
<template #title="{ item }">
<div class="h-full flex items-center" :class="`text-${item.color}-500`">
{{ item.title }}
</div>
</template>
</UFeed>
</template>

<script setup>
const feed = [
{
title: 'Package on delivery',
color: 'green',
icon: 'i-heroicons-truck'
},
{
title: 'Packaged failed to deliver!',
description: 'Call us to re-deliver your package, or pick it up at our store',
color: 'red',
icon: 'i-heroicons-x-mark'
}
]
</script>
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
<template>
<UFeed :feed="feed">
<template #trailing="{ item }">
<div v-if="item.trailing" class="mt-1.5 font-mono text-xs text-gray-500 flex items-center gap-2">
<div v-if="item.trailing" class="mt-1.5 font-mono text-xs text-gray-500 flex items-center justify-end gap-2">
{{ item.trailing }} <UIcon name="i-heroicons-clock" />
</div>
</template>
Expand Down
22 changes: 14 additions & 8 deletions docs/content/2.elements/12.feed.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ You may also use an array of objects as a feed, with the following properties:

:component-example{component="feed-example-objects"}

### Indicators
### Icons

You can transform the indicators to a small dot for all the events by setting the `indicators` prop to `false`.
You can transform the icons to small dots for all the events by setting the `icons` prop to `false`.

::component-card
---
Expand All @@ -57,7 +57,7 @@ baseProps:
icon: i-heroicons-paper-airplane
trailing: Oct 8 09:36:38
props:
indicators: false
icons: false
---
::

Expand All @@ -75,7 +75,7 @@ baseProps:
- Deployed
props:
separators: false
indicators: false
icons: false
---
::

Expand Down Expand Up @@ -105,7 +105,7 @@ baseProps:
trailing: Oct 8 09:36:38
color: 'gray'
props:
indicators: true
icons: true
color: 'primary'
---
::
Expand All @@ -118,11 +118,17 @@ You have access to the item indicator through the `icon` prop, that receives the

:component-example{component="feed-example-slot-icon"}

### `body`
### `title`

You can change how the feed item contents is presented using the `body` prop. It receives the item and the index position.
You can change how the feed title is presented using the `title` prop. It receives the item and the index position.

:component-example{component="feed-example-slot-body"}
:component-example{component="feed-example-slot-title"}

### `description`

You can change how the feed description is presented using the `description` prop. It receives the item and the index position.

:component-example{component="feed-example-slot-description"}

### `trailing`

Expand Down
10 changes: 10 additions & 0 deletions src/colors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,16 @@ const safelistByComponent = {
}, {
pattern: new RegExp(`bg-(${colorsAsRegex})-700`),
variants: ['dark']
}, {
pattern: new RegExp(`text-(${colorsAsRegex})-900`)
}, {
pattern: new RegExp(`text-(${colorsAsRegex})-50`),
variants: ['dark']
}, {
pattern: new RegExp(`text-(${colorsAsRegex})-500`)
}, {
pattern: new RegExp(`text-(${colorsAsRegex})-500`),
variants: ['dark']
}],
notification: (colorsAsRegex) => [{
pattern: new RegExp(`bg-(${colorsAsRegex})-400`),
Expand Down
129 changes: 49 additions & 80 deletions src/runtime/components/elements/Feed.vue
Original file line number Diff line number Diff line change
@@ -1,40 +1,52 @@
<template>
<ol :class="ui.base" v-bind="attrs">
<ol :class="ui.base" v-bind="attrs" :style="ui.style">
<template v-for="(item, key) in items" :key="key">
<li :class="ui.item">
<div :class="ui.indicator.base">
<div :class="indicatorContainerClass">
<div>
<slot name="icon" v-bind="{ item, key }">
<div :class="[indicatorIconClass, getIndicatorColorClass(item)]">
<template v-if="isDot" />
<UIcon v-else-if="item.icon" :name="item.icon" />
<template v-else>
{{ key + 1 }}
</template>
</div>
</slot>
<div>
<slot name="icon" v-bind="{ item, key }">
<div v-if="hasIcons" :class="getIconClass(item)">
<UIcon v-if="item.icon" :name="item.icon" />
<template v-else>
{{ key + 1 }}
</template>
</div>
<div v-if="withSeparators && key < items.length - 1" :class="separatorClass" />
</div>
<div v-else :class="getIconClass(item)" />
</slot>
</div>
<div :class="ui.body.base" class="">
<slot name="body" v-bind="{ item, key }">
<div :class="titleClass">

<div>
<slot name="title" v-bind="{ item, key }">
<div :class="[ui.title.base, ui.title.align, ui.title.size, ui.title.color]">
{{ item.title }}
</div>
<div v-if="item.description" :class="descriptionClass">
<small>{{ item.description }}</small>
</div>
</slot>
</div>
<div :class="ui.trailing.base">

<div>
<slot name="trailing" v-bind="{ item, key }">
<div :class="trailingTextClass">
<small>{{ item.trailing }}</small>
<div :class="[ui.trailing.base, ui.trailing.align, ui.trailing.size, ui.trailing.color]">
{{ item.trailing }}
</div>
</slot>
</div>

<div>
<div v-if="hasSeparators && key < items.length - 1" :class="ui.separator.wrapper">
<div :class="ui.separator.container">
<div :class="[ui.separator.size, ui.separator.background, hasIcons ? '' : ui.separator.withoutIndicators]" />
</div>
</div>
</div>

<div :class="key < items.length - 1 ? ui.padding : ''">
<slot name="description" v-bind="{ item, key }">
<div :class="[ui.description.base, ui.description.align, ui.description.size, ui.description.color]">
{{ item.description }}
</div>
</slot>
</div>

<div />
</li>
</template>
</ol>
Expand Down Expand Up @@ -64,7 +76,7 @@ export default defineComponent({
type: Array as PropType<String[] | FeedItem[]>,
default: () => []
},
indicators: {
icons: {
type: Boolean,
default: true
},
Expand All @@ -91,72 +103,29 @@ export default defineComponent({
return typeof item === 'string' ? { title: item } : item
}))
const isDot = computed(() => !props.indicators)
const withSeparators = computed(() => props.separators)
const indicatorContainerClass = computed(() => {
return twJoin(
ui.value.indicator.container,
isDot.value ? ui.value.indicator.margin : ''
)
})
const hasIcons = computed(() => props.icons)
const hasSeparators = computed(() => props.separators)
const indicatorIconClass = computed(() => {
return twJoin(
ui.value.indicator.icon.base,
ui.value.indicator.icon.rounded,
isDot.value ? ui.value.indicator.icon.dot : ui.value.indicator.icon.size
)
})
function getIconClass (item: FeedItem) {
const key = hasIcons.value ? 'large' : 'small'
function getIndicatorColorClass (item: FeedItem) {
return twJoin(
ui.value.indicator.icon.background.replaceAll('{color}', item.color ?? props.color)
ui.value.indicator[key].base,
ui.value.indicator[key].size,
ui.value.indicator[key].ring,
ui.value.indicator[key].rounded,
ui.value.indicator.color.replaceAll('{color}', item.color ?? props.color)
)
}
const separatorClass = computed(() => {
return twJoin(
ui.value.separator.base,
ui.value.separator.background.replaceAll('{color}', props.color)
)
})
const titleClass = computed(() => {
return twJoin(
ui.value.body.title.replaceAll('{color}', props.color)
)
})
const descriptionClass = computed(() => {
return twJoin(
ui.value.body.description.replaceAll('{color}', props.color)
)
})
const trailingTextClass = computed(() => {
return twJoin(
ui.value.trailing.text.base,
ui.value.trailing.text.align,
ui.value.trailing.text.color.replaceAll('{color}', props.color)
)
})
return {
// eslint-disable-next-line vue/no-dupe-keys
ui,
attrs,
items,
isDot,
withSeparators,
indicatorContainerClass,
indicatorIconClass,
getIndicatorColorClass,
separatorClass,
titleClass,
descriptionClass,
trailingTextClass
hasIcons,
hasSeparators,
getIconClass
}
}
})
Expand Down
65 changes: 40 additions & 25 deletions src/runtime/ui.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -551,37 +551,52 @@ export const meterGroup = {
}

export const feed = {
base: 'flex flex-col',
item: 'flex flex-row',
base: 'grid gap-x-4',
style: {
'grid-template-columns': 'max-content max-content max-content',
'grid-auto-rows': 'min-content min-content'
},
padding: 'pb-8',
item: 'contents',
indicator: {
base: 'h-full',
container: 'h-full flex flex-col items-center transition-all',
margin: 'mt-3',
icon: {
base: 'flex items-center justify-center transition-all',
background: 'bg-{color}-200 dark:bg-{color}-700',
color: '',
rounded: 'rounded-full',
color: 'bg-{color}-200 dark:bg-{color}-700',
large: {
base: 'grid place-items-center transition-colors',
size: 'h-8 w-8',
dot: 'h-2 w-2'
ring: '',
rounded: 'rounded-full'
},
small: {
base: 'mt-2',
size: 'h-2 w-2',
ring: '',
rounded: 'rounded-full'
}
},
separator: {
base: 'h-full w-px my-1',
background: 'bg-gray-200 dark:bg-gray-700'
},
body: {
base: 'grow px-4 pb-4 mt-0.5',
title: 'text-gray-900 dark:text-gray-50',
description: 'text-gray-500 dark:text-gray-500'
title: {
base: 'h-full flex items-center truncate',
align: '',
size: 'text-md',
color: 'text-gray-900 dark:text-gray-50'
},
trailing: {
base: 'mt-0.5',
text: {
base: '',
align: 'text-right',
color: 'text-gray-500 dark:text-gray-500'
}
base: 'h-full flex items-center truncate',
align: 'justify-end',
size: 'text-xs',
color: 'text-gray-500 dark:text-gray-500'
},
separator: {
wrapper: 'h-full w-full flex',
container: 'w-full flex justify-center py-1',
size: 'w-px',
background: 'bg-gray-200 dark:bg-gray-700',
withoutIndicators: '-mt-3 -mb-2'
},
description: {
base: '',
align: '',
size: 'text-sm',
color: 'text-gray-500 dark:text-gray-500'
},
default: {
color: 'gray'
Expand Down

0 comments on commit 3ca2c6f

Please sign in to comment.