Skip to content

Commit

Permalink
Merge branch 'main' into UI-367
Browse files Browse the repository at this point in the history
  • Loading branch information
GhitaNektt committed Jun 24, 2024
2 parents c7fda77 + 6257e08 commit 22a7e2a
Show file tree
Hide file tree
Showing 16 changed files with 257 additions and 176 deletions.
58 changes: 8 additions & 50 deletions packages/alto/src/_dev/App.vue
Original file line number Diff line number Diff line change
@@ -1,67 +1,25 @@
<script setup lang="ts">
import 'uno.css';
import '../assets/main.css';
import { ref } from 'vue';
import { Button, Popover } from '~/components';
const show = ref(false);
import { Loader } from '~/components';
</script>

<template>
<div class="container">
<Popover
v-model:show="show"
position="top"
object-fit="cover"
class="popover"
@click-outside="show = false"
>
<template #title>
Introducing Themes!
</template>
<template #description>
<p class="mr-0">
Introducing themes, a new way to make your store stand out
</p>
</template>
<template #footer>
<div class="actions">
<Button variant="primary" @click="show = false">
Get started
</Button>
<Button variant="tertiary" @click="show = false">
Later
</Button>
</div>
</template>
<Button variant="primary" @click="show = !show;">
<span>Show Popover</span>
</Button>
</Popover>
<Loader variant="spinner" label="Loading..." />
<Loader variant="brand" />
<Loader variant="bar" />
</div>
</template>

