@dolanske/vui 0.3.4 → 0.5.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.
Files changed (114) hide show
  1. package/LICENSE +673 -673
  2. package/README.md +41 -40
  3. package/dist/components/Dropdown/DropdownItem.vue.d.ts +1 -0
  4. package/dist/components/Flex/Flex.vue.d.ts +3 -1
  5. package/dist/components/Grid/Grid.vue.d.ts +3 -1
  6. package/dist/components/Tabs/Tabs.vue.d.ts +4 -0
  7. package/dist/style.css +1 -1
  8. package/dist/vui.js +1547 -1534
  9. package/package.json +68 -68
  10. package/src/App.vue +176 -175
  11. package/src/components/Accordion/Accordion.vue +91 -91
  12. package/src/components/Accordion/AccordionGroup.vue +43 -43
  13. package/src/components/Accordion/accordion.scss +81 -80
  14. package/src/components/Alert/Alert.vue +53 -53
  15. package/src/components/Alert/alert.scss +80 -80
  16. package/src/components/Avatar/Avatar.vue +50 -50
  17. package/src/components/Avatar/avatar.scss +52 -52
  18. package/src/components/Badge/Badge.vue +21 -21
  19. package/src/components/Badge/badge.scss +89 -89
  20. package/src/components/Breadcrumbs/BreadcrumbItem.vue +26 -26
  21. package/src/components/Breadcrumbs/Breadcrumbs.vue +33 -33
  22. package/src/components/Breadcrumbs/breadcrumbs.scss +30 -30
  23. package/src/components/Button/Button.vue +90 -90
  24. package/src/components/Button/button.scss +178 -176
  25. package/src/components/ButtonGroup/ButtonGroup.vue +25 -25
  26. package/src/components/ButtonGroup/button-group.scss +51 -51
  27. package/src/components/Calendar/Calendar.vue +63 -60
  28. package/src/components/Calendar/calendar.scss +60 -56
  29. package/src/components/Card/Card.vue +48 -48
  30. package/src/components/Card/card.scss +53 -53
  31. package/src/components/Checkbox/Checkbox.vue +51 -52
  32. package/src/components/Checkbox/checkbox.scss +75 -66
  33. package/src/components/CopyClipboard/CopyClipboard.vue +82 -82
  34. package/src/components/CopyClipboard/copy-clipboard.scss +17 -17
  35. package/src/components/Divider/Divider.vue +44 -44
  36. package/src/components/Divider/divider.scss +35 -35
  37. package/src/components/Drawer/Drawer.vue +97 -97
  38. package/src/components/Drawer/drawer.scss +36 -36
  39. package/src/components/Dropdown/Dropdown.vue +111 -111
  40. package/src/components/Dropdown/DropdownItem.vue +33 -29
  41. package/src/components/Dropdown/DropdownTitle.vue +8 -8
  42. package/src/components/Dropdown/dropdown-item.scss +77 -0
  43. package/src/components/Dropdown/dropdown.scss +39 -117
  44. package/src/components/Flex/Flex.vue +113 -106
  45. package/src/components/Grid/Grid.vue +60 -54
  46. package/src/components/Input/Counter.vue +70 -70
  47. package/src/components/Input/Dropzone.vue +65 -65
  48. package/src/components/Input/File.vue +15 -15
  49. package/src/components/Input/Input.vue +121 -121
  50. package/src/components/Input/Password.vue +47 -47
  51. package/src/components/Input/Textarea.vue +76 -76
  52. package/src/components/Input/input.scss +208 -208
  53. package/src/components/Kbd/Kbd.vue +48 -48
  54. package/src/components/Kbd/KbdGroup.vue +31 -31
  55. package/src/components/Kbd/kbd.scss +18 -18
  56. package/src/components/Modal/Confirm.vue +56 -56
  57. package/src/components/Modal/Modal.vue +91 -91
  58. package/src/components/Modal/modal.scss +49 -49
  59. package/src/components/OTP/OTP.vue +133 -133
  60. package/src/components/OTP/OTPItem.vue +37 -37
  61. package/src/components/OTP/otp.scss +83 -83
  62. package/src/components/Pagination/Pagination.vue +74 -74
  63. package/src/components/Pagination/pagination.ts +78 -78
  64. package/src/components/Popout/Popout.vue +42 -42
  65. package/src/components/Popout/popout.scss +8 -8
  66. package/src/components/Progress/Progress.vue +90 -90
  67. package/src/components/Progress/progress.scss +41 -41
  68. package/src/components/Radio/Radio.vue +36 -36
  69. package/src/components/Radio/RadioGroup.vue +40 -40
  70. package/src/components/Radio/radio.scss +68 -59
  71. package/src/components/Select/Select.vue +180 -180
  72. package/src/components/Select/select.scss +44 -44
  73. package/src/components/Sheet/Sheet.vue +92 -92
  74. package/src/components/Sheet/sheet.scss +60 -60
  75. package/src/components/Sidebar/Sidebar.vue +102 -0
  76. package/src/components/Sidebar/sidebar.scss +123 -0
  77. package/src/components/Skeleton/Skeleton.vue +43 -43
  78. package/src/components/Skeleton/skeleton.scss +14 -14
  79. package/src/components/Spinner/Spinner.vue +42 -42
  80. package/src/components/Spinner/spinner.scss +46 -46
  81. package/src/components/Switch/Switch.vue +30 -30
  82. package/src/components/Switch/switch.scss +60 -52
  83. package/src/components/Table/Cell.vue +23 -23
  84. package/src/components/Table/Header.vue +59 -59
  85. package/src/components/Table/Row.vue +9 -9
  86. package/src/components/Table/SelectAll.vue +23 -23
  87. package/src/components/Table/SelectRow.vue +29 -29
  88. package/src/components/Table/Table.vue +66 -66
  89. package/src/components/Table/table.scss +134 -134
  90. package/src/components/Table/table.ts +244 -244
  91. package/src/components/Tabs/Tab.vue +27 -27
  92. package/src/components/Tabs/Tabs.vue +89 -82
  93. package/src/components/Tabs/tabs.scss +80 -79
  94. package/src/components/Toast/Toasts.vue +47 -47
  95. package/src/components/Toast/toast.scss +41 -41
  96. package/src/components/Toast/toast.ts +68 -68
  97. package/src/components/Tooltip/Tooltip.vue +86 -86
  98. package/src/components/Tooltip/tooltip.scss +4 -4
  99. package/src/index.scss +1 -1
  100. package/src/index.ts +119 -119
  101. package/src/internal/Backdrop/Backdrop.vue +22 -22
  102. package/src/internal/Backdrop/backdrop.scss +28 -28
  103. package/src/main.ts +5 -5
  104. package/src/shared/helpers.ts +74 -74
  105. package/src/shared/types.ts +29 -29
  106. package/src/style/animation.scss +21 -21
  107. package/src/style/core.scss +150 -148
  108. package/src/style/layout.scss +168 -136
  109. package/src/style/media-query.scss +29 -29
  110. package/src/style/reset.scss +135 -135
  111. package/src/style/{fonts.scss → text.scss} +74 -53
  112. package/src/style/tooltip.scss +128 -128
  113. package/src/style/typography.scss +338 -338
  114. package/src/style/utils.scss +36 -36
