@dolanske/vui 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +27 -99
- package/dist/components/Accordion/Accordion.vue.d.ts +1 -0
- package/dist/components/Avatar/Avatar.vue.d.ts +4 -2
- package/dist/components/Divider/Divider.vue.d.ts +2 -4
- package/dist/components/Dropdown/Dropdown.vue.d.ts +105 -0
- package/dist/components/Input/Dropzone.vue.d.ts +1 -0
- package/dist/components/Input/Input.vue.d.ts +1 -0
- package/dist/components/Popout/Popout.vue.d.ts +3 -3
- package/dist/components/Radio/Radio.vue.d.ts +1 -1
- package/dist/components/Radio/RadioGroup.vue.d.ts +3 -12
- package/dist/components/Tooltip/Tooltip.vue.d.ts +1 -1
- package/dist/shared/helpers.d.ts +6 -0
- package/dist/shared/types.d.ts +3 -0
- package/dist/style.css +1 -1
- package/dist/vui.js +3922 -3842
- package/package.json +1 -1
- package/src/App.vue +7 -19
- package/src/components/Accordion/Accordion.vue +8 -4
- package/src/components/Accordion/accordion.scss +38 -2
- package/src/components/Avatar/Avatar.vue +25 -4
- package/src/components/Avatar/avatar.scss +5 -5
- package/src/components/Button/Button.vue +4 -4
- package/src/components/Calendar/Calendar.vue +10 -8
- package/src/components/Card/Card.vue +2 -2
- package/src/components/Checkbox/Checkbox.vue +4 -1
- package/src/components/Checkbox/checkbox.scss +12 -6
- package/src/components/Divider/Divider.vue +22 -12
- package/src/components/Drawer/Drawer.vue +6 -8
- package/src/components/Drawer/drawer.scss +0 -13
- package/src/components/Dropdown/Dropdown.vue +13 -8
- package/src/components/Input/Input.vue +4 -1
- package/src/components/Input/Textarea.vue +11 -6
- package/src/components/Input/input.scss +13 -4
- package/src/components/Popout/Popout.vue +3 -3
- package/src/components/Progress/Progress.vue +19 -11
- package/src/components/Progress/progress.scss +1 -1
- package/src/components/Radio/Radio.vue +1 -1
- package/src/components/Radio/RadioGroup.vue +10 -5
- package/src/components/Sheet/Sheet.vue +16 -15
- package/src/components/Sheet/sheet.scss +4 -0
- package/src/components/Skeleton/Skeleton.vue +19 -20
- package/src/components/Spinner/Spinner.vue +5 -5
- package/src/components/Table/table.ts +2 -1
- package/src/components/Tooltip/Tooltip.vue +1 -1
- package/src/shared/helpers.ts +15 -0
- package/src/shared/types.ts +6 -0
- package/src/style/core.scss +4 -1
- package/src/style/layout.scss +4 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
<script setup lang='ts'>
|
|
2
|
-
import { onMounted, useTemplateRef, watchEffect } from 'vue'
|
|
3
|
-
import { delay, isNil, randomMinMax } from '../../shared/helpers'
|
|
2
|
+
import { computed, onMounted, useTemplateRef, watchEffect } from 'vue'
|
|
3
|
+
import { delay, formatUnitValue, isNil, randomMinMax } from '../../shared/helpers'
|
|
4
4
|
import './progress.scss'
|
|
5
5
|
|
|
6
6
|
interface Props {
|
|
@@ -42,16 +42,19 @@ const progressRef = useTemplateRef('progress')
|
|
|
42
42
|
|
|
43
43
|
watchEffect(() => {
|
|
44
44
|
if (progressRef.value && !isNil(height)) {
|
|
45
|
-
progressRef.value.style.setProperty(
|
|
45
|
+
progressRef.value.style.setProperty(
|
|
46
|
+
'--vui-progress-height',
|
|
47
|
+
formatUnitValue(height),
|
|
48
|
+
)
|
|
46
49
|
}
|
|
47
50
|
})
|
|
48
51
|
|
|
49
52
|
// Automatically / randomly increment but never reach 100% until
|
|
50
53
|
async function fakeIncrement() {
|
|
51
54
|
if (fake && progressAmount.value < 100) {
|
|
52
|
-
if (progressAmount.value >
|
|
55
|
+
if (progressAmount.value > 90) {
|
|
53
56
|
// Only in crement by the fraction of the remaining amount
|
|
54
|
-
progressAmount.value += (100 - progressAmount.value) * 0.
|
|
57
|
+
progressAmount.value += (100 - progressAmount.value) * 0.05
|
|
55
58
|
await delay(randomMinMax(500, 3000))
|
|
56
59
|
}
|
|
57
60
|
else {
|
|
@@ -63,6 +66,9 @@ async function fakeIncrement() {
|
|
|
63
66
|
}
|
|
64
67
|
|
|
65
68
|
onMounted(fakeIncrement)
|
|
69
|
+
|
|
70
|
+
const w = computed(() => `${progressAmount.value}%`)
|
|
71
|
+
const bC = computed(() => color)
|
|
66
72
|
</script>
|
|
67
73
|
|
|
68
74
|
<template>
|
|
@@ -74,11 +80,13 @@ onMounted(fakeIncrement)
|
|
|
74
80
|
'fixed-active': progressAmount > 0 && progressAmount < 100,
|
|
75
81
|
}"
|
|
76
82
|
>
|
|
77
|
-
<div
|
|
78
|
-
class="vui-progress-indicator" :style="{
|
|
79
|
-
width: `${progressAmount}%`,
|
|
80
|
-
backgroundColor: color,
|
|
81
|
-
}"
|
|
82
|
-
/>
|
|
83
|
+
<div class="vui-progress-indicator" />
|
|
83
84
|
</div>
|
|
84
85
|
</template>
|
|
86
|
+
|
|
87
|
+
<style scoped lang="scss">
|
|
88
|
+
.vui-progress-indicator {
|
|
89
|
+
width: v-bind(w);
|
|
90
|
+
background-color: v-bind(bC);
|
|
91
|
+
}
|
|
92
|
+
</style>
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
.vui-progress {
|
|
2
2
|
--vui-progress-height: 3px;
|
|
3
|
+
|
|
3
4
|
display: block;
|
|
4
5
|
width: 100%;
|
|
5
6
|
position: relative;
|
|
@@ -18,7 +19,6 @@
|
|
|
18
19
|
border-radius: none !important;
|
|
19
20
|
|
|
20
21
|
&.fixed-active {
|
|
21
|
-
// Some arbitrary value which should never happen to people with
|
|
22
22
|
height: var(--vui-progress-height);
|
|
23
23
|
}
|
|
24
24
|
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
<script setup lang='ts'>
|
|
2
|
-
import type { VNode } from 'vue'
|
|
3
2
|
import type { FlexProps } from '../Flex/Flex.vue'
|
|
4
|
-
import type
|
|
3
|
+
import type Radio from './Radio.vue'
|
|
4
|
+
import { watchEffect } from 'vue'
|
|
5
5
|
import Flex from '../Flex/Flex.vue'
|
|
6
6
|
|
|
7
7
|
interface Props extends FlexProps {
|
|
@@ -14,22 +14,27 @@ const {
|
|
|
14
14
|
} = defineProps<Props>()
|
|
15
15
|
|
|
16
16
|
const slots = defineSlots<{
|
|
17
|
-
default: () =>
|
|
17
|
+
default: () => Array<typeof Radio>
|
|
18
18
|
}>()
|
|
19
19
|
|
|
20
20
|
const checked = defineModel()
|
|
21
|
+
|
|
22
|
+
watchEffect(() => {
|
|
23
|
+
if (slots.default().some(s => s.type.__name !== 'Radio')) {
|
|
24
|
+
console.error('You can only pass `<Radio />` components as children.')
|
|
25
|
+
}
|
|
26
|
+
})
|
|
21
27
|
</script>
|
|
22
28
|
|
|
23
29
|
<template>
|
|
24
30
|
<Flex v-bind="flexProps">
|
|
25
31
|
<Component
|
|
26
32
|
:is="vnode"
|
|
27
|
-
v-for="vnode of slots.default()
|
|
33
|
+
v-for="vnode of slots.default()"
|
|
28
34
|
:key="vnode.props.value"
|
|
29
35
|
v-bind="vnode.props"
|
|
30
36
|
v-model="checked"
|
|
31
37
|
:class="{ disabled: disabled || vnode.props.disabled }"
|
|
32
38
|
/>
|
|
33
39
|
</Flex>
|
|
34
|
-
<!-- <div class="vui-radio-group" /> -->
|
|
35
40
|
</template>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
<script setup lang='ts'>
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
import Backdrop from '../../internal/Backdrop/Backdrop.vue'
|
|
4
|
+
import { formatUnitValue } from '../../shared/helpers'
|
|
4
5
|
import Button from '../Button/Button.vue'
|
|
5
6
|
import Divider from '../Divider/Divider.vue'
|
|
6
7
|
import './sheet.scss'
|
|
@@ -17,6 +18,8 @@ const {
|
|
|
17
18
|
separator,
|
|
18
19
|
} = defineProps<Props>()
|
|
19
20
|
|
|
21
|
+
const TRANSITION_OFFSET = 16
|
|
22
|
+
|
|
20
23
|
const open = defineModel<boolean>()
|
|
21
24
|
|
|
22
25
|
function close() {
|
|
@@ -24,27 +27,21 @@ function close() {
|
|
|
24
27
|
}
|
|
25
28
|
|
|
26
29
|
const style = computed(() => {
|
|
27
|
-
const formattedSizeValue = typeof size === 'number' ? `${size}px` : size
|
|
28
|
-
let style
|
|
29
|
-
|
|
30
30
|
if (position === 'left' || position === 'right') {
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
else {
|
|
34
|
-
style = { minHeight: formattedSizeValue }
|
|
31
|
+
return { width: formatUnitValue(size) }
|
|
35
32
|
}
|
|
36
33
|
|
|
37
|
-
return
|
|
34
|
+
return undefined
|
|
38
35
|
})
|
|
39
36
|
|
|
40
37
|
// Used to compute base location so that sheet appears to animate form the edge of the screen
|
|
41
38
|
const baseTransform = computed(() => {
|
|
42
39
|
switch (position) {
|
|
43
|
-
case 'left': return `translate(
|
|
44
|
-
case 'top': return `translate(0,
|
|
45
|
-
case 'bottom': return `translate(0,
|
|
40
|
+
case 'left': return `translate(-${TRANSITION_OFFSET}px, 0)`
|
|
41
|
+
case 'top': return `translate(0, -${TRANSITION_OFFSET}px)`
|
|
42
|
+
case 'bottom': return `translate(0, ${TRANSITION_OFFSET}px)`
|
|
46
43
|
case 'right':
|
|
47
|
-
default: return `translate(
|
|
44
|
+
default: return `translate(${TRANSITION_OFFSET}px, 0)`
|
|
48
45
|
}
|
|
49
46
|
})
|
|
50
47
|
</script>
|
|
@@ -52,16 +49,16 @@ const baseTransform = computed(() => {
|
|
|
52
49
|
<template>
|
|
53
50
|
<Teleport to="body">
|
|
54
51
|
<Transition appear name="sheet">
|
|
55
|
-
<Backdrop v-if="open"
|
|
52
|
+
<Backdrop v-if="open" @close="open = false">
|
|
56
53
|
<div v-if="open" class="vui-sheet" :class="[`vui-sheet-position-${position}`]" :style>
|
|
57
54
|
<div class="vui-sheet-header">
|
|
58
|
-
<div
|
|
55
|
+
<div class="flex-1">
|
|
59
56
|
<slot name="header" :close />
|
|
60
57
|
</div>
|
|
61
58
|
<Button square icon="ph:x" @click="open = false" />
|
|
62
59
|
</div>
|
|
63
60
|
|
|
64
|
-
<Divider v-if="separator && $slots.header" :
|
|
61
|
+
<Divider v-if="separator && $slots.header" :space="1" />
|
|
65
62
|
|
|
66
63
|
<div v-if="$slots.default" class="vui-sheet-content">
|
|
67
64
|
<slot :close />
|
|
@@ -73,6 +70,10 @@ const baseTransform = computed(() => {
|
|
|
73
70
|
</template>
|
|
74
71
|
|
|
75
72
|
<style scoped lang="scss">
|
|
73
|
+
.vui-backdrop {
|
|
74
|
+
padding: 0;
|
|
75
|
+
}
|
|
76
|
+
|
|
76
77
|
.sheet-enter-active,
|
|
77
78
|
.sheet-leave-active {
|
|
78
79
|
transition: var(--transition);
|
|
@@ -9,20 +9,24 @@
|
|
|
9
9
|
&.vui-sheet-position-top {
|
|
10
10
|
top: 0;
|
|
11
11
|
border-bottom: 1px solid var(--color-border);
|
|
12
|
+
height: auto;
|
|
12
13
|
}
|
|
13
14
|
|
|
14
15
|
&.vui-sheet-position-bottom {
|
|
15
16
|
bottom: 0;
|
|
16
17
|
border-top: 1px solid var(--color-border);
|
|
18
|
+
height: auto;
|
|
17
19
|
}
|
|
18
20
|
|
|
19
21
|
&.vui-sheet-position-right {
|
|
20
22
|
right: 0;
|
|
23
|
+
top: 0;
|
|
21
24
|
border-left: 1px solid var(--color-border);
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
&.vui-sheet-position-left {
|
|
25
28
|
left: 0;
|
|
29
|
+
top: 0;
|
|
26
30
|
border-right: 1px solid var(--color-border);
|
|
27
31
|
}
|
|
28
32
|
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
<!-- eslint-disable ts/no-use-before-define -->
|
|
2
2
|
<script setup lang='ts'>
|
|
3
|
+
import { computed } from 'vue'
|
|
4
|
+
import { formatUnitValue } from '../../shared/helpers'
|
|
3
5
|
import './skeleton.scss'
|
|
4
6
|
|
|
5
7
|
interface Props {
|
|
@@ -20,27 +22,24 @@ const {
|
|
|
20
22
|
|
|
21
23
|
const DEFAULT_RADIUS = 'var(--border-radius-s)'
|
|
22
24
|
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
25
|
+
// Give priority to radius, if it is NOT set to default
|
|
26
|
+
const bR = computed(() => formatUnitValue(circle && radius === DEFAULT_RADIUS ? 9999 : radius))
|
|
27
|
+
|
|
28
|
+
// When using `circle` prop, we want to use the same
|
|
29
|
+
// value for both height and width, but we can't
|
|
30
|
+
// know which one will be defined
|
|
31
|
+
const w = computed(() => formatUnitValue(circle ? (width || height) : width))
|
|
32
|
+
const h = computed(() => formatUnitValue(circle ? (width || height) : height))
|
|
32
33
|
</script>
|
|
33
34
|
|
|
34
35
|
<template>
|
|
35
|
-
<div
|
|
36
|
-
class="vui-skeleton" :style="{
|
|
37
|
-
// Give priority to radius, if it is NOT set to default
|
|
38
|
-
borderRadius: valueToPixels(circle && radius === DEFAULT_RADIUS ? 9999 : radius),
|
|
39
|
-
// When using `circle` prop, we want to use the same
|
|
40
|
-
// value for both height and width, but we can't
|
|
41
|
-
// know which one will be defined
|
|
42
|
-
width: valueToPixels(circle ? (width || height) : width),
|
|
43
|
-
height: valueToPixels(circle ? (width || height) : height),
|
|
44
|
-
}"
|
|
45
|
-
/>
|
|
36
|
+
<div class="vui-skeleton" />
|
|
46
37
|
</template>
|
|
38
|
+
|
|
39
|
+
<style lang="scss" scoped>
|
|
40
|
+
.vui-skeleton {
|
|
41
|
+
border-radius: v-bind(bR);
|
|
42
|
+
width: v-bind(w);
|
|
43
|
+
height: v-bind(h);
|
|
44
|
+
}
|
|
45
|
+
</style>
|
|
@@ -12,7 +12,7 @@ const {
|
|
|
12
12
|
size = 's',
|
|
13
13
|
} = defineProps<Props>()
|
|
14
14
|
|
|
15
|
-
const
|
|
15
|
+
const w = computed(() => {
|
|
16
16
|
switch (size) {
|
|
17
17
|
case Size.s: return '16px'
|
|
18
18
|
case Size.l: return '38px'
|
|
@@ -21,7 +21,7 @@ const actualSize = computed(() => {
|
|
|
21
21
|
}
|
|
22
22
|
})
|
|
23
23
|
|
|
24
|
-
const
|
|
24
|
+
const bW = computed(() => {
|
|
25
25
|
switch (size) {
|
|
26
26
|
case Size.s: return '3px'
|
|
27
27
|
case Size.l: return '5px'
|
|
@@ -37,8 +37,8 @@ const actualBorderWidth = computed(() => {
|
|
|
37
37
|
|
|
38
38
|
<style lang="scss">
|
|
39
39
|
.vui-spinner {
|
|
40
|
-
width: v-bind(
|
|
41
|
-
height: v-bind(
|
|
42
|
-
border-width: v-bind(
|
|
40
|
+
width: v-bind(w);
|
|
41
|
+
height: v-bind(w);
|
|
42
|
+
border-width: v-bind(bW);
|
|
43
43
|
}
|
|
44
44
|
</style>
|
|
@@ -125,7 +125,8 @@ export function defineTable<const Dataset extends Array<BaseRow>>(
|
|
|
125
125
|
const key = sorting.value.key
|
|
126
126
|
|
|
127
127
|
if (key) {
|
|
128
|
-
|
|
128
|
+
// FIXME: change to `toSorted` when typescript is ok
|
|
129
|
+
final = [...final].sort((a: Dataset[number], b: Dataset[number]) => {
|
|
129
130
|
const aValue = a[key]
|
|
130
131
|
const bValue = b[key]
|
|
131
132
|
return sorting.value.type === 'asc'
|
package/src/shared/helpers.ts
CHANGED
|
@@ -57,3 +57,18 @@ export function setCharAt(str: string, char: string | number, index: number): st
|
|
|
57
57
|
return char.toString()
|
|
58
58
|
return str.substring(0, index) + char + str.substring(index + 1)
|
|
59
59
|
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Takes in a value and if it is a number, appends "px" to it, otherwise returns
|
|
63
|
+
* the original value.
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
66
|
+
export function formatUnitValue(value: string | number, unit: string = 'px'): string {
|
|
67
|
+
return typeof value === 'number'
|
|
68
|
+
? `${value}${unit}`
|
|
69
|
+
// If last value of string is NOT a number, do not add "px" at the end
|
|
70
|
+
// eslint-disable-next-line unicorn/prefer-number-properties
|
|
71
|
+
: isNaN(Number(value[value.length - 1]))
|
|
72
|
+
? value
|
|
73
|
+
: `${value}${unit}`
|
|
74
|
+
}
|
package/src/shared/types.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { ComponentPublicInstance } from 'vue'
|
|
2
|
+
|
|
1
3
|
export enum Size {
|
|
2
4
|
s = 's',
|
|
3
5
|
m = 'm',
|
|
@@ -9,3 +11,7 @@ export type Sizes = 's' | 'm' | 'l'
|
|
|
9
11
|
export type DeepRequired<T> = { [K in keyof T]: DeepRequired<T[K]> } & Required<T>
|
|
10
12
|
|
|
11
13
|
export type VueClass = string | Record<string, | boolean> | Array<string | Record<string, string | boolean>>
|
|
14
|
+
|
|
15
|
+
// FLoating UI imported types were ruining the build so here we go
|
|
16
|
+
export type PopoutMaybeElement<T> = T | ComponentPublicInstance | null | undefined
|
|
17
|
+
export type Placement = 'top' | 'right' | 'bottom' | 'left' | 'top-start' | 'top-end' | 'right-start' | 'right-end' | 'bottom-start' | 'bottom-end' | 'left-start' | 'left-end'
|
package/src/style/core.scss
CHANGED
|
@@ -23,15 +23,17 @@
|
|
|
23
23
|
--font-size-m: 1.6rem;
|
|
24
24
|
--font-size-l: 1.65rem;
|
|
25
25
|
|
|
26
|
+
--space-xxs: 4px;
|
|
26
27
|
--space-xs: 8px;
|
|
27
28
|
--space-s: 12px;
|
|
28
29
|
--space-m: 18px;
|
|
29
30
|
--space-l: 26px;
|
|
30
31
|
--space-xl: 40px;
|
|
31
32
|
--space-xxl: 52px;
|
|
33
|
+
--space-xxxl: 64px;
|
|
32
34
|
|
|
33
35
|
--transition-quick: 0.08s all ease-in-out;
|
|
34
|
-
--transition: 0.
|
|
36
|
+
--transition: 0.14s all ease-in-out;
|
|
35
37
|
--transition-slow: 0.3s all ease-in-out;
|
|
36
38
|
|
|
37
39
|
--color-bg: rgb(18, 18, 18);
|
|
@@ -117,6 +119,7 @@
|
|
|
117
119
|
|
|
118
120
|
body {
|
|
119
121
|
color: var(--color-text);
|
|
122
|
+
min-height: 100dvh;
|
|
120
123
|
}
|
|
121
124
|
|
|
122
125
|
@import './typography.scss';
|