You've already forked AstralRinth
forked from didirus/AstralRinth
Make current code library + add docs
This commit is contained in:
142
lib/components/base/Button.vue
Normal file
142
lib/components/base/Button.vue
Normal file
@@ -0,0 +1,142 @@
|
||||
<script setup>
|
||||
import { IssuesIcon, ExternalIcon, UnknownIcon} from '@/components'
|
||||
|
||||
import { computed } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
link: {
|
||||
type: String,
|
||||
default: null,
|
||||
},
|
||||
external: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
action: {
|
||||
type: Function,
|
||||
default: null,
|
||||
},
|
||||
design: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
},
|
||||
color: {
|
||||
type: String,
|
||||
default: 'default',
|
||||
},
|
||||
iconOnly: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
}
|
||||
})
|
||||
|
||||
const defaultDesign = computed(() => props.design === 'default')
|
||||
const accentedButton = computed(
|
||||
() => defaultDesign.value && ['danger', 'primary'].includes(props.color)
|
||||
)
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<!-- <nuxt-link-->
|
||||
<!-- v-if="link && link.startsWith('/')"-->
|
||||
<!-- class="omorphia__button button-base button-color-base padding-block-sm padding-inline-lg radius-sm"-->
|
||||
<!-- :class="{-->
|
||||
<!-- 'icon-only': props.iconOnly,-->
|
||||
<!-- 'bg-raised': raised,-->
|
||||
<!-- 'bg-red': danger,-->
|
||||
<!-- 'bg-brand': primary,-->
|
||||
<!-- 'color-accent-contrast': danger || primary,-->
|
||||
<!-- }"-->
|
||||
<!-- :to="link"-->
|
||||
<!-- :target="external ? '_blank' : '_self'"-->
|
||||
<!-- >-->
|
||||
<!-- <slot />-->
|
||||
<!-- <Icon v-if="external && !props.iconOnly" class="external-icon" icon="external" />-->
|
||||
<!-- <Icon v-if="!$slots.default" icon="unknown" />-->
|
||||
<!-- </nuxt-link>-->
|
||||
<a
|
||||
v-if="link"
|
||||
class="omorphia__button button-base padding-block-sm padding-inline-lg radius-sm"
|
||||
:class="{
|
||||
'standard-button': defaultDesign,
|
||||
'icon-only': props.iconOnly,
|
||||
'bg-raised': defaultDesign && color === 'raised',
|
||||
'bg-red': defaultDesign && color === 'danger',
|
||||
'bg-brand': defaultDesign && color === 'primary',
|
||||
'color-accent-contrast': accentedButton,
|
||||
}"
|
||||
:href="link"
|
||||
:target="external ? '_blank' : '_self'"
|
||||
>
|
||||
<slot />
|
||||
<ExternalIcon v-if="external && !iconOnly" class="external-icon" />
|
||||
<UnknownIcon v-if="!$slots.default" />
|
||||
</a>
|
||||
<button
|
||||
v-else-if="action"
|
||||
class="omorphia__button button-base padding-block-sm padding-inline-lg radius-sm"
|
||||
:class="{
|
||||
'standard-button': defaultDesign,
|
||||
'icon-only': props.iconOnly,
|
||||
'bg-raised': defaultDesign && color === 'raised',
|
||||
'bg-red': defaultDesign && color === 'danger',
|
||||
'bg-brand': defaultDesign && color === 'primary',
|
||||
'color-accent-contrast': accentedButton,
|
||||
}"
|
||||
@click="action"
|
||||
>
|
||||
<slot />
|
||||
<UnknownIcon v-if="!$slots.default" />
|
||||
</button>
|
||||
<div
|
||||
v-else
|
||||
class="omorphia__button button-base button-color-base padding-block-sm padding-inline-lg radius-sm bg-red color-accent-contrast"
|
||||
>
|
||||
<IssuesIcon />
|
||||
Missing link or action!
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
:where(button) {
|
||||
background: none;
|
||||
color: var(--color-base);
|
||||
}
|
||||
|
||||
.omorphia__button {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
cursor: pointer;
|
||||
width: fit-content;
|
||||
height: fit-content;
|
||||
text-decoration: none;
|
||||
|
||||
:deep(svg) {
|
||||
width: 1.1rem;
|
||||
height: 1.1rem;
|
||||
margin-right: 0.5rem;
|
||||
}
|
||||
|
||||
:deep(.external-icon) {
|
||||
width: 0.75rem;
|
||||
height: 0.75rem;
|
||||
margin-bottom: auto;
|
||||
margin-left: 0.25rem;
|
||||
margin-right: 0;
|
||||
}
|
||||
|
||||
&.icon-only {
|
||||
padding: 0;
|
||||
height: 2.25rem;
|
||||
width: 2.25rem;
|
||||
|
||||
:deep(svg) {
|
||||
min-width: 1.25rem;
|
||||
max-width: 1.25rem;
|
||||
min-height: 1.25rem;
|
||||
max-height: 1.25rem;
|
||||
margin: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
62
lib/components/base/Card.vue
Normal file
62
lib/components/base/Card.vue
Normal file
@@ -0,0 +1,62 @@
|
||||
<script setup>
|
||||
import { Button, DropdownIcon } from '@/components'
|
||||
|
||||
import { reactive } from 'vue'
|
||||
|
||||
const props = defineProps({
|
||||
collapsible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
defaultCollapsed: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
noAutoBody: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
|
||||
const state = reactive({
|
||||
collapsed: props.defaultCollapsed,
|
||||
})
|
||||
|
||||
function toggleCollapsed() {
|
||||
state.collapsed = !state.collapsed
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="omorphia__card standard-body padding-xl bg-raised radius-lg margin-bottom-md"
|
||||
:class="{ 'auto-body': !noAutoBody }"
|
||||
>
|
||||
<div v-if="!!$slots.header || collapsible" class="header">
|
||||
<slot name="header"></slot>
|
||||
<div v-if="collapsible" class="button-group margin-left-auto margin-right-0">
|
||||
<Button :action="toggleCollapsed">
|
||||
<DropdownIcon :style="{ transform: `rotate(${state.collapsed ? 0 : 180}deg)` }" />
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
<slot v-if="!state.collapsed" />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.omorphia__card {
|
||||
}
|
||||
|
||||
.header {
|
||||
display: flex;
|
||||
|
||||
:deep(h1, h2, h3, h4) {
|
||||
margin-block: 0;
|
||||
}
|
||||
|
||||
&:not(:last-child) {
|
||||
margin-bottom: var(--gap-lg);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
121
lib/components/base/Page.vue
Normal file
121
lib/components/base/Page.vue
Normal file
@@ -0,0 +1,121 @@
|
||||
<script setup>
|
||||
defineProps({
|
||||
collapsible: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
rightSidebar: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div
|
||||
class="omorphia__page"
|
||||
:class="{
|
||||
'right-sidebar': rightSidebar,
|
||||
'has-sidebar': !!$slots.sidebar,
|
||||
'has-header': !!$slots.header,
|
||||
'has-footer': !!$slots.footer,
|
||||
}"
|
||||
>
|
||||
<div v-if="!!$slots.header" class="header">
|
||||
<slot name="header" />
|
||||
</div>
|
||||
<div v-if="!!$slots.sidebar" class="sidebar">
|
||||
<slot name="sidebar" />
|
||||
</div>
|
||||
<div class="content">
|
||||
<slot />
|
||||
</div>
|
||||
<div v-if="!!$slots.footer" class="footer">
|
||||
<slot name="footer" />
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
.omorphia__page {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 0 0.75rem;
|
||||
|
||||
.header {
|
||||
grid-area: header;
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
grid-area: sidebar;
|
||||
}
|
||||
|
||||
.footer {
|
||||
grid-area: footer;
|
||||
}
|
||||
|
||||
.content {
|
||||
grid-area: content;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 1024px) {
|
||||
.omorphia__page {
|
||||
margin: 0 auto;
|
||||
max-width: 80rem;
|
||||
column-gap: 0.75rem;
|
||||
|
||||
&.has-sidebar {
|
||||
display: grid;
|
||||
grid-template:
|
||||
'sidebar content' auto
|
||||
'footer content' auto
|
||||
'dummy content' 1fr
|
||||
/ 20rem 1fr;
|
||||
|
||||
&.has-header {
|
||||
grid-template:
|
||||
'header header' auto
|
||||
'sidebar content' auto
|
||||
'footer content' auto
|
||||
'dummy content' 1fr
|
||||
/ 20rem 1fr;
|
||||
}
|
||||
|
||||
&.right-sidebar {
|
||||
grid-template:
|
||||
'content sidebar' auto
|
||||
'content footer' auto
|
||||
'content dummy' 1fr
|
||||
/ 1fr 20rem;
|
||||
|
||||
&.has-header {
|
||||
grid-template:
|
||||
'header header' auto
|
||||
'content sidebar' auto
|
||||
'content footer' auto
|
||||
'content dummy' 1fr
|
||||
/ 1fr 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
.content {
|
||||
max-width: calc(60rem - 0.75rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.sidebar {
|
||||
min-width: 20rem;
|
||||
width: 20rem;
|
||||
}
|
||||
}
|
||||
|
||||
@media (min-width: 80rem) {
|
||||
.omorphia__page.has-sidebar {
|
||||
.content {
|
||||
width: calc(60rem - 0.75rem);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user