@@ -1,91 +1,91 @@
1
- <script setup lang="ts">
2
- import { Icon } from '@iconify/vue'
3
- import { useResizeObserver } from '@vueuse/core'
4
- import { onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue'
5
- import './accordion.scss'
6
-
7
- export interface AccordionProps {
8
- open?: boolean
9
- label?: string
10
- card?: boolean
11
- }
12
-
13
- const props = defineProps<AccordionProps>()
14
- const emits = defineEmits<{
15
- open: []
16
- close: []
17
- }>()
18
-
19
- const isOpen = ref(false)
20
- const contentRef = useTemplateRef('content')
21
- const contentMaxHeight = ref(0)
22
-
23
- watchEffect(() => {
24
- isOpen.value = props.open
25
- }, {
26
- flush: 'post',
27
- })
28
-
29
- watch(isOpen, (value) => {
30
- if (value) {
31
- emits('open')
32
- contentMaxHeight.value = contentRef.value?.scrollHeight || 0
33
- }
34
- else {
35
- emits('close')
36
- }
37
- }, {
38
- flush: 'post',
39
- immediate: true,
40
- })
41
-
42
- function open() {
43
- isOpen.value = true
44
- }
45
-
46
- function close() {
47
- isOpen.value = false
48
- }
49
-
50
- function toggle() {
51
- isOpen.value = !isOpen.value
52
- }
53
-
54
- defineExpose({
55
- open,
56
- close,
57
- toggle,
58
- isOpen,
59
- })
60
-
61
- onMounted(() => {
62
- useResizeObserver(contentRef, ([entry]) => {
63
- if (isOpen.value && contentMaxHeight.value !== entry.contentRect.height) {
64
- contentMaxHeight.value = entry.contentRect.height || 0
65
- }
66
- })
67
- })
68
- </script>
69
-
70
- <template>
71
- <div class="vui-accordion" :class="{ 'open': isOpen, 'is-card': !!props.card }">
72
- <!-- Completely custom header which needs to be styled and implemented by the developer -->
73
- <slot v-if="$slots.trigger" name="trigger" :open :close :toggle :is-open />
74
- <button v-else class="vui-accordion-header" @click="isOpen = !isOpen">
75
- <slot name="header">
76
- {{ props.label }}
77
- </slot>
78
- <Icon icon="ph:caret-down" />
79
- </button>
80
-
81
- <div
82
- class="vui-accordion-content"
83
- :aria-hidden="!isOpen"
84
- :style="{ 'max-height': isOpen ? `${contentMaxHeight}px` : '0px' }"
85
- >
86
- <div ref="content" class="vui-accordtion-content-inner">
87
- <slot />
88
- </div>
89
- </div>
90
- </div>
91
- </template>
1
+ <script setup lang="ts">
2
+ import { Icon } from '@iconify/vue'
3
+ import { useResizeObserver } from '@vueuse/core'
4
+ import { onMounted, ref, useTemplateRef, watch, watchEffect } from 'vue'
5
+ import './accordion.scss'
6
+
7
+ export interface AccordionProps {
8
+ open?: boolean
9
+ label?: string
10
+ card?: boolean
11
+ }
12
+
13
+ const props = defineProps<AccordionProps>()
14
+ const emits = defineEmits<{
15
+ open: []
16
+ close: []
17
+ }>()
18
+
19
+ const isOpen = ref(false)
20
+ const contentRef = useTemplateRef('content')
21
+ const contentMaxHeight = ref(0)
22
+
23
+ watchEffect(() => {
24
+ isOpen.value = props.open
25
+ }, {
26
+ flush: 'post',
27
+ })
28
+
29
+ watch(isOpen, (value) => {
30
+ if (value) {
31
+ emits('open')
32
+ contentMaxHeight.value = contentRef.value?.scrollHeight || 0
33
+ }
34
+ else {
35
+ emits('close')
36
+ }
37
+ }, {
38
+ flush: 'post',
39
+ immediate: true,
40
+ })
41
+
42
+ function open() {
43
+ isOpen.value = true
44
+ }
45
+
46
+ function close() {
47
+ isOpen.value = false
48
+ }
49
+
50
+ function toggle() {
51
+ isOpen.value = !isOpen.value
52
+ }
53
+
54
+ defineExpose({
55
+ open,
56
+ close,
57
+ toggle,
58
+ isOpen,
59
+ })
60
+
61
+ onMounted(() => {
62
+ useResizeObserver(contentRef, ([entry]) => {
63
+ if (isOpen.value && contentMaxHeight.value !== entry.contentRect.height) {
64
+ contentMaxHeight.value = entry.contentRect.height || 0
65
+ }
66
+ })
67
+ })
68
+ </script>
69
+
70
+ <template>
71
+ <div class="vui-accordion" :class="{ 'open': isOpen, 'is-card': !!props.card }">
72
+ <!-- Completely custom header which needs to be styled and implemented by the developer -->
73
+ <slot v-if="$slots.trigger" name="trigger" :open :close :toggle :is-open />
74
+ <button v-else class="vui-accordion-header" @click="isOpen = !isOpen">
75
+ <slot name="header">
76
+ {{ props.label }}
77
+ </slot>
78
+ <Icon icon="ph:caret-down" />
79
+ </button>
80
+
81
+ <div
82
+ class="vui-accordion-content"
83
+ :aria-hidden="!isOpen"
84
+ :style="{ 'max-height': isOpen ? `${contentMaxHeight}px` : '0px' }"
85
+ >
86
+ <div ref="content" class="vui-accordtion-content-inner">
87
+ <slot />
88
+ </div>
89
+ </div>
90
+ </div>
91
+ </template>
@@ -1,43 +1,43 @@
1
- <script setup lang="ts">
2
- import type { VNode } from 'vue'
3
- import type { AccordionProps } from './Accordion.vue'
4
- import type Accordion from './Accordion.vue'
5
- import { useTemplateRef } from 'vue'
6
- // Renderless component which is used to house multiple accordions which can be triggered together in some way
7
-
8
- interface Props {
9
- /**
10
- * If set to true, if an accordion opens, all other close
11
- */
12
- single?: boolean
13
- }
14
-
15
- const props = defineProps<Props>()
16
-
17
- const slots = defineSlots<{
18
- default: () => Array<VNode & { props: AccordionProps }>
19
- }>()
20
-
21
- const accordionRefs = useTemplateRef<InstanceType<typeof Accordion>[]>('accordion')
22
-
23
- function handleAccordionOpen(newIndex: number) {
24
- if (!accordionRefs.value || !props.single)
25
- return
26
-
27
- accordionRefs.value.forEach((item, index) => {
28
- if (index !== newIndex) {
29
- item.close()
30
- }
31
- })
32
- }
33
- </script>
34
-
35
- <template>
36
- <component
37
- :is="item"
38
- v-for="(item, index) of slots.default()"
39
- ref="accordion"
40
- :key="item"
41
- @open="handleAccordionOpen(index)"
42
- />
43
- </template>
1
+ <script setup lang="ts">
2
+ import type { VNode } from 'vue'
3
+ import type { AccordionProps } from './Accordion.vue'
4
+ import type Accordion from './Accordion.vue'
5
+ import { useTemplateRef } from 'vue'
6
+ // Renderless component which is used to house multiple accordions which can be triggered together in some way
7
+
8
+ interface Props {
9
+ /**
10
+ * If set to true, if an accordion opens, all other close
11
+ */
12
+ single?: boolean
13
+ }
14
+
15
+ const props = defineProps<Props>()
16
+
17
+ const slots = defineSlots<{
18
+ default: () => Array<VNode & { props: AccordionProps }>
19
+ }>()
20
+
21
+ const accordionRefs = useTemplateRef<InstanceType<typeof Accordion>[]>('accordion')
22
+
23
+ function handleAccordionOpen(newIndex: number) {
24
+ if (!accordionRefs.value || !props.single)
25
+ return
26
+
27
+ accordionRefs.value.forEach((item, index) => {
28
+ if (index !== newIndex) {
29
+ item.close()
30
+ }
31
+ })
32
+ }
33
+ </script>
34
+
35
+ <template>
36
+ <component
37
+ :is="item"
38
+ v-for="(item, index) of slots.default()"
39
+ ref="accordion"
40
+ :key="item"
41
+ @open="handleAccordionOpen(index)"
42
+ />
43
+ </template>
@@ -1,80 +1,81 @@
1
- .vui-accordion {
2
- width: 100%;
3
- transition: var(--transition);
4
- border-bottom: 1px solid var(--color-border);
5
- padding-bottom: 0;
6
-
7
- &.is-card {
8
- border: 1px solid var(--color-border);
9
- border-radius: var(--border-radius-m);
10
-
11
- &.open {
12
- padding-bottom: 0;
13
-
14
- .vui-accordion-header {
15
- border-block-width: 1px;
16
- border-bottom-left-radius: 0;
17
- border-bottom-right-radius: 0;
18
- }
19
- }
20
-
21
- .vui-accordion-header {
22
- padding-inline: var(--space-m);
23
- border-bottom: 0px solid var(--color-border);
24
- text-decoration: inherit;
25
- border-radius: var(--border-radius-m);
26
-
27
- &:hover {
28
- text-decoration: inherit;
29
- text-underline-offset: inherit;
30
- background-color: var(--color-button-gray);
31
- }
32
- }
33
-
34
- .vui-accordtion-content-inner {
35
- padding: var(--space-m);
36
- }
37
- }
38
-
39
- &.open {
40
- padding-bottom: var(--space-m);
41
-
42
- .vui-accordion-header svg {
43
- transform: rotate(180deg);
44
- }
45
-
46
- .vui-accordion-content {
47
- visibility: visible;
48
- }
49
- }
50
-
51
- .vui-accordion-header {
52
- display: flex;
53
- width: 100%;
54
- justify-content: space-between;
55
- align-items: center;
56
- padding: var(--space-m) 0;
57
- color: pointer;
58
- font-size: var(--font-size-m);
59
- font-weight: 500;
60
- color: var(--color-text);
61
-
62
- &:hover {
63
- text-decoration: underline;
64
- text-underline-offset: 4px;
65
- }
66
-
67
- svg {
68
- transition: var(--transition);
69
- color: var(--color-text-light);
70
- }
71
- }
72
-
73
- .vui-accordion-content {
74
- transition: var(--transition-slow);
75
- width: 100%;
76
- max-height: 0;
77
- overflow: hidden;
78
- visibility: hidden;
79
- }
80
- }
1
+ .vui-accordion {
2
+ width: 100%;
3
+ transition: var(--transition);
4
+ border-bottom: 1px solid var(--color-border);
5
+ padding-bottom: 0;
6
+
7
+ &.is-card {
8
+ border: 1px solid var(--color-border);
9
+ border-radius: var(--border-radius-m);
10
+
11
+ &.open {
12
+ padding-bottom: 0;
13
+
14
+ .vui-accordion-header {
15
+ border-block-width: 1px;
16
+ border-bottom-left-radius: 0;
17
+ border-bottom-right-radius: 0;
18
+ }
19
+ }
20
+
21
+ .vui-accordion-header {
22
+ padding-inline: var(--space-m);
23
+ border-bottom: 0px solid var(--color-border);
24
+ text-decoration: inherit;
25
+ border-radius: var(--border-radius-m);
26
+
27
+ &:hover {
28
+ text-decoration: inherit;
29
+ text-underline-offset: inherit;
30
+ background-color: var(--color-button-gray);
31
+ }
32
+ }
33
+
34
+ .vui-accordtion-content-inner {
35
+ padding: var(--space-m);
36
+ }
37
+ }
38
+
39
+ &.open {
40
+ padding-bottom: var(--space-m);
41
+
42
+ .vui-accordion-header svg {
43
+ transform: rotate(180deg);
44
+ }
45
+
46
+ .vui-accordion-content {
47
+ visibility: visible;
48
+ }
49
+ }
50
+
51
+ .vui-accordion-header {
52
+ display: flex;
53
+ width: 100%;
54
+ justify-content: space-between;
55
+ align-items: center;
56
+ padding: var(--space-m) 0;
57
+ color: pointer;
58
+ font-size: var(--font-size-m);
59
+ font-weight: 500;
60
+ color: var(--color-text);
61
+ border-radius: var(--border-radius-m);
62
+
63
+ &:hover {
64
+ text-decoration: underline;
65
+ text-underline-offset: 4px;
66
+ }
67
+
68
+ svg {
69
+ transition: var(--transition);
70
+ color: var(--color-text-light);
71
+ }
72
+ }
73
+
74
+ .vui-accordion-content {
75
+ transition: var(--transition-slow);
76
+ width: 100%;
77
+ max-height: 0;
78
+ overflow: hidden;
79
+ visibility: hidden;
80
+ }
81
+ }
@@ -1,53 +1,53 @@
1
- <script setup lang="ts">
2
- import { Icon } from '@iconify/vue'
3
- import { computed } from 'vue'
4
- import './alert.scss'
5
-
6
- interface Props {
7
- variant?: 'neutral' | 'info' | 'success' | 'warning' | 'danger'
8
- /**
9
- * Override the variant's default icon
10
- */
11
- icon?: string
12
-
13
- /**
14
- * Setting a title and description will use slightly different styling other than slots.
15
- */
16
- title?: string
17
- description?: string
18
- }
19
-
20
- const {
21
- icon = 'ph:circle-light',
22
- variant = 'neutral',
23
- title,
24
- description,
25
- } = defineProps<Props>()
26
-
27
- const actualIcon = computed(() => {
28
- switch (variant) {
29
- case 'info': return 'ph:info'
30
- case 'success': return 'ph:check-circle'
31
- case 'warning': return 'ph:warning'
32
- case 'danger': return 'ph:warning-diamond'
33
- default: return icon
34
- }
35
- })
36
- </script>
37
-
38
- <template>
39
- <div class="vui-alert" :class="[`vui-alert-variant-${variant}`]">
40
- <Icon v-if="actualIcon" class="vui-alert-icon" :icon="actualIcon" />
41
- <div v-if="$slots.default" class="vui-alert-content">
42
- <slot />
43
- </div>
44
- <div v-else class="vui-alert-default-content">
45
- <strong v-if="title">{{ title }}</strong>
46
- <p v-if="description">
47
- {{ description }}
48
- </p>
49
- </div>
50
-
51
- <slot name="end" />
52
- </div>
53
- </template>
1
+ <script setup lang="ts">
2
+ import { Icon } from '@iconify/vue'
3
+ import { computed } from 'vue'
4
+ import './alert.scss'
5
+
6
+ interface Props {
7
+ variant?: 'neutral' | 'info' | 'success' | 'warning' | 'danger'
8
+ /**
9
+ * Override the variant's default icon
10
+ */
11
+ icon?: string
12
+
13
+ /**
14
+ * Setting a title and description will use slightly different styling other than slots.
15
+ */
16
+ title?: string
17
+ description?: string
18
+ }
19
+
20
+ const {
21
+ icon = 'ph:circle-light',
22
+ variant = 'neutral',
23
+ title,
24
+ description,
25
+ } = defineProps<Props>()
26
+
27
+ const actualIcon = computed(() => {
28
+ switch (variant) {
29
+ case 'info': return 'ph:info'
30
+ case 'success': return 'ph:check-circle'
31
+ case 'warning': return 'ph:warning'
32
+ case 'danger': return 'ph:warning-diamond'
33
+ default: return icon
34
+ }
35
+ })
36
+ </script>
37
+
38
+ <template>
39
+ <div class="vui-alert" :class="[`vui-alert-variant-${variant}`]">
40
+ <Icon v-if="actualIcon" class="vui-alert-icon" :icon="actualIcon" />
41
+ <div v-if="$slots.default" class="vui-alert-content">
42
+ <slot />
43
+ </div>
44
+ <div v-else class="vui-alert-default-content">
45
+ <strong v-if="title">{{ title }}</strong>
46
+ <p v-if="description">
47
+ {{ description }}
48
+ </p>
49
+ </div>
50
+
51
+ <slot name="end" />
52
+ </div>
53
+ </template>