@returnless/focus-ui 0.0.2 → 0.0.3
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/dist/focus-ui.js +10851 -0
- package/dist/focus-ui.umd.cjs +26 -0
- package/dist/style.css +1 -0
- package/package.json +11 -7
- package/src/build-utils/generate-component-meta.ts +5 -1
- package/src/build-utils/update-component-list.ts +1 -1
- package/src/components/Accordion/AccordionContent.vue +34 -5
- package/src/components/Accordion/AccordionItem.vue +5 -2
- package/src/components/Accordion/AccordionTrigger.vue +5 -2
- package/src/components/Accordion/README.md +1 -1
- package/src/components/ActionList/ActionList.vue +9 -0
- package/src/components/ActionList/ActionListBody.vue +11 -0
- package/src/components/ActionList/ActionListItem.vue +37 -0
- package/src/components/ActionList/ActionListSection.vue +7 -0
- package/src/components/ActionList/ActionListTrigger.vue +9 -0
- package/src/components/ActionList/README.md +113 -0
- package/src/components/ActionList/index.ts +5 -0
- package/src/components/Alert/Alert.vue +23 -10
- package/src/components/Alert/AlertDescription.vue +13 -1
- package/src/components/Alert/AlertTitle.vue +1 -1
- package/src/components/Alert/DismissableAlertButton.vue +6 -4
- package/src/components/Alert/README.md +31 -2
- package/src/components/Alert/index.ts +2 -0
- package/src/components/Alert/types.ts +1 -0
- package/src/components/AlertDialog/AlertDialog.vue +10 -1
- package/src/components/AlertDialog/AlertDialogActionButton.vue +9 -2
- package/src/components/AlertDialog/AlertDialogCancelButton.vue +1 -1
- package/src/components/AlertDialog/AlertDialogDescription.vue +7 -1
- package/src/components/AlertDialog/AlertDialogTitle.vue +11 -3
- package/src/components/AlertDialog/README.md +15 -16
- package/src/components/AspectRatio/AspectRatio.vue +19 -0
- package/src/components/AspectRatio/README.md +36 -0
- package/src/components/AspectRatio/index.ts +1 -0
- package/src/components/Avatar/Avatar.vue +57 -13
- package/src/components/Avatar/README.md +3 -9
- package/src/components/Badge/Badge.vue +1 -1
- package/src/components/Badge/README.md +9 -9
- package/src/components/BarChart/BarChart.vue +80 -0
- package/src/components/{MetricCard/MetricCardHeader.vue → BarChart/BarChartContainer.vue} +1 -1
- package/src/components/BarChart/BarChartStacked.vue +93 -0
- package/src/components/BarChart/README.md +83 -0
- package/src/components/BarChart/index.ts +3 -0
- package/src/components/Breadcrumbs/Breadcrumb.vue +7 -0
- package/src/components/Breadcrumbs/BreadcrumbEllipsis.vue +12 -0
- package/src/components/{MetricCard/MetricCardValue.vue → Breadcrumbs/BreadcrumbItem.vue} +2 -2
- package/src/components/Breadcrumbs/BreadcrumbLink.vue +13 -0
- package/src/components/Breadcrumbs/BreadcrumbList.vue +8 -0
- package/src/components/Breadcrumbs/BreadcrumbPage.vue +13 -0
- package/src/components/Breadcrumbs/BreadcrumbSeparator.vue +12 -0
- package/src/components/Breadcrumbs/README.md +91 -0
- package/src/components/Breadcrumbs/index.ts +7 -0
- package/src/components/Button/Button.vue +53 -41
- package/src/components/Button/ButtonContent.vue +1 -1
- package/src/components/Button/ButtonIcon.vue +28 -3
- package/src/components/Button/README.md +32 -29
- package/src/components/Button/index.ts +2 -0
- package/src/components/Button/types.ts +30 -0
- package/src/components/ButtonGroup/README.md +1 -1
- package/src/components/Card/CardHelp.vue +23 -0
- package/src/components/Card/CardSection.vue +17 -2
- package/src/components/Card/CardTitle.vue +6 -3
- package/src/components/Card/README.md +97 -10
- package/src/components/Card/index.ts +2 -1
- package/src/components/Checkbox/Checkbox.vue +29 -5
- package/src/components/Checkbox/README.md +34 -5
- package/src/components/DatePicker/DatePicker.vue +7 -27
- package/src/components/DatePicker/README.md +1 -1
- package/src/components/DescriptionList/DescriptionList.vue +1 -1
- package/src/components/DescriptionList/DescriptionListItem.vue +1 -1
- package/src/components/DescriptionList/README.md +2 -2
- package/src/components/Dialog/README.md +2 -0
- package/src/components/Dialog/index.ts +0 -0
- package/src/components/DropZone/DropZone.vue +105 -0
- package/src/components/DropZone/README.md +48 -0
- package/src/components/DropZone/index.ts +1 -0
- package/src/components/EmptyState/README.md +1 -1
- package/src/components/Feed/FeedItem.vue +4 -1
- package/src/components/Feed/FeedItemBlock.vue +4 -1
- package/src/components/Feed/README.md +1 -1
- package/src/components/FileUploadButton/FileUploadButton.vue +62 -0
- package/src/components/FileUploadButton/index.ts +1 -0
- package/src/components/Form/Form.vue +7 -2
- package/src/components/Form/README.md +1 -1
- package/src/components/FormLayout/FormLayout.vue +20 -2
- package/src/components/FormLayout/README.md +39 -1
- package/src/components/Heading/Heading.vue +32 -0
- package/src/components/Heading/index.ts +3 -0
- package/src/components/Heading/types.ts +3 -0
- package/src/components/Image/Image.vue +30 -0
- package/src/components/Image/index.ts +1 -0
- package/src/components/InertiaLink/InertiaLink.vue +11 -0
- package/src/components/InertiaLink/index.ts +1 -0
- package/src/components/InlineError/InlineError.vue +21 -0
- package/src/components/InlineError/README.md +63 -0
- package/src/components/InlineError/index.ts +1 -0
- package/src/components/KPICard/KPICard.vue +28 -0
- package/src/components/KPICard/KPICardSection.vue +30 -0
- package/src/components/KPICard/README.md +124 -0
- package/src/components/KPICard/index.ts +2 -0
- package/src/components/Legend/Legend.vue +7 -0
- package/src/components/Legend/LegendItem.vue +34 -0
- package/src/components/Legend/README.md +32 -0
- package/src/components/Legend/index.ts +2 -0
- package/src/components/Link/Link.vue +4 -4
- package/src/components/Link/README.md +1 -1
- package/src/components/Navigation/Navigation.vue +2 -2
- package/src/components/Navigation/NavigationItem.vue +14 -10
- package/src/components/Navigation/NavigationSecondarySection.vue +12 -0
- package/src/components/Navigation/NavigationSection.vue +1 -1
- package/src/components/Navigation/README.md +10 -15
- package/src/components/Navigation/index.ts +1 -0
- package/src/components/Page/Page.vue +2 -33
- package/src/components/Page/PageBody.vue +36 -0
- package/src/components/Page/PageTitle.vue +6 -3
- package/src/components/Page/README.md +45 -39
- package/src/components/Page/index.ts +1 -0
- package/src/components/Pagination/README.md +1 -1
- package/src/components/PinInput/README.md +1 -1
- package/src/components/Popover/Popover.vue +18 -0
- package/src/components/Popover/PopoverBody.vue +11 -0
- package/src/components/Popover/PopoverTrigger.vue +9 -0
- package/src/components/Popover/README.md +34 -6
- package/src/components/Popover/index.ts +3 -0
- package/src/components/Popper/Popper.vue +91 -0
- package/src/components/Popper/PopperBody.vue +19 -0
- package/src/components/Popper/PopperTrigger.vue +14 -0
- package/src/components/Popper/README.md +42 -0
- package/src/components/Popper/index.ts +3 -0
- package/src/components/ProgressBar/ProgressBar.vue +24 -6
- package/src/components/RadioButton/README.md +1 -1
- package/src/components/RadioButton/RadioButton.vue +3 -2
- package/src/components/ResourceList/README.md +160 -0
- package/src/components/ResourceList/ResourceList.vue +7 -0
- package/src/components/ResourceList/ResourceListItem.vue +7 -0
- package/src/components/ResourceList/ResourceListItemContent.vue +7 -0
- package/src/components/ResourceList/index.ts +3 -0
- package/src/components/Select/README.md +1 -1
- package/src/components/Select/Select.vue +1 -1
- package/src/components/Separator/README.md +5 -1
- package/src/components/Separator/Separator.vue +20 -3
- package/src/components/Spinner/README.md +1 -1
- package/src/components/Spinner/Spinner.vue +10 -4
- package/src/components/StatusIndicator/README.md +2 -2
- package/src/components/StatusIndicator/StatusIndicator.vue +11 -5
- package/src/components/Stepper/README.md +38 -0
- package/src/components/Stepper/Stepper.vue +104 -0
- package/src/components/Stepper/index.ts +1 -0
- package/src/components/Tabs/README.md +1 -1
- package/src/components/Tabs/TabTrigger.vue +5 -4
- package/src/components/Tabs/Tabs.vue +4 -1
- package/src/components/Tag/Tag.vue +45 -0
- package/src/components/Tag/index.ts +1 -0
- package/src/components/TextField/README.md +24 -6
- package/src/components/TextField/TextField.vue +25 -5
- package/src/components/TextField/TextFieldIcon.vue +19 -0
- package/src/components/TextStyle/README.md +1 -1
- package/src/components/TextStyle/TextStyle.vue +1 -1
- package/src/components/Toast/DismissToastAction.vue +1 -1
- package/src/components/Toast/README.md +1 -1
- package/src/components/Toggle/README.md +1 -1
- package/src/components/Toggle/Toggle.vue +8 -5
- package/src/components/Tooltip/README.md +1 -1
- package/src/components/Tooltip/Tooltip.vue +15 -41
- package/src/components/TopBar/TopBarSearch.vue +2 -2
- package/src/components/index.ts +68 -12
- package/src/components/types.ts +5 -0
- package/src/composables/useTheme.ts +13 -1
- package/src/composables/useToastNotifications.ts +1 -1
- package/src/composables/useUniqueId.ts +4 -3
- package/src/index.css +17 -13
- package/src/index.ts +0 -11
- package/dist/focus-ui.es.js +0 -33
- package/dist/types/components/Accordion/Accordion.vue.d.ts +0 -32
- package/dist/types/components/Accordion/AccordionItem.vue.d.ts +0 -2
- package/dist/types/components/Accordion/index.d.ts +0 -2
- package/dist/types/components/index.d.ts +0 -1
- package/dist/types/index.d.ts +0 -7
- package/src/components/CategoryBar/CategoryBar.vue +0 -25
- package/src/components/CategoryBar/CategoryBarItem.vue +0 -34
- package/src/components/CategoryBar/README.md +0 -17
- package/src/components/CategoryBar/index.ts +0 -2
- package/src/components/MetricCard/MetricCard.vue +0 -11
- package/src/components/MetricCard/MetricCardLabel.vue +0 -9
- package/src/components/MetricCard/MetricCardSection.vue +0 -11
- package/src/components/MetricCard/README.md +0 -53
- package/src/components/MetricCard/index.ts +0 -5
|
@@ -1,7 +1,15 @@
|
|
|
1
|
-
<script lang="ts" setup
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { Heading } from '../Heading';
|
|
3
|
+
import { inject } from 'vue';
|
|
4
|
+
|
|
5
|
+
const alertDialogLabelledBy = inject<string>('alertDialogLabelledBy')!;
|
|
6
|
+
</script>
|
|
2
7
|
|
|
3
8
|
<template>
|
|
4
|
-
<
|
|
9
|
+
<Heading
|
|
10
|
+
:id="alertDialogLabelledBy"
|
|
11
|
+
level="h2"
|
|
12
|
+
>
|
|
5
13
|
<slot />
|
|
6
|
-
</
|
|
14
|
+
</Heading>
|
|
7
15
|
</template>
|
|
@@ -28,21 +28,20 @@ A modal dialog that interrupts the user with important content and expects a res
|
|
|
28
28
|
<Button @click="alertDialogOpen = true">
|
|
29
29
|
Open Dialog
|
|
30
30
|
</Button>
|
|
31
|
-
|
|
32
|
-
<
|
|
33
|
-
<
|
|
34
|
-
<
|
|
35
|
-
<
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
</
|
|
39
|
-
|
|
40
|
-
<
|
|
41
|
-
<
|
|
42
|
-
|
|
43
|
-
</
|
|
44
|
-
</
|
|
45
|
-
</AlertDialog>
|
|
31
|
+
<AlertDialog :open="alertDialogOpen" @cancel="alertDialogOpen = false">
|
|
32
|
+
<AlertDialogContent>
|
|
33
|
+
<AlertDialogHeader>
|
|
34
|
+
<AlertDialogTitle>Are you absolutely sure?</AlertDialogTitle>
|
|
35
|
+
<AlertDialogDescription>
|
|
36
|
+
This action cannot be undone. This will permanently delete your account and remove your data from our servers.
|
|
37
|
+
</AlertDialogDescription>
|
|
38
|
+
</AlertDialogHeader>
|
|
39
|
+
<AlertDialogFooter>
|
|
40
|
+
<AlertDialogCancelButton>Cancel</AlertDialogCancelButton>
|
|
41
|
+
<AlertDialogActionButton>Continue</AlertDialogActionButton>
|
|
42
|
+
</AlertDialogFooter>
|
|
43
|
+
</AlertDialogContent>
|
|
44
|
+
</AlertDialog>
|
|
46
45
|
</ComponentWrapper>
|
|
47
46
|
|
|
48
47
|
```js-vue
|
|
@@ -57,7 +56,7 @@ import {
|
|
|
57
56
|
AlertDialogHeader,
|
|
58
57
|
AlertDialogTitle,
|
|
59
58
|
Button,
|
|
60
|
-
} from 'focus-ui';
|
|
59
|
+
} from '@returnless/focus-ui';
|
|
61
60
|
|
|
62
61
|
const alertDialogOpen = ref(false);
|
|
63
62
|
</script>
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
withDefaults(defineProps<{
|
|
3
|
+
/** The aspect ratio of the element. */
|
|
4
|
+
ratio?: number;
|
|
5
|
+
}>(), {
|
|
6
|
+
ratio: 1,
|
|
7
|
+
});
|
|
8
|
+
</script>
|
|
9
|
+
|
|
10
|
+
<template>
|
|
11
|
+
<div
|
|
12
|
+
:style="{ paddingBottom: `${100 / ratio}%` }"
|
|
13
|
+
class="relative w-full"
|
|
14
|
+
>
|
|
15
|
+
<div class="absolute inset-0 [&>*]:object-cover [&>*]:w-full [&>*]:h-full">
|
|
16
|
+
<slot />
|
|
17
|
+
</div>
|
|
18
|
+
</div>
|
|
19
|
+
</template>
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { AspectRatio } from '../../src/components';
|
|
3
|
+
import api from '../component-meta/AspectRatio.json';
|
|
4
|
+
</script>
|
|
5
|
+
|
|
6
|
+
# Aspect Ratio
|
|
7
|
+
|
|
8
|
+
The AspectRatio component is a layout component that enforces a fixed aspect ratio on its children. This is useful when
|
|
9
|
+
you want to ensure that a child component maintains a specific aspect ratio, regardless of the size of the parent
|
|
10
|
+
component.
|
|
11
|
+
|
|
12
|
+
<ComponentApi :api="api" />
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
<ComponentWrapper>
|
|
17
|
+
<div style="width: 400px;">
|
|
18
|
+
<AspectRatio :ratio="16 / 9">
|
|
19
|
+
<img src="https://www.retourneren.nl/media/catalog/product/cache/8d4d2075b1a30681853bef5bdc41b164/r/e/returnless_afbeelding.jpg">
|
|
20
|
+
</AspectRatio>
|
|
21
|
+
</div>
|
|
22
|
+
</ComponentWrapper>
|
|
23
|
+
|
|
24
|
+
```js-vue
|
|
25
|
+
<script lang="ts" setup>
|
|
26
|
+
import { AspectRatio } from '@returnless/focus-ui';
|
|
27
|
+
</script>
|
|
28
|
+
|
|
29
|
+
<template>
|
|
30
|
+
<div style="width: 400px;">
|
|
31
|
+
<AspectRatio :ratio="16 / 9">
|
|
32
|
+
<img src="https://www.retourneren.nl/media/catalog/product/cache/8d4d2075b1a30681853bef5bdc41b164/r/e/returnless_afbeelding.jpg">
|
|
33
|
+
</AspectRatio>
|
|
34
|
+
</div>
|
|
35
|
+
</template>
|
|
36
|
+
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { default as AspectRatio } from './AspectRatio.vue';
|
|
@@ -1,47 +1,59 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import { UserIcon } from '@heroicons/vue/16/solid';
|
|
3
|
-
import { computed } from 'vue';
|
|
3
|
+
import { computed, ref } from 'vue';
|
|
4
|
+
import { AspectRatio } from '../AspectRatio';
|
|
5
|
+
import { Image } from '../Image';
|
|
4
6
|
|
|
5
7
|
const props = withDefaults(defineProps<{
|
|
6
8
|
/** The size of the avatar */
|
|
7
9
|
size?: 'xs' | 'sm' | 'md' | 'lg' | 'xl';
|
|
8
10
|
|
|
9
11
|
/** The name of the person, company or entity */
|
|
10
|
-
name?: string |
|
|
12
|
+
name?: string | undefined;
|
|
11
13
|
|
|
12
14
|
/** Initials of person to display. */
|
|
13
15
|
initials?: string | null;
|
|
14
16
|
|
|
15
17
|
/** URL of the avatar image which falls back to initials if the image fails to load. */
|
|
16
|
-
source?: string |
|
|
18
|
+
source?: string | undefined;
|
|
17
19
|
|
|
18
20
|
/** Accessible label for the avatar image. */
|
|
19
21
|
accessibilityLabel?: string | null;
|
|
20
22
|
}>(), {
|
|
21
23
|
size: 'md',
|
|
22
|
-
name:
|
|
24
|
+
name: undefined,
|
|
23
25
|
initials: null,
|
|
24
|
-
source:
|
|
26
|
+
source: undefined,
|
|
25
27
|
accessibilityLabel: null,
|
|
26
28
|
});
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
enum ImageLoadingState {
|
|
31
|
+
Pending = 'PENDING',
|
|
32
|
+
Loaded = 'LOADED',
|
|
33
|
+
Errored = 'ERRORED',
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const imageLoadingState = ref<ImageLoadingState>(ImageLoadingState.Pending);
|
|
37
|
+
|
|
38
|
+
const classList = computed((): Record<string, boolean>[] => {
|
|
29
39
|
return [
|
|
30
40
|
{ 'w-4 h-4': props.size === 'xs' },
|
|
31
41
|
{ 'w-6 h-6': props.size === 'sm' },
|
|
32
42
|
{ 'w-8 h-8': props.size === 'md' },
|
|
33
43
|
{ 'w-10 h-10': props.size === 'lg' },
|
|
34
44
|
{ 'w-12 h-12': props.size === 'xl' },
|
|
45
|
+
|
|
46
|
+
{ 'bg-slate-200': imageLoadingState.value !== ImageLoadingState.Loaded },
|
|
35
47
|
];
|
|
36
48
|
});
|
|
37
49
|
|
|
38
|
-
const iconSize = computed(() => {
|
|
50
|
+
const iconSize = computed((): Record<string, boolean>[] => {
|
|
39
51
|
return [
|
|
40
52
|
{ 'w-3 h-3': props.size === 'xs' },
|
|
41
53
|
];
|
|
42
54
|
});
|
|
43
55
|
|
|
44
|
-
const textSize = computed(() => {
|
|
56
|
+
const textSize = computed((): Record<string, boolean>[] => {
|
|
45
57
|
return [
|
|
46
58
|
{ 'text-xs': props.size === 'xs' },
|
|
47
59
|
{ 'text-xs': props.size === 'sm' },
|
|
@@ -56,23 +68,55 @@ function renderInitials(initials: string): string {
|
|
|
56
68
|
? initials?.slice(0, 1)
|
|
57
69
|
: initials;
|
|
58
70
|
}
|
|
71
|
+
|
|
72
|
+
function handleImageError(): void {
|
|
73
|
+
imageLoadingState.value = ImageLoadingState.Errored;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function handleImageLoad(): void {
|
|
77
|
+
imageLoadingState.value = ImageLoadingState.Loaded;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const accessibilityLabelValue = computed((): string | undefined => {
|
|
81
|
+
const accessibilityLabel = props.accessibilityLabel || props.name;
|
|
82
|
+
|
|
83
|
+
return accessibilityLabel
|
|
84
|
+
? accessibilityLabel
|
|
85
|
+
: undefined;
|
|
86
|
+
});
|
|
59
87
|
</script>
|
|
60
88
|
|
|
61
89
|
<template>
|
|
62
|
-
<
|
|
63
|
-
|
|
90
|
+
<span
|
|
91
|
+
:aria-label="accessibilityLabelValue"
|
|
64
92
|
:class="classList"
|
|
93
|
+
class="relative flex items-center justify-center overflow-hidden rounded"
|
|
65
94
|
>
|
|
66
95
|
<UserIcon
|
|
67
96
|
v-if="!initials"
|
|
68
|
-
role="img"
|
|
69
97
|
:class="iconSize"
|
|
98
|
+
role="img"
|
|
70
99
|
/>
|
|
71
100
|
<span
|
|
72
|
-
|
|
101
|
+
v-if="source"
|
|
102
|
+
class="absolute h-full w-full"
|
|
103
|
+
>
|
|
104
|
+
<AspectRatio>
|
|
105
|
+
<Image
|
|
106
|
+
:alt="name!"
|
|
107
|
+
:class="{ 'hidden': imageLoadingState !== ImageLoadingState.Loaded}"
|
|
108
|
+
:source="source"
|
|
109
|
+
@error="handleImageError"
|
|
110
|
+
@load="handleImageLoad"
|
|
111
|
+
/>
|
|
112
|
+
</AspectRatio>
|
|
113
|
+
</span>
|
|
114
|
+
<span
|
|
115
|
+
v-if="initials && imageLoadingState !== ImageLoadingState.Loaded"
|
|
73
116
|
:class="textSize"
|
|
117
|
+
class="font-semibold"
|
|
74
118
|
>
|
|
75
119
|
{{ renderInitials(initials) }}
|
|
76
120
|
</span>
|
|
77
|
-
</
|
|
121
|
+
</span>
|
|
78
122
|
</template>
|
|
@@ -17,7 +17,7 @@ Avatars are used to show a thumbnail representation of an individual or business
|
|
|
17
17
|
|
|
18
18
|
```js-vue
|
|
19
19
|
<script lang="ts" setup>
|
|
20
|
-
import { Avatar } from 'focus-ui';
|
|
20
|
+
import { Avatar } from '@returnless/focus-ui';
|
|
21
21
|
</script>
|
|
22
22
|
|
|
23
23
|
<template>
|
|
@@ -35,7 +35,7 @@ import { Avatar } from 'focus-ui';
|
|
|
35
35
|
|
|
36
36
|
```js-vue
|
|
37
37
|
<script lang="ts" setup>
|
|
38
|
-
import { Avatar } from 'focus-ui';
|
|
38
|
+
import { Avatar } from '@returnless/focus-ui';
|
|
39
39
|
</script>
|
|
40
40
|
|
|
41
41
|
<template>
|
|
@@ -66,7 +66,7 @@ import { Avatar } from 'focus-ui';
|
|
|
66
66
|
|
|
67
67
|
```js-vue
|
|
68
68
|
<script lang="ts" setup>
|
|
69
|
-
import { Avatar } from 'focus-ui';
|
|
69
|
+
import { Avatar } from '@returnless/focus-ui';
|
|
70
70
|
</script>
|
|
71
71
|
|
|
72
72
|
<template>
|
|
@@ -109,12 +109,6 @@ For avatars, we recommend using a format that describes what will show in the im
|
|
|
109
109
|
|
|
110
110
|
## Accessibility
|
|
111
111
|
|
|
112
|
-
### Structure
|
|
113
|
-
|
|
114
|
-
The avatar component uses a generated scalable vector graphics (SVG) file, which can cause challenges for users that
|
|
115
|
-
use assistive technologies. To create a standard experience, the `<img>` is hidden from assistive technologies by
|
|
116
|
-
using an empty `alt` attribute, and replaced with a `<span>` that has `role="img"`.
|
|
117
|
-
|
|
118
112
|
### Labeling
|
|
119
113
|
|
|
120
114
|
The avatar component represents content, and should have a text equivalent for users using assistive technologies.
|
|
@@ -25,7 +25,7 @@ const colorValues = computed((): CSSProperties => {
|
|
|
25
25
|
};
|
|
26
26
|
});
|
|
27
27
|
|
|
28
|
-
const classList = computed(() => {
|
|
28
|
+
const classList = computed((): Record<string, any> => {
|
|
29
29
|
return [
|
|
30
30
|
{ 'text-xs px-2 py-1': props.size === 'sm' },
|
|
31
31
|
{ 'text-sm px-3 py-1.5': props.size === 'md' },
|
|
@@ -24,7 +24,7 @@ Badges are used to inform users of the tone of an object or of an action that's
|
|
|
24
24
|
|
|
25
25
|
```js-vue
|
|
26
26
|
<script lang="ts" setup>
|
|
27
|
-
import { Badge } from 'focus-ui';
|
|
27
|
+
import { Badge } from '@returnless/focus-ui';
|
|
28
28
|
</script>
|
|
29
29
|
|
|
30
30
|
<template>
|
|
@@ -43,7 +43,7 @@ Badges can include icons to help users quickly identify the tone of an object or
|
|
|
43
43
|
<ComponentWrapper>
|
|
44
44
|
<ComponentGrid>
|
|
45
45
|
<Badge color="green">
|
|
46
|
-
<
|
|
46
|
+
<BadgeContent>+ 25%</BadgeContent>
|
|
47
47
|
<BadgeIcon>
|
|
48
48
|
<ArrowTrendingUpIcon />
|
|
49
49
|
</BadgeIcon>
|
|
@@ -52,20 +52,20 @@ Badges can include icons to help users quickly identify the tone of an object or
|
|
|
52
52
|
<BadgeIcon>
|
|
53
53
|
<ArrowTrendingDownIcon />
|
|
54
54
|
</BadgeIcon>
|
|
55
|
-
<
|
|
55
|
+
<BadgeContent>- 25%</BadgeContent>
|
|
56
56
|
</Badge>
|
|
57
57
|
</ComponentGrid>
|
|
58
58
|
</ComponentWrapper>
|
|
59
59
|
|
|
60
60
|
```js-vue
|
|
61
61
|
<script lang="ts" setup>
|
|
62
|
-
import { Badge,
|
|
62
|
+
import { Badge, BadgeContent, BadgeIcon } from '@returnless/focus-ui';
|
|
63
63
|
import { ArrowTrendingUpIcon, ArrowTrendingDownIcon } from '@heroicons/vue/16/solid';
|
|
64
64
|
</script>
|
|
65
65
|
|
|
66
66
|
<template>
|
|
67
67
|
<Badge color="green">
|
|
68
|
-
<
|
|
68
|
+
<BadgeContent>+ 25%</BadgeContent>
|
|
69
69
|
<BadgeIcon>
|
|
70
70
|
<ArrowTrendingUpIcon />
|
|
71
71
|
</BadgeIcon>
|
|
@@ -74,7 +74,7 @@ import { ArrowTrendingUpIcon, ArrowTrendingDownIcon } from '@heroicons/vue/16/so
|
|
|
74
74
|
<BadgeIcon>
|
|
75
75
|
<ArrowTrendingDownIcon />
|
|
76
76
|
</BadgeIcon>
|
|
77
|
-
<
|
|
77
|
+
<BadgeContent>- 25%</BadgeContent>
|
|
78
78
|
</Badge>
|
|
79
79
|
</template>
|
|
80
80
|
```
|
|
@@ -92,19 +92,19 @@ Badges come in three sizes: small, medium, and large.
|
|
|
92
92
|
<BadgeIcon>
|
|
93
93
|
<ArrowTrendingUpIcon />
|
|
94
94
|
</BadgeIcon>
|
|
95
|
-
<
|
|
95
|
+
<BadgeContent>sm with icon</BadgeContent>
|
|
96
96
|
</Badge>
|
|
97
97
|
<Badge color="blue" size="md">
|
|
98
98
|
<BadgeIcon>
|
|
99
99
|
<ArrowTrendingUpIcon />
|
|
100
100
|
</BadgeIcon>
|
|
101
|
-
<
|
|
101
|
+
<BadgeContent>md with icon</BadgeContent>
|
|
102
102
|
</Badge>
|
|
103
103
|
<Badge color="red" size="lg">
|
|
104
104
|
<BadgeIcon>
|
|
105
105
|
<ArrowTrendingDownIcon />
|
|
106
106
|
</BadgeIcon>
|
|
107
|
-
<
|
|
107
|
+
<BadgeContent>lg with icon</BadgeContent>
|
|
108
108
|
</Badge>
|
|
109
109
|
</ComponentGrid>
|
|
110
110
|
</ComponentWrapper>
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import collect, { Collection } from 'collect.js';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
import { TailwindColor, useTailwindColor } from '../../composables';
|
|
5
|
+
import { BarChartContainer } from './';
|
|
6
|
+
import { Legend, LegendItem } from '../Legend';
|
|
7
|
+
|
|
8
|
+
type DataPoint = {
|
|
9
|
+
label: string;
|
|
10
|
+
value: number;
|
|
11
|
+
color: TailwindColor;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const props = defineProps<{
|
|
15
|
+
/** The data points to display */
|
|
16
|
+
dataPoints: DataPoint[];
|
|
17
|
+
|
|
18
|
+
/** The height of the chart */
|
|
19
|
+
height: number;
|
|
20
|
+
}>();
|
|
21
|
+
|
|
22
|
+
const dataPointCollection = computed((): Collection<DataPoint> => {
|
|
23
|
+
return collect(props.dataPoints);
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
const max = computed((): number => {
|
|
27
|
+
return dataPointCollection.value.max('value');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function dataPointHeight(dataPoint: DataPoint): number {
|
|
31
|
+
return dataPoint.value / max.value * 100;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getColorValue(dataPoint: DataPoint): string {
|
|
35
|
+
return useTailwindColor(dataPoint.color, '400');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const axisLabels = computed(() => {
|
|
39
|
+
return [
|
|
40
|
+
props.dataPoints[0].label,
|
|
41
|
+
props.dataPoints[props.dataPoints.length - 1].label,
|
|
42
|
+
];
|
|
43
|
+
});
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<BarChartContainer>
|
|
48
|
+
<Legend>
|
|
49
|
+
<LegendItem color="blue">
|
|
50
|
+
En-route
|
|
51
|
+
</LegendItem>
|
|
52
|
+
</Legend>
|
|
53
|
+
|
|
54
|
+
<div class="space-y-2">
|
|
55
|
+
<div
|
|
56
|
+
class="flex space-x-1"
|
|
57
|
+
:style="{ height: `${height}px` }"
|
|
58
|
+
>
|
|
59
|
+
<div
|
|
60
|
+
v-for="(dataPoint, dataPointIndex) in dataPoints"
|
|
61
|
+
:key="dataPointIndex"
|
|
62
|
+
:style="{ width: `${100 / dataPoints.length}%` }"
|
|
63
|
+
class="flex h-full items-end rounded-sm bg-slate-100"
|
|
64
|
+
>
|
|
65
|
+
<div
|
|
66
|
+
class="w-full rounded-sm"
|
|
67
|
+
:style="{
|
|
68
|
+
height: `${dataPointHeight(dataPoint)}%`,
|
|
69
|
+
backgroundColor: getColorValue(dataPoint),
|
|
70
|
+
}"
|
|
71
|
+
/>
|
|
72
|
+
</div>
|
|
73
|
+
</div>
|
|
74
|
+
<div class="flex justify-between">
|
|
75
|
+
<div>{{ axisLabels[0] }}</div>
|
|
76
|
+
<div>{{ axisLabels[1] }}</div>
|
|
77
|
+
</div>
|
|
78
|
+
</div>
|
|
79
|
+
</BarChartContainer>
|
|
80
|
+
</template>
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import collect from 'collect.js';
|
|
3
|
+
import { computed } from 'vue';
|
|
4
|
+
import { TailwindColor, useTailwindColor } from '../../composables';
|
|
5
|
+
import { Legend, LegendItem } from '../Legend';
|
|
6
|
+
import { BarChartContainer } from './index';
|
|
7
|
+
|
|
8
|
+
type DataPointStack = {
|
|
9
|
+
label: string;
|
|
10
|
+
dataPoints: DataPoint[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
type DataPoint = {
|
|
14
|
+
label: string;
|
|
15
|
+
value: number;
|
|
16
|
+
color: TailwindColor;
|
|
17
|
+
};
|
|
18
|
+
|
|
19
|
+
const props = defineProps<{
|
|
20
|
+
dataPoints: DataPointStack[];
|
|
21
|
+
height: number;
|
|
22
|
+
}>();
|
|
23
|
+
|
|
24
|
+
const max = computed((): number => {
|
|
25
|
+
return collect(props.dataPoints)
|
|
26
|
+
.map((dataPointStack: DataPointStack) => collect(dataPointStack.dataPoints).sum('value'))
|
|
27
|
+
.max();
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
function getDataPointHeight(dataPoint: DataPoint): number {
|
|
31
|
+
return dataPoint.value / max.value * 100;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
function getColorValue(dataPoint: DataPoint): string {
|
|
35
|
+
return useTailwindColor(dataPoint.color, '400');
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const axisLabels = computed((): string[] => {
|
|
39
|
+
return [
|
|
40
|
+
props.dataPoints[0].label,
|
|
41
|
+
props.dataPoints[props.dataPoints.length - 1].label,
|
|
42
|
+
];
|
|
43
|
+
});
|
|
44
|
+
</script>
|
|
45
|
+
|
|
46
|
+
<template>
|
|
47
|
+
<BarChartContainer>
|
|
48
|
+
<Legend>
|
|
49
|
+
<LegendItem color="teal">
|
|
50
|
+
Announced
|
|
51
|
+
</LegendItem>
|
|
52
|
+
<LegendItem color="green">
|
|
53
|
+
Sent
|
|
54
|
+
</LegendItem>
|
|
55
|
+
<LegendItem color="lime">
|
|
56
|
+
En-route
|
|
57
|
+
</LegendItem>
|
|
58
|
+
<LegendItem color="yellow">
|
|
59
|
+
Delivered
|
|
60
|
+
</LegendItem>
|
|
61
|
+
<LegendItem color="amber">
|
|
62
|
+
En-route
|
|
63
|
+
</LegendItem>
|
|
64
|
+
</Legend>
|
|
65
|
+
<div class="space-y-2">
|
|
66
|
+
<div
|
|
67
|
+
class="flex space-x-1"
|
|
68
|
+
:style="{ height: `${height}px` }"
|
|
69
|
+
>
|
|
70
|
+
<div
|
|
71
|
+
v-for="(dataStack, dataStackIndex) in dataPoints"
|
|
72
|
+
:key="dataStackIndex"
|
|
73
|
+
:style="{ width: `${100 / dataPoints.length}%` }"
|
|
74
|
+
class="flex flex-col-reverse h-full items-end rounded-sm bg-slate-100 overflow-hidden"
|
|
75
|
+
>
|
|
76
|
+
<div
|
|
77
|
+
v-for="(dataPoint, dataPointIndex) in dataStack.dataPoints"
|
|
78
|
+
:key="dataPointIndex"
|
|
79
|
+
class="w-full"
|
|
80
|
+
:style="{
|
|
81
|
+
height: `${getDataPointHeight(dataPoint)}%`,
|
|
82
|
+
backgroundColor: getColorValue(dataPoint),
|
|
83
|
+
}"
|
|
84
|
+
/>
|
|
85
|
+
</div>
|
|
86
|
+
</div>
|
|
87
|
+
<div class="flex justify-between">
|
|
88
|
+
<div>{{ axisLabels[0] }}</div>
|
|
89
|
+
<div>{{ axisLabels[1] }}</div>
|
|
90
|
+
</div>
|
|
91
|
+
</div>
|
|
92
|
+
</BarChartContainer>
|
|
93
|
+
</template>
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { BarChart, BarChartStacked, Card, CardSection, Legend, LegendItem } from '../../src/components';
|
|
3
|
+
import api from '../component-meta/BarChart.json';
|
|
4
|
+
|
|
5
|
+
const dataPoints = Array.from({ length: 30 }).map((_, index) => {
|
|
6
|
+
return {
|
|
7
|
+
value: Math.floor(Math.random() * 200),
|
|
8
|
+
label: `data-point ${index}`,
|
|
9
|
+
color: 'blue',
|
|
10
|
+
};
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const stackedDataPoints = Array.from({ length: 30 }).map((_, index) => {
|
|
14
|
+
return {
|
|
15
|
+
label: `data-point ${index}`,
|
|
16
|
+
dataPoints: Array.from({ length: 5 }).map((_, index) => {
|
|
17
|
+
return {
|
|
18
|
+
value: Math.floor(Math.random() * 200),
|
|
19
|
+
label: `data-point ${index}`,
|
|
20
|
+
color: ['teal', 'green', 'lime', 'yellow', 'amber'][index],
|
|
21
|
+
};
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
});
|
|
25
|
+
</script>
|
|
26
|
+
|
|
27
|
+
# Bar Chart
|
|
28
|
+
|
|
29
|
+
<ComponentApi :api="api" />
|
|
30
|
+
|
|
31
|
+
## Usage
|
|
32
|
+
|
|
33
|
+
Use the `BarChart` component to display a single data point in a bar.
|
|
34
|
+
|
|
35
|
+
<ComponentWrapper>
|
|
36
|
+
<Card>
|
|
37
|
+
<CardSection>
|
|
38
|
+
<BarChart :data-points="dataPoints" height="150" />
|
|
39
|
+
</CardSection>
|
|
40
|
+
</Card>
|
|
41
|
+
</ComponentWrapper>
|
|
42
|
+
|
|
43
|
+
```js-vue
|
|
44
|
+
<script lang="ts" setup>
|
|
45
|
+
import { BarChart, Card, CardSection } from '@returnless/focus-ui';
|
|
46
|
+
</script>
|
|
47
|
+
|
|
48
|
+
<template>
|
|
49
|
+
<Card>
|
|
50
|
+
<CardSection>
|
|
51
|
+
<BarChart :data-points="dataPoints" height="200" />
|
|
52
|
+
</CardSection>
|
|
53
|
+
</Card>
|
|
54
|
+
</template>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Stacked Bar Chart
|
|
58
|
+
|
|
59
|
+
Use the `BarChartStacked` component to display multiple data points in a single bar.
|
|
60
|
+
|
|
61
|
+
<ComponentWrapper>
|
|
62
|
+
<Card>
|
|
63
|
+
<CardSection>
|
|
64
|
+
<BarChartStacked :data-points="stackedDataPoints" height="150">
|
|
65
|
+
test
|
|
66
|
+
</BarChartStacked>
|
|
67
|
+
</CardSection>
|
|
68
|
+
</Card>
|
|
69
|
+
</ComponentWrapper>
|
|
70
|
+
|
|
71
|
+
```js-vue
|
|
72
|
+
<script lang="ts" setup>
|
|
73
|
+
import { BarChartStacked, Card, CardSection } from '@returnless/focus-ui';
|
|
74
|
+
</script>
|
|
75
|
+
|
|
76
|
+
<template>
|
|
77
|
+
<Card>
|
|
78
|
+
<CardSection>
|
|
79
|
+
<BarChartStacked :data-points="dataPoints" height="200" />
|
|
80
|
+
</CardSection>
|
|
81
|
+
</Card>
|
|
82
|
+
</template>
|
|
83
|
+
```
|