<style scoped>
.container {
display: flex;
flex-direction: column;
flex-direction: row;
align-items: center;
justify-content: center;
height: 95vh;
padding: 10px;
}
.mr-0 {
margin: 0;
}
.actions {
display: flex;
flex-direction: row-reverse;
justify-content: flex-end;
column-gap: 10px;
}
.popover {
z-index: 99;
width: 100vw;
height: 100vh;
gap: 80px;
}
</style>
4 changes: 2 additions & 2 deletions packages/alto/src/components/Dropdown/Dropdown.vue
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { elementChildrenNavigate } from './utils';
import type { DropdownGroupValue } from './types';
import type { DropdownProps, DropdownValue } from '~/types';
import { setPosition } from '~/helpers';
import { Spinner } from '~/components';
import { Loader } from '~/components';
const props = withDefaults(defineProps<DropdownProps>(), {
multiSelectLabel: 'Selected items',
Expand Down Expand Up @@ -342,7 +342,7 @@ onClickOutside(dropdown, () => show.value = false);
{{ noDataText }}
</div>
<div v-if="isLoading" class="loading">
<Spinner :size="15" />
<Loader :size="15" />
</div>
</div>
</Transition>
Expand Down
39 changes: 39 additions & 0 deletions packages/alto/src/components/Loader/Loader.stories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { Meta, StoryObj } from '@storybook/vue3';
import { Loader } from '~/components';

type Story = StoryObj<typeof Loader>;
const meta: Meta<typeof Loader> = {
title: 'Application/Loader',
component: Loader,
tags: ['loader', 'loading', 'spinner'],
argTypes: {
variant: {
control: 'select',
options: ['spinner', 'brand', 'bar'],
},
labelFontSize: {
control: 'select',
options: ['xs', 'sm', 'md', 'lg', 'xl'],
},
},
args: {
variant: 'spinner',
size: 40,
label: '',
labelFontSize: 'md',
color: 'var(--brand-500)',
labelColor: 'var(--brand-500)',
},
};

export const Default: Story = {
render: args => ({
components: { Loader },
setup() {
return { args };
},
template: '<Loader v-bind="args" />',
}),
};

export default meta;
69 changes: 69 additions & 0 deletions packages/alto/src/components/Loader/Loader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
<script setup lang="ts">
import { computed, defineAsyncComponent } from 'vue';
import type { LoaderProps } from '~/types';
const props = withDefaults(
defineProps<LoaderProps>(),
{
color: 'var(--brand-500)',
size: 40,
labelColor: 'var(--brand-500)',
labelFontSize: 'md',
variant: 'spinner',
},
);
const loader = computed (() => {
switch (props.variant) {
case 'brand':
return defineAsyncComponent(() => import('./internal/BrandLoading.vue'));
case 'bar':
return defineAsyncComponent(() => import('./internal/BarLoading.vue'));
default:
return defineAsyncComponent(() => import('./internal/Spinner.vue'));
}
});
</script>

<template>
<div class="loader-block">
<component :is="loader" :color="color" :size="size" />

<p v-if="label" class="label" :class="[labelFontSize]">
{{ label }}
</p>
</div>
</template>

<style scoped>
.loader-block {
display: flex;
flex-direction: column;
align-items: center;
gap: 10px;
}
.loader-block .label {
margin: 0;
color: v-bind("labelColor");
font: var(--text-md-regular);
}
.loader-block .label.xs {
font: var(--text-xs-regular);
}
.loader-block .label.sm {
font: var(--text-sm-regular);
}
.loader-block .label.lg {
font: var(--text-lg-regular);
}
.loader-block .label.xl {
font: var(--text-xl-regular);
}
</style>
Binary file not shown.
35 changes: 35 additions & 0 deletions packages/alto/src/components/Loader/internal/BarLoading.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script setup lang="ts">
import type { BarLoadingProps } from '~/types';
defineProps<BarLoadingProps>();
</script>

<template>
<div class="bar-loading" />
</template>

<style scoped>
.bar-loading {
position: relative;
width: 160px;
height: 4px;
overflow: hidden;
border-radius: 2px;
background-color: var(--gray-100);
}
.bar-loading::before {
content: "";
display: block;
width: 100%;
height: 100%;
animation: progress 1200ms ease-in-out backwards alternate infinite;
border-radius: 2px;
background-color: v-bind(color);
}
@keyframes progress {
0% { transform: translateX(-93%); }
100% { transform: translateX(93%); }
}
</style>
43 changes: 43 additions & 0 deletions packages/alto/src/components/Loader/internal/BrandLoading.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { BrandLoadingProps } from '~/types';
const props = withDefaults(defineProps<BrandLoadingProps>(), {
size: 67,
});
const percent = 59 / 67;
const height = computed(() => `${props.size * percent}px`);
const width = computed(() => `${props.size}px`);
</script>

<template>
<svg class="animated-svg" :width="width" :height="height" viewBox="0 0 67 59" :fill="color" :stroke="color" xmlns="http://www.w3.org/2000/svg">
<path d="M32.4472 28.5835H13.1062L0.765851 0.5H20.1169L32.4472 28.5835Z" />
<path d="M33.6705 29.2951L33.6705 29.295L46.319 0.5H65.6703L53.1985 28.8927L53.1984 28.8928L40.5501 57.667H21.1989L33.6705 29.2951Z" />
</svg>
</template>

<style scoped>
.animated-svg path {
animation: draw 1500ms linear forwards infinite;
stroke-dasharray: 163.58;
fill: var(--gray-100);
}
@keyframes draw {
0% { stroke-dashoffset: 163.58; }
40%,
50% {
stroke-dashoffset: 0;
fill: var(--gray-100);
}
85%,
100% {
stroke-dashoffset: 0;
fill: v-bind(color);
}
}
</style>
31 changes: 31 additions & 0 deletions packages/alto/src/components/Loader/internal/Spinner.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
<script setup lang="ts">
import { computed } from 'vue';
import type { SpinnerProps } from '~/types';
const props = defineProps<SpinnerProps>();
const spinnerSize = computed(() => `${props.size}px`);
const borderWidth = computed(() => `${props.size * 0.1}px`);
</script>

<template>
<div class="spinner" />
</template>

<style scoped>
.spinner {
box-sizing: border-box;
width: v-bind(spinnerSize);
animation: s4 1s infinite linear;
border: v-bind(borderWidth) solid var(--gray-100);
border-radius: 50%;
border-right-color: v-bind(color);
aspect-ratio: 1;
}
@keyframes s4 {
100% {
transform: rotate(1turn);
}
}
</style>
23 changes: 23 additions & 0 deletions packages/alto/src/components/Loader/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
export type SpinnerVariant = 'brand' | 'bar' | 'spinner';
export type LabelSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';

interface SharedProps {
size: number
color?: string
}
export interface BarLoadingProps {
color?: string
}

export interface BrandLoadingProps extends SharedProps {}

export interface SpinnerProps extends SharedProps {}

export interface LoaderProps {
label?: string
size?: number
color?: string
labelColor?: string
labelFontSize?: LabelSize
variant?: SpinnerVariant
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import ResourceItem from './Internal/Resource.vue';
import { isEmptyArray } from './utils';
import type { PickerProps, Resource } from '~/types';
import Overlay from '~/components/Overlay/Overlay.vue';
import { Button, Input, Spinner } from '~/components';
import { Button, Input, Loader } from '~/components';
const props = withDefaults(defineProps<PickerProps>(), {
visible: false,
Expand Down Expand Up @@ -120,7 +120,7 @@ onUnmounted(() => {
<Input v-model.trim="term" :placeholder="searchPlaceholder" @input.stop="handleSearch" @keyup.enter.stop="handleSearch" />
</div>
<div v-if="isLoading" class="loading">
<Spinner label="" />
<Loader />
</div>
<ul v-else-if="!isEmptyArray(resources)" class="list">
<li v-for="resource in resources" :key="resource.id" class="resource">
Expand Down
41 changes: 0 additions & 41 deletions packages/alto/src/components/Spinner/Spinner.stories.ts

This file was deleted.

Loading

0 comments on commit 22a7e2a

Please sign in to comment.