sprintify-ui 0.0.123 → 0.0.125

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.
@@ -0,0 +1,68 @@
1
+ import { PropType } from 'vue';
2
+ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
3
+ value: {
4
+ required: true;
5
+ type: StringConstructor;
6
+ };
7
+ showTooltip: {
8
+ default: boolean;
9
+ type: BooleanConstructor;
10
+ };
11
+ tooltipPosition: {
12
+ default: string;
13
+ type: PropType<"left" | "right" | "top" | "bottom">;
14
+ };
15
+ tooltipSize: {
16
+ default: string;
17
+ type: PropType<"small" | "large" | "medium">;
18
+ };
19
+ timeZone: {
20
+ default: string;
21
+ type: StringConstructor;
22
+ };
23
+ as: {
24
+ default: string;
25
+ type: StringConstructor;
26
+ };
27
+ }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
28
+ value: {
29
+ required: true;
30
+ type: StringConstructor;
31
+ };
32
+ showTooltip: {
33
+ default: boolean;
34
+ type: BooleanConstructor;
35
+ };
36
+ tooltipPosition: {
37
+ default: string;
38
+ type: PropType<"left" | "right" | "top" | "bottom">;
39
+ };
40
+ tooltipSize: {
41
+ default: string;
42
+ type: PropType<"small" | "large" | "medium">;
43
+ };
44
+ timeZone: {
45
+ default: string;
46
+ type: StringConstructor;
47
+ };
48
+ as: {
49
+ default: string;
50
+ type: StringConstructor;
51
+ };
52
+ }>>, {
53
+ as: string;
54
+ showTooltip: boolean;
55
+ tooltipPosition: "left" | "right" | "top" | "bottom";
56
+ tooltipSize: "small" | "large" | "medium";
57
+ timeZone: string;
58
+ }>, {
59
+ default: (_: {
60
+ readableDate: string;
61
+ }) => any;
62
+ }>;
63
+ export default _default;
64
+ type __VLS_WithTemplateSlots<T, S> = T & {
65
+ new (): {
66
+ $slots: S;
67
+ };
68
+ };
@@ -2,7 +2,7 @@ import { PropType } from 'vue';
2
2
  declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
3
3
  modelValue: {
4
4
  default: boolean;
5
- type: BooleanConstructor;
5
+ type: PropType<boolean | null | undefined>;
6
6
  };
