mirror of
https://github.com/Ocelot-Social-Community/Ocelot-Social.git
synced 2026-01-15 09:24:34 +00:00
Replace styleguide components
This commit is contained in:
parent
25942d17b7
commit
636fda45f2
@ -1,20 +1,73 @@
|
||||
<script setup lang="ts">
|
||||
import Maintenance from './components/maintenance.vue';
|
||||
<template>
|
||||
<transition name="fade" appear>
|
||||
<div class="container">
|
||||
<base-card>
|
||||
<div class="flex-container">
|
||||
<div class="item">
|
||||
<a
|
||||
:href="emails.ORGANIZATION_LINK"
|
||||
:title="$t('login.moreInfo', metadata)"
|
||||
target="_blank"
|
||||
>
|
||||
<img class="image" alt="Under maintenance" src="/img/custom/logo-squared.svg" >
|
||||
</a>
|
||||
</div>
|
||||
<div class="item">
|
||||
<h3>{{ $t('maintenance.title', metadata) }}</h3>
|
||||
</div>
|
||||
<div class="explanation">
|
||||
<p>{{ $t('maintenance.explanation') }}</p>
|
||||
<p>
|
||||
{{ $t('maintenance.questions') }}
|
||||
<a :href="'mailto:' + supportEmail">{{ supportEmail }}</a>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</base-card>
|
||||
</div>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script setup>
|
||||
import emails from '~/constants/emails'
|
||||
import metadata from '~/constants/metadata'
|
||||
|
||||
import BaseCard from '~/components/BaseCard/BaseCard.vue'
|
||||
|
||||
const supportEmail = emails.supportEmail
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<div>
|
||||
<Maintenance />
|
||||
</div>
|
||||
</template>
|
||||
<style src="./style.css" lang="scss" />
|
||||
|
||||
<style>
|
||||
:root {
|
||||
--space-base: 16px;
|
||||
--space-small: 8px;
|
||||
--space-x-small: 6px;
|
||||
--space-xx-small: 4px;
|
||||
--color-locale-menu: #333;
|
||||
}
|
||||
<style scoped lang="scss">
|
||||
@use './media-queries.scss' as media-queries;
|
||||
|
||||
.image {
|
||||
width: 75%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
.flex-container {
|
||||
display: flex;
|
||||
gap: var(--space-small);
|
||||
}
|
||||
|
||||
.item {
|
||||
margin-top: var(--space-small);
|
||||
}
|
||||
|
||||
.container {
|
||||
padding: 0 var(--space-small);
|
||||
margin: 0 auto;
|
||||
|
||||
max-width: var(--md);
|
||||
|
||||
@media #{media-queries.$medium} {
|
||||
padding: 0 var(--space-base);
|
||||
}
|
||||
|
||||
@media #{media-queries.$large} {
|
||||
padding: 0 var(--space-large);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
||||
79
maintenance/components/BaseCard/BaseCard.story.js
Normal file
79
maintenance/components/BaseCard/BaseCard.story.js
Normal file
@ -0,0 +1,79 @@
|
||||
import { storiesOf } from '@storybook/vue'
|
||||
import helpers from '~/storybook/helpers'
|
||||
import logos from '~/constants/logos.js'
|
||||
import BaseCard from './BaseCard.vue'
|
||||
|
||||
storiesOf('Generic/BaseCard', module)
|
||||
.addDecorator(helpers.layout)
|
||||
|
||||
.add('default', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card>
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
|
||||
.add('with slot: hero image', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card style="width: 400px;">
|
||||
<template #heroImage>
|
||||
<img class="image" src="https://unsplash.com/photos/R4y_E5ZQDPg/download" />
|
||||
</template>
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
|
||||
.add('with slot: image column', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card style="width: 600px;">
|
||||
<template #imageColumn>
|
||||
<img class="image" alt="Example image" src="${logos.LOGO_WELCOME_PATH}" />
|
||||
</template>
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
|
||||
.add('with slot: topMenu', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card style="width: 600px;">
|
||||
<template #imageColumn>
|
||||
<img class="image" alt="Example image" src="${logos.LOGO_WELCOME_PATH}" />
|
||||
</template>
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
<template #topMenu>
|
||||
<base-button size="small">Menu</base-button>
|
||||
</template>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
|
||||
.add('with highlight prop', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card highlight style="width: 400px;">
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
|
||||
.add('with wideContent prop', () => ({
|
||||
components: { BaseCard },
|
||||
template: `
|
||||
<base-card wideContent style="width: 400px;">
|
||||
<h2 class="title">I am a card heading</h2>
|
||||
<p>And I am a paragraph.</p>
|
||||
</base-card>
|
||||
`,
|
||||
}))
|
||||
133
maintenance/components/BaseCard/BaseCard.vue
Normal file
133
maintenance/components/BaseCard/BaseCard.vue
Normal file
@ -0,0 +1,133 @@
|
||||
<template>
|
||||
<article :class="classNames">
|
||||
<template v-if="$slots.imageColumn">
|
||||
<aside class="image-column">
|
||||
<slot name="imageColumn" />
|
||||
</aside>
|
||||
<section class="content-column">
|
||||
<slot />
|
||||
</section>
|
||||
</template>
|
||||
|
||||
<template v-else-if="$slots.heroImage">
|
||||
<section class="hero-image">
|
||||
<slot name="heroImage" />
|
||||
</section>
|
||||
<slot />
|
||||
</template>
|
||||
|
||||
<slot v-else />
|
||||
<aside v-if="$slots.topMenu" class="top-menu">
|
||||
<slot name="topMenu" />
|
||||
</aside>
|
||||
</article>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
highlight: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
wideContent: {
|
||||
type: Boolean,
|
||||
default: false,
|
||||
},
|
||||
},
|
||||
computed: {
|
||||
classNames() {
|
||||
let classNames = 'base-card'
|
||||
|
||||
if (this.$slots.imageColumn) classNames += ' --columns'
|
||||
if (this.highlight) classNames += ' --highlight'
|
||||
if (this.wideContent) classNames += ' --wide-content'
|
||||
|
||||
return classNames
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.base-card {
|
||||
position: relative;
|
||||
padding: var(--space-base);
|
||||
border-radius: var(--border-radius-x-large);
|
||||
overflow: hidden;
|
||||
overflow-wrap: break-word;
|
||||
background-color: var(--color-neutral-100);
|
||||
box-shadow: var(--box-shadow-base);
|
||||
|
||||
&.--columns {
|
||||
display: flex;
|
||||
}
|
||||
|
||||
&.--highlight {
|
||||
border: var(--border-size-base) solid var(--color-warning);
|
||||
}
|
||||
|
||||
&.--wide-content {
|
||||
padding: var(--space-small)
|
||||
|
||||
> .hero-image {
|
||||
width: calc(100% + (2 * var(--space-small)));
|
||||
margin: calc(-1 * var(--space-small));
|
||||
margin-bottom: var(--space-small);
|
||||
}
|
||||
}
|
||||
|
||||
> .title,
|
||||
> .content-column > .title {
|
||||
font-size: var(--font-size-large);
|
||||
margin-bottom: var(--space-x-small);
|
||||
}
|
||||
|
||||
> .hero-image {
|
||||
width: calc(100% + (2 * var(--space-base)));
|
||||
max-height: var(--size-image-max-height);
|
||||
margin: calc(-1 * var(--space-base));
|
||||
margin-bottom: var(--space-base);
|
||||
overflow: hidden;
|
||||
|
||||
> .image {
|
||||
width: 100%;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
|
||||
> .image-column {
|
||||
flex-basis: 50%;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
padding-right: var(--space-base);
|
||||
|
||||
.image {
|
||||
width: 100%;
|
||||
max-width: 200px;
|
||||
}
|
||||
}
|
||||
|
||||
> .content-column {
|
||||
flex-basis: 50%;
|
||||
}
|
||||
|
||||
> .top-menu {
|
||||
position: absolute;
|
||||
top: var(--space-small);
|
||||
left: var(--space-small);
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 565px) {
|
||||
.base-card.--columns {
|
||||
flex-direction: column;
|
||||
|
||||
> .image-column {
|
||||
padding-right: 0;
|
||||
margin-bottom: var(--space-base);
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
@ -1,80 +0,0 @@
|
||||
<template>
|
||||
<transition name="fade" appear>
|
||||
<ds-container width="medium">
|
||||
<base-card>
|
||||
<ds-space>
|
||||
<!-- <locale-switch class="login-locale-switch" offset="5" /> -->
|
||||
</ds-space>
|
||||
<ds-flex>
|
||||
<ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }">
|
||||
<ds-space>
|
||||
<!-- QUESTION: could we have internal page or even all internal pages here as well with PageParamsLink by having the footer underneath? -->
|
||||
<!-- I tried this out, but only could get the nginx page displayed. I guees the there were nuxt errors, because the nuxt config file 'webapp/maintenance/source/nuxt.config.maintenance.js' would have to be refactored for that as well and may be the missing folder `components/_new/generic/` plays a role, see https://github.com/Ocelot-Social-Community/Ocelot-Social/pull/4619 -->
|
||||
<!-- <page-params-link :pageParams="links.ORGANIZATION" :title="$t('login.moreInfo', metadata)">
|
||||
<logo type="maintenance" />
|
||||
</page-params-link> -->
|
||||
<!-- BUT: not the logo and not even the a-tag is working at the moment -->
|
||||
<!-- <a
|
||||
:href="emails.ORGANIZATION_LINK"
|
||||
:title="$t('login.moreInfo', metadata)"
|
||||
target="_blank"
|
||||
> -->
|
||||
<img class="image" alt="Under maintenance" src="/img/custom/logo-squared.svg" >
|
||||
<!-- </a> -->
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item :width="{ base: '100%', sm: 1, md: 1 }">
|
||||
<ds-flex-item>
|
||||
<ds-heading tag="h3">{{ $t('maintenance.title', metadata) }}</ds-heading>
|
||||
</ds-flex-item>
|
||||
<ds-flex-item>
|
||||
<ds-space margin="small">
|
||||
<ds-text>{{ $t('maintenance.explanation') }}</ds-text>
|
||||
<ds-text>
|
||||
{{ $t('maintenance.questions') }}
|
||||
<a :href="'mailto:' + supportEmail">{{ supportEmail }}</a>
|
||||
</ds-text>
|
||||
</ds-space>
|
||||
</ds-flex-item>
|
||||
</ds-flex-item>
|
||||
</ds-flex>
|
||||
</base-card>
|
||||
</ds-container>
|
||||
</transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import emails from '~/constants/emails'
|
||||
// import links from '~/constants/links.js'
|
||||
import metadata from '~/constants/metadata'
|
||||
// import LocaleSwitch from '~/components/LocaleSwitch/LocaleSwitch'
|
||||
// import Logo from '~/components/Logo/Logo'
|
||||
|
||||
import { Container as DsContainer, Card as BaseCard, Space as DsSpace, Flex as DsFlex, FlexItem as DsFlexItem, Heading as DsHeading, Text as DsText } from '../lib/styleguide'
|
||||
|
||||
export default {
|
||||
components: {
|
||||
// LocaleSwitch,
|
||||
// Logo,
|
||||
DsContainer,
|
||||
BaseCard,
|
||||
DsSpace,
|
||||
DsFlex,
|
||||
DsFlexItem,
|
||||
DsHeading,
|
||||
DsText,
|
||||
},
|
||||
layout: 'blank',
|
||||
data() {
|
||||
// return { links, metadata, supportEmail: emails.SUPPORT_EMAIL }
|
||||
return { metadata, supportEmail: emails.SUPPORT_EMAIL }
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="scss">
|
||||
.image {
|
||||
width: 75%;
|
||||
height: auto;
|
||||
}
|
||||
</style>
|
||||
@ -10,15 +10,12 @@ import Radio from './data-input/Radio/Radio.vue'
|
||||
import Select from './data-input/Select/Select.vue'
|
||||
import Container from './layout/Container/Container.vue'
|
||||
import Card from './layout/Card/Card.vue'
|
||||
import Flex from './layout/Flex/Flex.vue'
|
||||
import FlexItem from './layout/Flex/FlexItem.vue'
|
||||
import Grid from './layout/Grid/Grid.vue'
|
||||
import Modal from './layout/Modal/Modal.vue'
|
||||
import Page from './layout/Page/Page.vue'
|
||||
import PageTitle from './layout/PageTitle/PageTitle.vue'
|
||||
import Placeholder from './layout/Placeholder/Placeholder.vue'
|
||||
import Section from './layout/Section/Section.vue'
|
||||
import Space from './layout/Space/Space.vue'
|
||||
import Spinner from './layout/Spinner/Spinner.vue'
|
||||
import Button from './navigation/Button/Button.vue'
|
||||
import Menu from './navigation/Menu/Menu.vue'
|
||||
@ -43,15 +40,12 @@ export {
|
||||
Select,
|
||||
Container,
|
||||
Card,
|
||||
Flex,
|
||||
FlexItem,
|
||||
Grid,
|
||||
Modal,
|
||||
Page,
|
||||
PageTitle,
|
||||
Placeholder,
|
||||
Section,
|
||||
Space,
|
||||
Spinner,
|
||||
Button,
|
||||
Menu,
|
||||
|
||||
@ -1,94 +0,0 @@
|
||||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
:style="styles"
|
||||
class="ds-flex">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import { getSpace } from '@@/utils'
|
||||
import { mediaQuery } from '@@/mixins'
|
||||
|
||||
/**
|
||||
* Used in combination with the flex item component to create flexible layouts.
|
||||
* @version 1.0.0
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'DsFlex',
|
||||
mixins: [mediaQuery],
|
||||
|
||||
provide() {
|
||||
return {
|
||||
$parentFlex: this
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* Default gutter size of columns
|
||||
*/
|
||||
gutter: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* Default width of columns
|
||||
*/
|
||||
width: {
|
||||
type: [String, Number, Object],
|
||||
default: 1
|
||||
},
|
||||
/**
|
||||
* Direction of the flex items
|
||||
* @options row|row-reverse|column|column-reverse
|
||||
*/
|
||||
direction: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* The outtermost html tag
|
||||
*/
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
styles() {
|
||||
const gutter = this.mediaQuery(this.gutter)
|
||||
const direction = this.mediaQuery(this.direction)
|
||||
const gutterStyle = gutter ? this.parseGutter(gutter) : {}
|
||||
const directionStyle = direction ? this.parseDirection(direction) : {}
|
||||
return {
|
||||
...gutterStyle,
|
||||
...directionStyle
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseGutter(gutter: string) {
|
||||
const realGutter = getSpace(gutter)
|
||||
return {
|
||||
marginLeft: `-${realGutter / 2}px`,
|
||||
marginRight: `-${realGutter / 2}px`
|
||||
}
|
||||
},
|
||||
parseDirection(direction: string) {
|
||||
return {
|
||||
flexDirection: direction
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="./style.scss">
|
||||
</style>
|
||||
|
||||
@ -1,107 +0,0 @@
|
||||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
:style="styles"
|
||||
class="ds-flex-item">
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import { getSpace } from '@@/utils'
|
||||
import { mediaQuery } from '@@/mixins'
|
||||
|
||||
/**
|
||||
* @version 1.0.0
|
||||
* @see DsFlex
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'DsFlexItem',
|
||||
mixins: [mediaQuery],
|
||||
|
||||
inject: {
|
||||
$parentFlex: {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* The item's width
|
||||
* @default 1
|
||||
*/
|
||||
width: {
|
||||
type: [String, Number, Object],
|
||||
default() {
|
||||
return this.$parentFlex ? this.$parentFlex.width : 1
|
||||
}
|
||||
},
|
||||
/**
|
||||
* The outtermost html tag
|
||||
*/
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
},
|
||||
|
||||
/**
|
||||
* Center content vertical and horizontal
|
||||
*/
|
||||
centered: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
gutter() {
|
||||
return this.$parentFlex ? this.$parentFlex.gutter : 0
|
||||
},
|
||||
styles() {
|
||||
const width = this.mediaQuery(this.width)
|
||||
const gutter = this.mediaQuery(this.gutter)
|
||||
const widthStyle = this.parseWidth(width)
|
||||
const gutterStyle = this.parseGutter(gutter)
|
||||
const centerStyle = this.centered
|
||||
? {
|
||||
'align-self': 'center',
|
||||
'jusify-self': 'center'
|
||||
}
|
||||
: {}
|
||||
return {
|
||||
...widthStyle,
|
||||
...gutterStyle,
|
||||
...centerStyle
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseWidth(width: string | number) {
|
||||
const styles = {}
|
||||
if (isNaN(width)) {
|
||||
styles.flexBasis = width
|
||||
styles.width = width
|
||||
} else {
|
||||
styles.flexGrow = width
|
||||
styles.flexShrink = 0
|
||||
styles.flexBasis = 0
|
||||
}
|
||||
return styles
|
||||
},
|
||||
parseGutter(gutter: string) {
|
||||
const realGutter = getSpace(gutter)
|
||||
if (realGutter === 0) {
|
||||
return {}
|
||||
}
|
||||
return {
|
||||
paddingLeft: `${realGutter / 2}px`,
|
||||
paddingRight: `${realGutter / 2}px`,
|
||||
marginBottom: `${realGutter}px`
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
@ -1,12 +0,0 @@
|
||||
@use "@@/styles/shared" as *;
|
||||
|
||||
.ds-flex {
|
||||
@include reset;
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
}
|
||||
|
||||
.ds-flex-item {
|
||||
@include reset;
|
||||
@include layout-flex-fix;
|
||||
}
|
||||
@ -1,119 +0,0 @@
|
||||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
:style="styles"
|
||||
class="ds-space"
|
||||
:class="[
|
||||
centered && 'ds-space-centered'
|
||||
]"
|
||||
>
|
||||
<slot />
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import { getSpace } from '@@/utils'
|
||||
import { mediaQuery } from '@@/mixins'
|
||||
|
||||
/**
|
||||
* Use this component for grouping and separation.
|
||||
* @version 1.0.0
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'DsSpace',
|
||||
mixins: [mediaQuery],
|
||||
|
||||
inject: {
|
||||
$parentRow: {
|
||||
default: null
|
||||
}
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* The top margin of this space.
|
||||
*/
|
||||
marginTop: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
/**
|
||||
* The bottom margin of this space.
|
||||
*/
|
||||
marginBottom: {
|
||||
type: [String, Object],
|
||||
default: 'large'
|
||||
},
|
||||
/**
|
||||
* The bottom and top margin of this space.
|
||||
*/
|
||||
margin: {
|
||||
type: [String, Object],
|
||||
default: null
|
||||
},
|
||||
|
||||
/**
|
||||
* Center content vertacally and horizontally
|
||||
*/
|
||||
centered: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* The html element name used for this space.
|
||||
*/
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
}
|
||||
},
|
||||
|
||||
computed: {
|
||||
styles() {
|
||||
const top = this.margin ? this.margin : this.marginTop
|
||||
const bottom = this.margin ? this.margin : this.marginBottom
|
||||
|
||||
const marginTop = this.mediaQuery(top)
|
||||
const marginBottom = this.mediaQuery(bottom)
|
||||
const marginTopStyle = this.parseMargin('Top')(marginTop)
|
||||
const marginBottomStyle = this.parseMargin('Bottom')(marginBottom)
|
||||
const centerStyle = this.centered
|
||||
? {
|
||||
'text-align': 'center',
|
||||
flex: 1,
|
||||
'align-content': 'center',
|
||||
'jusify-content': 'center'
|
||||
}
|
||||
: {}
|
||||
|
||||
return {
|
||||
...marginTopStyle,
|
||||
...marginBottomStyle,
|
||||
...centerStyle
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
methods: {
|
||||
parseMargin(direction) {
|
||||
return margin => {
|
||||
const styles = {}
|
||||
if (!margin) {
|
||||
return styles
|
||||
}
|
||||
const realMargin = getSpace(margin)
|
||||
if (realMargin !== 0) {
|
||||
styles[`margin${direction}`] = `${realMargin}px`
|
||||
}
|
||||
return styles
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="./style.scss">
|
||||
</style>
|
||||
|
||||
@ -1,9 +0,0 @@
|
||||
@use "@@/styles/shared" as *;
|
||||
|
||||
.ds-space {
|
||||
@include reset;
|
||||
}
|
||||
|
||||
.ds-space-centered {
|
||||
text-align: center;
|
||||
}
|
||||
@ -0,0 +1,55 @@
|
||||
<template>
|
||||
<component
|
||||
:is="tag"
|
||||
class="ds-logo"
|
||||
:class="[inverse && 'ds-logo-inverse']"
|
||||
>
|
||||
<svg-logo
|
||||
v-if="!inverse"
|
||||
class="ds-logo-svg"
|
||||
/>
|
||||
<svg-logo-inverse
|
||||
v-else
|
||||
class="ds-logo-svg"
|
||||
/>
|
||||
</component>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { defineComponent } from 'vue';
|
||||
|
||||
import svgLogo from '@@/assets/img/Logo-Horizontal.svg'
|
||||
import svgLogoInverse from '@@/assets/img/Logo-Horizontal-Dark.svg'
|
||||
/**
|
||||
* This component displays the brand's logo.
|
||||
* @version 1.0.0
|
||||
*/
|
||||
export default defineComponent({
|
||||
name: 'DsLogo',
|
||||
|
||||
components: {
|
||||
svgLogo,
|
||||
svgLogoInverse
|
||||
},
|
||||
|
||||
props: {
|
||||
/**
|
||||
* Inverse the logo
|
||||
*/
|
||||
inverse: {
|
||||
type: Boolean,
|
||||
default: false
|
||||
},
|
||||
/**
|
||||
* The html element name used for the logo.
|
||||
*/
|
||||
tag: {
|
||||
type: String,
|
||||
default: 'div'
|
||||
}
|
||||
},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" src="./style.scss">
|
||||
</style>
|
||||
@ -0,0 +1,20 @@
|
||||
@use "@@/styles/shared" as *;
|
||||
@use "@@/styles/tokens/tokens" as *;
|
||||
|
||||
.ds-logo {
|
||||
@include reset;
|
||||
display: inline-flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
color: $text-color-primary;
|
||||
}
|
||||
|
||||
.ds-logo-inverse {
|
||||
color: $text-color-primary-inverse;
|
||||
}
|
||||
|
||||
.ds-logo-svg {
|
||||
width: 130px;
|
||||
height: auto;
|
||||
fill: currentColor;
|
||||
}
|
||||
@ -1,9 +1,8 @@
|
||||
import '@@/styles/main.scss'
|
||||
|
||||
import * as utils from './utils'
|
||||
import * as mixins from './mixins'
|
||||
|
||||
export * from './components'
|
||||
|
||||
export { utils, mixins }
|
||||
export { utils }
|
||||
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
import mediaQuery from './media-query'
|
||||
|
||||
export { mediaQuery }
|
||||
@ -1,62 +0,0 @@
|
||||
import { tokenMap } from '@@/styles/tokens'
|
||||
|
||||
const windowSize = {
|
||||
width: null,
|
||||
height: null,
|
||||
}
|
||||
|
||||
function updateWindowSize() {
|
||||
windowSize.width =
|
||||
document.documentElement.clientWidth || document.body.clientWidth
|
||||
|
||||
windowSize.height =
|
||||
document.documentElement.clientHeight || document.body.clientHeight
|
||||
}
|
||||
|
||||
let init = false
|
||||
|
||||
function initListener() {
|
||||
if (init) {
|
||||
return
|
||||
}
|
||||
try {
|
||||
if (window && typeof window !== 'undefined') {
|
||||
window.addEventListener('resize', updateWindowSize)
|
||||
updateWindowSize()
|
||||
}
|
||||
init = true
|
||||
} catch (err) {
|
||||
init = true
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @mixin
|
||||
*/
|
||||
export default {
|
||||
data() {
|
||||
return {
|
||||
mediaQueryWindowSize: windowSize,
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
mediaQuery(arg) {
|
||||
initListener()
|
||||
if (arg === null || typeof arg !== 'object') {
|
||||
return arg
|
||||
}
|
||||
let result = arg.base
|
||||
Object.keys(tokenMap.mediaSize)
|
||||
.reverse()
|
||||
.some((key) => {
|
||||
const width = tokenMap.mediaSize[key].value
|
||||
if (width <= this.mediaQueryWindowSize.width && arg[key]) {
|
||||
result = arg[key]
|
||||
return true
|
||||
}
|
||||
})
|
||||
return result
|
||||
},
|
||||
},
|
||||
}
|
||||
5
maintenance/media-queries.scss
Normal file
5
maintenance/media-queries.scss
Normal file
@ -0,0 +1,5 @@
|
||||
$x-small: '(screen and (min-width: 480px))';
|
||||
$small: '(screen and (min-width: 600px))';
|
||||
$medium: '(screen and (min-width: 768px))';
|
||||
$large: '(screen and (min-width: 1024px))';
|
||||
$x-large: '(screen and (min-width: 1200px))';
|
||||
@ -30,7 +30,7 @@ export default defineNuxtConfig({
|
||||
plugins: [viteTsConfigPaths()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@@': resolve(__dirname, './src'),
|
||||
'@@': resolve(__dirname, './lib/styleguide'),
|
||||
}
|
||||
},
|
||||
build: {
|
||||
|
||||
280
maintenance/style.css
Normal file
280
maintenance/style.css
Normal file
@ -0,0 +1,280 @@
|
||||
:root {
|
||||
/* Color Brand */
|
||||
--color-primary: rgb(23, 181, 63);
|
||||
--color-primary-light: rgb(96, 214, 98);
|
||||
--color-primary-dark: rgb(25, 122, 49);
|
||||
--color-primary-active: rgb(25, 194, 67);
|
||||
--color-primary-inverse: rgb(241, 253, 244);
|
||||
--color-secondary: rgb(0, 142, 230);
|
||||
--color-secondary-active: rgb(10, 161, 255);
|
||||
--color-secondary-inverse: rgb(240, 249, 255);
|
||||
--color-success: rgb(23, 181, 63);
|
||||
--color-success-active: rgb(26, 203, 71);
|
||||
--color-success-inverse: rgb(241, 253, 244);
|
||||
--color-danger: rgb(219, 57, 36);
|
||||
--color-danger-light: rgb(242, 97, 65);
|
||||
--color-danger-dark: rgb(158, 43, 28);
|
||||
--color-danger-active: rgb(224, 81, 62);
|
||||
--color-danger-inverse: rgb(253, 243, 242);
|
||||
--color-warning: rgb(230, 121, 25);
|
||||
--color-warning-active: rgb(233, 137, 53);
|
||||
--color-warning-inverse: rgb(253, 247, 241);
|
||||
--color-yellow: rgb(245, 196, 0);
|
||||
--color-yellow-active: rgb(255, 206, 10);
|
||||
--color-yellow-inverse: rgb(255, 252, 240);
|
||||
|
||||
/* Color Neutral */
|
||||
--color-neutral-0: rgb(25, 23, 28);
|
||||
--color-neutral-10: rgb(40, 37, 45);
|
||||
--color-neutral-20: rgb(75, 69, 84);
|
||||
--color-neutral-30: rgb(100, 92, 112);
|
||||
--color-neutral-40: rgb(112, 103, 126);
|
||||
--color-neutral-50: rgb(151, 143, 163);
|
||||
--color-neutral-60: rgb(177, 171, 186);
|
||||
--color-neutral-70: rgb(203, 199, 209);
|
||||
--color-neutral-80: rgb(229, 227, 232);
|
||||
--color-neutral-85: rgb(239, 238, 241);
|
||||
--color-neutral-90: rgb(245, 244, 246);
|
||||
--color-neutral-95: rgb(250, 249, 250);
|
||||
--color-neutral-100: rgb(255, 255, 255);
|
||||
|
||||
/* Color Text */
|
||||
--text-color-base: rgb(75, 69, 84);
|
||||
--text-color-soft: rgb(112, 103, 126);
|
||||
--text-color-softer: rgb(177, 171, 186);
|
||||
--text-color-disabled: rgb(177, 171, 186);
|
||||
--text-color-inverse: rgb(250, 249, 250);
|
||||
--text-color-link: rgb(23, 181, 63);
|
||||
--text-color-link-active: rgb(25, 194, 67);
|
||||
--text-color-primary: rgb(23, 181, 63);
|
||||
--text-color-primary-inverse: rgb(241, 253, 244);
|
||||
--text-color-secondary: rgb(0, 142, 230);
|
||||
--text-color-secondary-inverse: rgb(240, 249, 255);
|
||||
--text-color-success: rgb(23, 181, 63);
|
||||
--text-color-success-inverse: rgb(241, 253, 244);
|
||||
--text-color-warning: rgb(230, 121, 25);
|
||||
--text-color-warning-inverse: rgb(253, 247, 241);
|
||||
--text-color-danger: rgb(219, 57, 36);
|
||||
--text-color-danger-inverse: rgb(253, 243, 242);
|
||||
|
||||
/* Color Background */
|
||||
--background-color-base: rgb(255, 255, 255);
|
||||
--background-color-soft: rgb(250, 249, 250);
|
||||
--background-color-softer: rgb(245, 244, 246);
|
||||
--background-color-softer-active: rgb(250, 249, 250);
|
||||
--background-color-softest: rgb(239, 238, 241);
|
||||
--background-color-softest-active: rgb(245, 244, 246);
|
||||
--background-color-inverse: rgb(25, 23, 28);
|
||||
--background-color-inverse-soft: rgb(40, 37, 45);
|
||||
--background-color-inverse-softer: rgb(75, 69, 84);
|
||||
--background-color-inverse-softer-active: rgb(100, 92, 112);
|
||||
--background-color-disabled: rgb(245, 244, 246);
|
||||
--background-color-primary: rgb(23, 181, 63);
|
||||
--background-color-primary-active: rgb(25, 194, 67);
|
||||
--background-color-primary-inverse: rgb(241, 253, 244);
|
||||
--background-color-secondary: rgb(0, 142, 230);
|
||||
--background-color-secondary-active: rgb(10, 161, 255);
|
||||
--background-color-secondary-inverse: rgb(240, 249, 255);
|
||||
--background-color-third: rgb(126, 82, 204);
|
||||
--background-color-third-active: rgb(160, 103, 255);
|
||||
--background-color-third-inverse: rgb(239, 230, 255);
|
||||
--background-color-success: rgb(23, 181, 63);
|
||||
--background-color-success-active: rgb(26, 203, 71);
|
||||
--background-color-success-inverse: rgb(241, 253, 244);
|
||||
--background-color-warning: rgb(230, 121, 25);
|
||||
--background-color-warning-active: rgb(233, 137, 53);
|
||||
--background-color-warning-inverse: rgb(253, 247, 241);
|
||||
--background-color-danger: rgb(219, 57, 36);
|
||||
--background-color-danger-active: rgb(224, 81, 62);
|
||||
--background-color-danger-inverse: rgb(253, 243, 242);
|
||||
|
||||
/* Color Border */
|
||||
--border-color-base: rgb(177, 171, 186);
|
||||
--border-color-soft: rgb(203, 199, 209);
|
||||
--border-color-softer: rgb(229, 227, 232);
|
||||
--border-color-softest: rgb(245, 244, 246);
|
||||
--border-color-active: rgb(23, 181, 63);
|
||||
--border-color-primary: rgb(23, 181, 63);
|
||||
--border-color-success: rgb(23, 181, 63);
|
||||
--border-color-warning: rgb(230, 121, 25);
|
||||
--border-color-danger: rgb(219, 57, 36);
|
||||
|
||||
/* Border Size */
|
||||
--border-size-base: 1px;
|
||||
--border-size-large: 3px;
|
||||
--border-size-x-large: 6px;
|
||||
|
||||
/* Border Radius */
|
||||
--border-radius-x-large: 5px;
|
||||
--border-radius-large: 4px;
|
||||
--border-radius-base: 4px;
|
||||
--border-radius-small: 2px;
|
||||
--border-radius-rounded: 2em;
|
||||
--border-radius-circle: 50%;
|
||||
|
||||
/* Font Size */
|
||||
--font-size-xxxx-large: 3rem;
|
||||
--font-size-xxx-large: 2.5rem;
|
||||
--font-size-xx-large: 2rem;
|
||||
--font-size-x-large: 1.5rem;
|
||||
--font-size-large: 1.25rem;
|
||||
--font-size-base: 1rem;
|
||||
--font-size-body: 15px;
|
||||
--font-size-small: 0.8rem;
|
||||
--font-size-x-small: 0.7rem;
|
||||
--font-size-xx-small: 0.6rem;
|
||||
|
||||
/* Font Space */
|
||||
--font-space-xxxx-large: 2em;
|
||||
--font-space-xxx-large: 1.5em;
|
||||
--font-space-xx-large: 1.2em;
|
||||
--font-space-x-large: 1em;
|
||||
--font-space-large: 0.6em;
|
||||
--font-space-base: 0.5em;
|
||||
--font-space-small: 0.4em;
|
||||
--font-space-x-small: 0.3em;
|
||||
--font-space-xx-small: 0.2em;
|
||||
--font-space-xxx-small: 0.1em;
|
||||
|
||||
/* Font Family */
|
||||
--font-family-heading: 'LatoWeb', sans-serif;
|
||||
--font-family-text: 'LatoWeb', sans-serif;
|
||||
--font-family-serif: 'Gentium Basic', serif;
|
||||
--font-family-code: inconsolata, monospace;
|
||||
|
||||
/* Font Weight */
|
||||
--font-weight-regular: normal;
|
||||
--font-weight-bold: 600;
|
||||
|
||||
/* Line Height */
|
||||
--line-height-large: 1.5rem;
|
||||
--line-height-base: 1.3rem;
|
||||
--line-height-small: 1.1rem;
|
||||
--line-height-smaller: 1.0rem;
|
||||
|
||||
/* Letter Spacing */
|
||||
--letter-spacing-x-large: 0.1em;
|
||||
--letter-spacing-large: 0.05em;
|
||||
--letter-spacing-base: 0;
|
||||
--letter-spacing-small: -0.01em;
|
||||
--letter-spacing-x-small: -0.015em;
|
||||
|
||||
/* Opacity */
|
||||
--opacity-base: 1;
|
||||
--opacity-soft: 0.7;
|
||||
--opacity-disabled: 0.5;
|
||||
|
||||
/* Space */
|
||||
--space-xxx-large: 128px;
|
||||
--space-xx-large: 64px;
|
||||
--space-x-large: 48px;
|
||||
--space-large: 32px;
|
||||
--space-base: 24px;
|
||||
--space-small: 16px;
|
||||
--space-x-small: 8px;
|
||||
--space-xx-small: 4px;
|
||||
--space-xxx-small: 2px;
|
||||
--space-none: 0;
|
||||
|
||||
/* Size Height */
|
||||
--size-height-base: 42px;
|
||||
--size-height-large: 50px;
|
||||
--size-height-xlarge: 60px;
|
||||
--size-height-footer: 64px;
|
||||
--size-height-connections: 315px;
|
||||
--size-tappable-square: 44px;
|
||||
--size-ribbon: 6px;
|
||||
|
||||
/* Size Width */
|
||||
--size-width-filter-sidebar: 85px;
|
||||
--size-width-paginate: 200px;
|
||||
--size-max-width-filter-menu: 1026px;
|
||||
|
||||
/* Size Avatar */
|
||||
--size-avatar-small: 34px;
|
||||
--size-avatar-base: 44px;
|
||||
--size-avatar-large: 114px;
|
||||
|
||||
/* Size Buttons */
|
||||
--size-button-large: 50px;
|
||||
--size-button-base: 36px;
|
||||
--size-button-small: 26px;
|
||||
|
||||
/* Size Images */
|
||||
--size-image-max-height: 2000px;
|
||||
--size-image-cropper-max-height: 600px;
|
||||
--size-image-cropper-min-height: 400px;
|
||||
--size-image-uploader-min-height: 250px;
|
||||
|
||||
/* Size Icons */
|
||||
--size-icon-base: 16px;
|
||||
--size-icon-large: 60px;
|
||||
|
||||
/* Shadow */
|
||||
--box-shadow-x-large: 0 15px 30px 0 rgba(0,0,0,.11),0 5px 15px 0 rgba(0,0,0,.08);
|
||||
--box-shadow-large: 0 10px 20px 0 rgba(0,0,0,.11),0 3px 10px 0 rgba(0,0,0,.08);
|
||||
--box-shadow-base: 0px 12px 26px -4px rgba(0, 0, 0, .1);
|
||||
--box-shadow-small: 0px 8px 18px -2px rgba(0, 0, 0, .1);
|
||||
--box-shadow-x-small: 0px 0px 3px 0px rgba(0, 0, 0, .1);
|
||||
--box-shadow-active: 0 0 6px 1px rgba(20, 100, 160, 0.5);
|
||||
--box-shadow-inset: inset 0 0 20px 1px rgba(0,0,0,.15);
|
||||
--box-shadow-small-inset: inset 0 0 0 1px rgba(0,0,0,.05);
|
||||
|
||||
/* Effects */
|
||||
--blur-radius: 22px;
|
||||
|
||||
/* Animation Duration */
|
||||
--duration-short: 0.08s;
|
||||
--duration-base: 0.5s;
|
||||
--duration-long: 0.75s;
|
||||
--duration-x-long: 1s;
|
||||
--duration-xx-long: 2s;
|
||||
|
||||
/* Animation Ease */
|
||||
--ease-out: cubic-bezier(0.25, 0.46, 0.45, 0.94);
|
||||
--ease-out-sharp: cubic-bezier(0.165, 0.84, 0.44, 1);
|
||||
--ease-out-bounce: cubic-bezier(.87,-.41,.19,1.44);
|
||||
--ease-in: cubic-bezier(0.55, 0.085, 0.68, 0.53);
|
||||
--ease-in-sharp: cubic-bezier(0.895, 0.03, 0.685, 0.22);
|
||||
|
||||
/* Z-Index */
|
||||
--z-index-modal: 9999;
|
||||
--z-index-overlay: 9000;
|
||||
--z-index-dropdown: 8888;
|
||||
--z-index-page-submenu: 2500;
|
||||
--z-index-page-header: 2000;
|
||||
--z-index-page-sidebar: 1500;
|
||||
--z-index-sticky-float: 150;
|
||||
--z-index-sticky: 100;
|
||||
--z-index-post-teaser-link: 5;
|
||||
--z-index-surface: 1;
|
||||
|
||||
/* Custom Tokens (Footer, Header, etc.) */
|
||||
--color-header-background: var(--color-neutral-100);
|
||||
--color-footer-background: var(--color-neutral-100);
|
||||
--color-footer-link: var(--color-primary);
|
||||
--color-locale-menu: var(--text-color-soft);
|
||||
--color-donation-bar: var(--color-primary);
|
||||
--color-donation-bar-light: var(--color-primary-light);
|
||||
--color-toast-red: var(--color-danger);
|
||||
--color-toast-orange: var(--color-warning);
|
||||
--color-toast-yellow: var(--color-yellow);
|
||||
--color-toast-blue: var(--color-secondary);
|
||||
--color-toast-green: var(--color-success);
|
||||
--color-ribbon-event: var(--background-color-third);
|
||||
--color-ribbon-event-active: var(--background-color-third-active);
|
||||
--color-ribbon-article: var(--background-color-secondary);
|
||||
--color-ribbon-article-active: var(--background-color-secondary-active);
|
||||
|
||||
/* Chat Tokens */
|
||||
--chat-message-bg-me: var(--color-primary-light);
|
||||
--chat-message-color: var(--text-color-base);
|
||||
--chat-message-bg-others: var(--color-neutral-80);
|
||||
--chat-sidemenu-bg: var(--color-secondary-active);
|
||||
--chat-new-message-color: var(--color-secondary-active);
|
||||
--chat-message-timestamp: var(--text-color-soft);
|
||||
--chat-message-checkmark-seen: var(--text-color-secondary);
|
||||
--chat-message-checkmark: var(--text-color-soft);
|
||||
--chat-room-color-counter-badge: var(--text-color-inverse);
|
||||
--chat-room-background-counter-badge: var(--color-secondary);
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user