7
7
  name: {
8
8
  default: undefined;
@@ -27,7 +27,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
27
27
  }, {}, unknown, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, "update:modelValue"[], "update:modelValue", import("vue").VNodeProps & import("vue").AllowedComponentProps & import("vue").ComponentCustomProps, Readonly<import("vue").ExtractPropTypes<{
28
28
  modelValue: {
29
29
  default: boolean;
30
- type: BooleanConstructor;
30
+ type: PropType<boolean | null | undefined>;
31
31
  };
32
32
  name: {
33
33
  default: undefined;
@@ -56,7 +56,7 @@ declare const _default: __VLS_WithTemplateSlots<import("vue").DefineComponent<{
56
56
  name: string;
57
57
  color: "dark" | "light" | "danger" | "success" | "warning" | "info" | "primary";
58
58
  size: "base" | "xs" | "sm" | "lg" | "xl";
59
- modelValue: boolean;
59
+ modelValue: boolean | null | undefined;
60
60
  hasError: boolean;
61
61
  }>, {
62
62
  default: (_: {}) => any;
@@ -28,6 +28,7 @@ import BaseDateSelect from './BaseDateSelect.vue';
28
28
  import BaseDescriptionList from './BaseDescriptionList.vue';
29
29
  import BaseDescriptionListItem from './BaseDescriptionListItem.vue';
30
30
  import BaseDialog from './BaseDialog.vue';
31
+ import BaseDisplayRelativeTime from './BaseDisplayRelativeTime.vue';
31
32
  import BaseDropdown from './BaseDropdown.vue';
32
33
  import BaseDropdownAutocomplete from './BaseDropdownAutocomplete.vue';
33
34
  import BaseField from './BaseField.vue';
@@ -79,4 +80,4 @@ import BaseLayoutStacked from './BaseLayoutStacked.vue';
79
80
  import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
80
81
  import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
81
82
  import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
82
- export { BaseActionItem, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClickOutside, BaseClipboard, BaseColor, BaseContainer, BaseCounter, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDropdown, BaseDropdownAutocomplete, BaseField, BaseFieldI18n, BaseFilePicker, BaseFileUploader, BaseForm, BaseHasMany, BaseIcon, BaseInput, BaseInputLabel, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseSwitch, BaseSystemAlert, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTable, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
83
+ export { BaseActionItem, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClickOutside, BaseClipboard, BaseColor, BaseContainer, BaseCounter, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDisplayRelativeTime, BaseDropdown, BaseDropdownAutocomplete, BaseField, BaseFieldI18n, BaseFilePicker, BaseFileUploader, BaseForm, BaseHasMany, BaseIcon, BaseInput, BaseInputLabel, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseSwitch, BaseSystemAlert, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTable, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
@@ -68,6 +68,7 @@ declare const messages: {
68
68
  yes_delete: string;
69
69
  you_can_upload_up_to_n_files: string;
70
70
  you_cannot_select_more_than_x_items: string;
71
+ just_now: string;
71
72
  };
72
73
  };
73
74
  fr: {
@@ -132,6 +133,7 @@ declare const messages: {
132
133
  yes_delete: string;
133
134
  you_can_upload_up_to_n_files: string;
134
135
  you_cannot_select_more_than_x_items: string;
136
+ just_now: string;
135
137
  };
136
138
  };
137
139
  };
@@ -209,6 +211,7 @@ declare const config: {
209
211
  yes_delete: string;
210
212
  you_can_upload_up_to_n_files: string;
211
213
  you_cannot_select_more_than_x_items: string;
214
+ just_now: string;
212
215
  };
213
216
  };
214
217
  fr: {
@@ -273,6 +276,7 @@ declare const config: {
273
276
  yes_delete: string;
274
277
  you_can_upload_up_to_n_files: string;
275
278
  you_cannot_select_more_than_x_items: string;
279
+ just_now: string;
276
280
  };
277
281
  };
278
282
  }, {}, {}, string, true>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "sprintify-ui",
3
- "version": "0.0.123",
3
+ "version": "0.0.125",
4
4
  "scripts": {
5
5
  "build": "rimraf dist && vue-tsc && vite build",
6
6
  "build-fast": "rimraf dist && vite build",
@@ -105,6 +105,20 @@ watch(
105
105
  }
106
106
  );
107
107
 
108
+ window.addEventListener('keydown', onKeydown);
109
+
110
+ onBeforeUnmount(() => {
111
+ window.removeEventListener('keydown', onKeydown);
112
+ });
113
+
114
+ function onKeydown(event: KeyboardEvent) {
115
+ if (dialogs.value.length == 0) return;
116
+
117
+ if (event.key === 'Escape') {
118
+ cancel(dialogs.value[dialogs.value.length - 1]);
119
+ }
120
+ }
121
+
108
122
  defineExpose({
109
123
  dialogs,
110
124
  });
@@ -42,7 +42,7 @@
42
42
  {{ title }}
43
43
  </h3>
44
44
  <div class="mt-2">
45
- <p class="text-base font-light text-slate-600">
45
+ <p class="text-base font-normal text-slate-600">
46
46
  {{ message }}
47
47
  </p>
48
48
  </div>
@@ -51,6 +51,7 @@
51
51
  </div>
52
52
  <div class="mt-5 sm:mt-4 sm:flex sm:flex-row-reverse">
53
53
  <button
54
+ ref="confirm"
54
55
  type="button"
55
56
  class="btn mb-2 w-full sm:mb-0 sm:w-auto"
56
57
  :class="{
@@ -75,7 +76,7 @@
75
76
  </template>
76
77
 
77
78
  <script lang="ts" setup>
78
- import { PropType } from 'vue';
79
+ import { PropType, Ref } from 'vue';
79
80
  import { Icon as BaseIcon } from '@iconify/vue';
80
81
 
81
82
  defineProps({
@@ -108,4 +109,12 @@ defineProps({
108
109
  });
109
110
 
110
111
  defineEmits(['cancel', 'confirm']);
112
+
113
+ const confirm = ref(null) as Ref<HTMLButtonElement | null>;
114
+
115
+ onMounted(() => {
116
+ if (confirm.value) {
117
+ confirm.value.focus();
118
+ }
119
+ });
111
120
  </script>
@@ -0,0 +1,59 @@
1
+ import BaseDisplayRelativeTime from './BaseDisplayRelativeTime.vue';
2
+ import { DateTime } from 'luxon';
3
+
4
+ export default {
5
+ title: 'Components/BaseDisplayRelativeTime',
6
+ component: BaseDisplayRelativeTime,
7
+ argTypes: {
8
+ showTooltip: {
9
+ control: { type: 'boolean' },
10
+ },
11
+ tooltipPosition: {
12
+ options: ['top', 'bottom', 'right', 'left'],
13
+ control: { type: 'radio' },
14
+ if: { arg: 'showTooltip' },
15
+ },
16
+ tooltipSize: {
17
+ options: ['small', 'medium', 'large'],
18
+ control: { type: 'radio' },
19
+ if: { arg: 'showTooltip' },
20
+ },
21
+ },
22
+ args: {
23
+ value: DateTime.now().minus({ minutes: 2 }).toISO(),
24
+ },
25
+ };
26
+
27
+ const Template = (args) => ({
28
+ components: { BaseDisplayRelativeTime },
29
+ setup() {
30
+ return { args };
31
+ },
32
+ template: `
33
+ <BaseDisplayRelativeTime v-bind="args"></BaseDisplayRelativeTime>
34
+ `,
35
+ });
36
+
37
+ export const Demo = Template.bind({});
38
+ Demo.args = {
39
+ showTooltip: true,
40
+ tooltipPosition: 'top',
41
+ tooltipSize: 'large',
42
+ };
43
+
44
+ const TemplateCustom = (args) => ({
45
+ components: { BaseDisplayRelativeTime },
46
+ setup() {
47
+ return { args };
48
+ },
49
+ template: `
50
+ <BaseDisplayRelativeTime v-bind="args" v-slot="{readableDate}">
51
+ <span class="text-red-500">
52
+ {{readableDate}}
53
+ </span>
54
+ </BaseDisplayRelativeTime>
55
+ `,
56
+ });
57
+
58
+ export const CustomSlot = TemplateCustom.bind({});
59
+ CustomSlot.args = {};
@@ -0,0 +1,122 @@
1
+ <template>
2
+ <component
3
+ :is="as"
4
+ :aria-label="showTooltip ? tooltip : undefined"
5
+ :data-microtip-position="showTooltip ? tooltipPosition : undefined"
6
+ :data-microtip-size="showTooltip ? tooltipSize : undefined"
7
+ :role="showTooltip ? 'tooltip' : undefined"
8
+ >
9
+ <slot name="default" :readable-date="readableDate">
10
+ <span
11
+ class="cursor-pointer rounded-full px-3 py-1 text-xs text-slate-600 hover:bg-slate-50"
12
+ >
13
+ {{ readableDate }}
14
+ </span>
15
+ </slot>
16
+ </component>
17
+ </template>
18
+
19
+ <script lang="ts" setup>
20
+ import humanizeDuration from 'humanize-duration';
21
+ import { DateTime } from 'luxon';
22
+ import { PropType } from 'vue';
23
+ const props = defineProps({
24
+ value: {
25
+ required: true,
26
+ type: String,
27
+ },
28
+ showTooltip: {
29
+ default: true,
30
+ type: Boolean,
31
+ },
32
+ tooltipPosition: {
33
+ default: 'top',
34
+ type: String as PropType<'top' | 'right' | 'left' | 'bottom'>,
35
+ },
36
+ tooltipSize: {
37
+ default: 'large',
38
+ type: String as PropType<'small' | 'medium' | 'large'>,
39
+ },
40
+ timeZone: {
41
+ default: 'utc',
42
+ type: String,
43
+ },
44
+ as: {
45
+ default: 'span',
46
+ type: String,
47
+ },
48
+ });
49
+
50
+ const now = ref(DateTime.now().toSeconds());
51
+
52
+ function getMinutes(duration: number) {
53
+ return Math.abs(duration / 60000);
54
+ }
55
+
56
+ function getDuration() {
57
+ const nowLuxon = DateTime.fromSeconds(now.value);
58
+ const duration = DateTime.fromISO(props.value, {
59
+ zone: props.timeZone,
60
+ }).diff(nowLuxon).milliseconds;
61
+
62
+ return duration;
63
+ }
64
+
65
+ function getInterval() {
66
+ const duration = getDuration();
67
+ const minutes = Math.ceil(getMinutes(duration));
68
+
69
+ if (minutes < 10) {
70
+ return 10 * 1000;
71
+ }
72
+
73
+ if (minutes < 60) {
74
+ return 30 * 1000;
75
+ }
76
+
77
+ if (minutes < 1140) {
78
+ return 60 * 1000;
79
+ }
80
+
81
+ if (minutes < 10080) {
82
+ return 60 * 60 * 1000;
83
+ }
84
+
85
+ return 1000;
86
+ }
87
+
88
+ const intervalValue = getInterval();
89
+
90
+ const intervalId = setInterval(() => {
91
+ now.value = DateTime.now().toSeconds();
92
+ }, intervalValue);
93
+
94
+ const i18n = useI18n();
95
+
96
+ const readableDate = computed(() => {
97
+ const duration = getDuration();
98
+ const durationHuman = humanizeDuration(duration, {
99
+ language: i18n.locale.value,
100
+ round: true,
101
+ largest: 1,
102
+ });
103
+
104
+ const minutes = getMinutes(duration);
105
+
106
+ if (minutes < 1) {
107
+ return i18n.t('sui.just_now');
108
+ }
109
+
110
+ return i18n.t('sui.x_ago', { duration: durationHuman });
111
+ });
112
+
113
+ const tooltip = computed(() => {
114
+ return DateTime.fromISO(props.value)
115
+ .setLocale(i18n.locale.value)
116
+ .toLocaleString(DateTime.DATETIME_FULL);
117
+ });
118
+
119
+ onBeforeUnmount(() => {
120
+ clearInterval(intervalId);
121
+ });
122
+ </script>
@@ -2,7 +2,7 @@
2
2
  <SwitchGroup>
3
3
  <div class="inline-flex items-center space-x-3">
4
4
  <Switch
5
- :model-value="modelValue"
5
+ :model-value="modelValue ?? false"
6
6
  :class="[
7
7
  modelValue ? bg : 'bg-slate-200',
8
8
  'relative inline-flex shrink-0 cursor-pointer items-center rounded-full transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-offset-2 ',
@@ -39,7 +39,7 @@ import { PropType } from 'vue';
39
39
  const props = defineProps({
40
40
  modelValue: {
41
41
  default: false,
42
- type: Boolean,
42
+ type: [Boolean, null, undefined] as PropType<boolean | null | undefined>,
43
43
  },
44
44
  name: {
45
45
  default: undefined,
@@ -28,6 +28,7 @@ import BaseDateSelect from './BaseDateSelect.vue';
28
28
  import BaseDescriptionList from './BaseDescriptionList.vue';
29
29
  import BaseDescriptionListItem from './BaseDescriptionListItem.vue';
30
30
  import BaseDialog from './BaseDialog.vue';
31
+ import BaseDisplayRelativeTime from './BaseDisplayRelativeTime.vue';
31
32
  import BaseDropdown from './BaseDropdown.vue';
32
33
  import BaseDropdownAutocomplete from './BaseDropdownAutocomplete.vue';
33
34
  import BaseField from './BaseField.vue';
@@ -112,6 +113,7 @@ export {
112
113
  BaseDescriptionList,
113
114
  BaseDescriptionListItem,
114
115
  BaseDialog,
116
+ BaseDisplayRelativeTime,
115
117
  BaseDropdown,
116
118
  BaseDropdownAutocomplete,
117
119
  BaseField,
package/src/lang/en.json CHANGED
@@ -59,6 +59,7 @@
59
59
  "year": "Year",
60
60
  "yes_delete": "Yes, delete",
61
61
  "you_can_upload_up_to_n_files": "You can upload one file at most|You can upload up to {count} files",
62
- "you_cannot_select_more_than_x_items": "You can't select more than one item|You can't select more than {count} items"
62
+ "you_cannot_select_more_than_x_items": "You can't select more than one item|You can't select more than {count} items",
63
+ "just_now": "Just now"
63
64
  }
64
65
  }
package/src/lang/fr.json CHANGED
@@ -59,6 +59,7 @@
59
59
  "year": "Année",
60
60
  "yes_delete": "Oui, supprimer",
61
61
  "you_can_upload_up_to_n_files": "Vous pouvez télécharger un fichier au maximum|Vous pouvez télécharger jusqu'à {count} fichiers",
62
- "you_cannot_select_more_than_x_items": "Vous ne pouvez pas sélectionner plus de un élément|Vous ne pouvez pas sélectionner plus de {count} éléments"
62
+ "you_cannot_select_more_than_x_items": "Vous ne pouvez pas sélectionner plus de un élément|Vous ne pouvez pas sélectionner plus de {count} éléments",
63
+ "just_now": "à l’instant"
63
64
  }
64
65
  }