sprintify-ui 0.6.78 → 0.6.80
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 +7 -1
- package/dist/sprintify-ui.es.js +10736 -10413
- package/dist/style.css +1 -1
- package/dist/types/src/components/BaseAddressForm.vue.d.ts +10 -0
- package/dist/types/src/components/BaseGantt.vue.d.ts +8 -8
- package/dist/types/src/components/BaseScrollColumn.vue.d.ts +53 -0
- package/dist/types/src/components/BaseTextareaAutoresize.vue.d.ts +1 -1
- package/dist/types/src/components/BaseTimePicker.vue.d.ts +118 -0
- package/dist/types/src/components/index.d.ts +2 -1
- package/dist/types/src/index.d.ts +8 -0
- package/package.json +1 -1
- package/src/assets/base-time-picker.css +10 -0
- package/src/assets/main.css +1 -0
- package/src/components/BaseAddressForm.vue +20 -0
- package/src/components/BaseScrollColumn.vue +130 -0
- package/src/components/BaseTimePicker.stories.js +71 -0
- package/src/components/BaseTimePicker.vue +376 -0
- package/src/components/index.ts +2 -0
- package/src/lang/en.json +5 -1
- package/src/lang/fr.json +5 -1
- package/src/stories/PageInputSizes.vue +26 -0
|
@@ -28,6 +28,7 @@ import BaseCropperModal from './BaseCropperModal.vue';
|
|
|
28
28
|
import BaseDataIterator from './BaseDataIterator.vue';
|
|
29
29
|
import BaseDataTable from './BaseDataTable.vue';
|
|
30
30
|
import BaseDatePicker from './BaseDatePicker.vue';
|
|
31
|
+
import BaseTimePicker from './BaseTimePicker.vue';
|
|
31
32
|
import BaseDateSelect from './BaseDateSelect.vue';
|
|
32
33
|
import BaseDescriptionList from './BaseDescriptionList.vue';
|
|
33
34
|
import BaseDescriptionListItem from './BaseDescriptionListItem.vue';
|
|
@@ -100,4 +101,4 @@ import BaseLayoutStacked from './BaseLayoutStacked.vue';
|
|
|
100
101
|
import BaseLayoutStackedConfigurable from './BaseLayoutStackedConfigurable.vue';
|
|
101
102
|
import BaseLayoutSidebar from './BaseLayoutSidebar.vue';
|
|
102
103
|
import BaseLayoutSidebarConfigurable from './BaseLayoutSidebarConfigurable.vue';
|
|
103
|
-
export { BaseActionItem, BaseAddressForm, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBelongsToFetch, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseCalendar, BaseColor, BaseContainer, BaseCounter, BaseCropper, BaseCropperModal, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDisplayRelativeTime, BaseDropdown, BaseDropdownAutocomplete, BaseEmptyState, BaseField, BaseFieldI18n, BaseFilePicker, BaseFilePickerCrop, BaseFileUploader, BaseForm, BaseGantt, BaseHasMany, BaseHeader, BaseIcon, BaseIconPicker, BaseInput, BaseInputLabel, BaseInputPercent, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BaseNavbarSideItem, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseStepper, BaseStepperItem, BaseSwitch, BaseSystemAlert, BaseTable, BaseTableBody, BaseTableCell, BaseTableHead, BaseTableHeader, BaseTableRow, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseTooltip, BaseUniqueCode, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
|
|
104
|
+
export { BaseActionItem, BaseAddressForm, BaseAlert, BaseApp, BaseAppDialogs, BaseAppNotifications, BaseAutocomplete, BaseAutocompleteFetch, BaseAvatar, BaseAvatarGroup, BaseBadge, BaseBelongsTo, BaseBelongsToFetch, BaseBoolean, BaseBreadcrumbs, BaseButton, BaseButtonGroup, BaseCard, BaseCardRow, BaseCharacterCounter, BaseClipboard, BaseCalendar, BaseColor, BaseContainer, BaseCounter, BaseCropper, BaseCropperModal, BaseDataIterator, BaseDataTable, BaseDatePicker, BaseTimePicker, BaseDateSelect, BaseDescriptionList, BaseDescriptionListItem, BaseDialog, BaseDisplayRelativeTime, BaseDropdown, BaseDropdownAutocomplete, BaseEmptyState, BaseField, BaseFieldI18n, BaseFilePicker, BaseFilePickerCrop, BaseFileUploader, BaseForm, BaseGantt, BaseHasMany, BaseHeader, BaseIcon, BaseIconPicker, BaseInput, BaseInputLabel, BaseInputPercent, BaseLoadingCover, BaseMediaItem, BaseMediaLibrary, BaseMediaPreview, BaseMenu, BaseMenuItem, BaseModalCenter, BaseModalSide, BaseNavbar, BaseNavbarItem, BaseNavbarItemContent, BaseNavbarSideItem, BasePagination, BasePanel, BasePassword, BaseProgressCircle, BaseRadioGroup, BaseReadMore, BaseRichText, BaseSelect, BaseShortcut, BaseSideNavigation, BaseSideNavigationItem, BaseSkeleton, BaseStatistic, BaseStepper, BaseStepperItem, BaseSwitch, BaseSystemAlert, BaseTable, BaseTableBody, BaseTableCell, BaseTableHead, BaseTableHeader, BaseTableRow, BaseTabs, BaseTabItem, BaseTagAutocomplete, BaseTagAutocompleteFetch, BaseTableColumn, BaseTextarea, BaseTextareaAutoresize, BaseTimeline, BaseTimelineItem, BaseTooltip, BaseUniqueCode, BaseLayoutStacked, BaseLayoutStackedConfigurable, BaseLayoutSidebar, BaseLayoutSidebarConfigurable, };
|
|
@@ -15,6 +15,7 @@ declare const messages: {
|
|
|
15
15
|
month: string;
|
|
16
16
|
save: string;
|
|
17
17
|
sui: {
|
|
18
|
+
notes: string;
|
|
18
19
|
address: string;
|
|
19
20
|
address_1_placeholder: string;
|
|
20
21
|
address_2_description: string;
|
|
@@ -28,6 +29,7 @@ declare const messages: {
|
|
|
28
29
|
city: string;
|
|
29
30
|
clear: string;
|
|
30
31
|
click_or_select_date: string;
|
|
32
|
+
click_or_select_time: string;
|
|
31
33
|
click_to_copy: string;
|
|
32
34
|
columns: string;
|
|
33
35
|
confirm: string;
|
|
@@ -58,7 +60,9 @@ declare const messages: {
|
|
|
58
60
|
none: string;
|
|
59
61
|
nothing_found: string;
|
|
60
62
|
notifications_empty: string;
|
|
63
|
+
now: string;
|
|
61
64
|
of: string;
|
|
65
|
+
ok: string;
|
|
62
66
|
or: string;
|
|
63
67
|
page: string;
|
|
64
68
|
pagination_detail_1: string;
|
|
@@ -110,6 +114,7 @@ declare const messages: {
|
|
|
110
114
|
month: string;
|
|
111
115
|
save: string;
|
|
112
116
|
sui: {
|
|
117
|
+
notes: string;
|
|
113
118
|
address: string;
|
|
114
119
|
address_1_placeholder: string;
|
|
115
120
|
address_2_description: string;
|
|
@@ -123,6 +128,7 @@ declare const messages: {
|
|
|
123
128
|
city: string;
|
|
124
129
|
clear: string;
|
|
125
130
|
click_or_select_date: string;
|
|
131
|
+
click_or_select_time: string;
|
|
126
132
|
click_to_copy: string;
|
|
127
133
|
columns: string;
|
|
128
134
|
confirm: string;
|
|
@@ -153,7 +159,9 @@ declare const messages: {
|
|
|
153
159
|
none: string;
|
|
154
160
|
nothing_found: string;
|
|
155
161
|
notifications_empty: string;
|
|
162
|
+
now: string;
|
|
156
163
|
of: string;
|
|
164
|
+
ok: string;
|
|
157
165
|
or: string;
|
|
158
166
|
page: string;
|
|
159
167
|
pagination_detail_1: string;
|
package/package.json
CHANGED
package/src/assets/main.css
CHANGED
|
@@ -103,6 +103,21 @@
|
|
|
103
103
|
@update:model-value="update('region', $event)"
|
|
104
104
|
/>
|
|
105
105
|
</BaseField>
|
|
106
|
+
|
|
107
|
+
<BaseField
|
|
108
|
+
v-if="props.showNotes"
|
|
109
|
+
:label="t('sui.notes')"
|
|
110
|
+
:name="`${namePrefix}notes`"
|
|
111
|
+
:required="isRequired('notes')"
|
|
112
|
+
class="col-span-2"
|
|
113
|
+
:size="size"
|
|
114
|
+
>
|
|
115
|
+
<BaseTextarea
|
|
116
|
+
:model-value="normalizedModelValue.notes ?? ''"
|
|
117
|
+
class="w-full"
|
|
118
|
+
@update:model-value="update('notes', $event)"
|
|
119
|
+
/>
|
|
120
|
+
</BaseField>
|
|
106
121
|
</div>
|
|
107
122
|
</template>
|
|
108
123
|
|
|
@@ -114,6 +129,7 @@ import { Region } from '@/types/Region';
|
|
|
114
129
|
import BaseField from './BaseField.vue';
|
|
115
130
|
import BaseInput from './BaseInput.vue';
|
|
116
131
|
import BaseSelect from './BaseSelect.vue';
|
|
132
|
+
import BaseTextarea from './BaseTextarea.vue';
|
|
117
133
|
import { t } from '@/i18n';
|
|
118
134
|
import { config } from '..';
|
|
119
135
|
import { Size } from '@/utils/sizes';
|
|
@@ -128,6 +144,7 @@ type Address = {
|
|
|
128
144
|
city?: string | null;
|
|
129
145
|
region?: string | null;
|
|
130
146
|
country?: string | null;
|
|
147
|
+
notes?: string | null;
|
|
131
148
|
};
|
|
132
149
|
|
|
133
150
|
const props = withDefaults(
|
|
@@ -141,6 +158,7 @@ const props = withDefaults(
|
|
|
141
158
|
size?: Size;
|
|
142
159
|
hideRegion?: boolean;
|
|
143
160
|
hideCountry?: boolean;
|
|
161
|
+
showNotes?: boolean;
|
|
144
162
|
requiredFields?: (keyof Address)[];
|
|
145
163
|
}>(),
|
|
146
164
|
{
|
|
@@ -158,6 +176,7 @@ const props = withDefaults(
|
|
|
158
176
|
size: undefined,
|
|
159
177
|
hideRegion: false,
|
|
160
178
|
hideCountry: false,
|
|
179
|
+
showNotes: false,
|
|
161
180
|
requiredFields() {
|
|
162
181
|
return ['address_1', 'city', 'postal_code', 'country', 'region'];
|
|
163
182
|
}
|
|
@@ -176,6 +195,7 @@ const normalizedModelValue = computed((): Address => {
|
|
|
176
195
|
form.postal_code = form.postal_code ?? '';
|
|
177
196
|
form.country = form.country ?? '';
|
|
178
197
|
form.region = form.region ?? '';
|
|
198
|
+
form.notes = form.notes ?? '';
|
|
179
199
|
return form;
|
|
180
200
|
});
|
|
181
201
|
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
<template>
|
|
2
|
+
<div
|
|
3
|
+
v-for="time in times"
|
|
4
|
+
:key="time"
|
|
5
|
+
:ref="element"
|
|
6
|
+
class="cursor-pointer py-1 text-center rounded content"
|
|
7
|
+
:class="{ 'bg-slate-100': hoveredIndex === `${type}-${time}`, 'bg-primary-100': selectedValue === `${type}-${time}` }"
|
|
8
|
+
@mouseenter="hoveredIndex = `${type}-${time}`"
|
|
9
|
+
@mouseleave="hoveredIndex = null"
|
|
10
|
+
@click="selectTime(`${type}-${time}`, type, time)"
|
|
11
|
+
>
|
|
12
|
+
{{ time }}
|
|
13
|
+
</div>
|
|
14
|
+
</template>
|
|
15
|
+
|
|
16
|
+
<script lang="ts" setup>
|
|
17
|
+
import { PropType } from 'vue';
|
|
18
|
+
|
|
19
|
+
const props = defineProps({
|
|
20
|
+
value: {
|
|
21
|
+
default: undefined,
|
|
22
|
+
type: [String, null, undefined] as PropType<string | null | undefined>,
|
|
23
|
+
},
|
|
24
|
+
type: {
|
|
25
|
+
default: 'hour',
|
|
26
|
+
type: String,
|
|
27
|
+
},
|
|
28
|
+
element: {
|
|
29
|
+
type: String,
|
|
30
|
+
required: true,
|
|
31
|
+
},
|
|
32
|
+
container: {
|
|
33
|
+
type: [HTMLElement, null] as PropType<HTMLElement | null>,
|
|
34
|
+
required: true,
|
|
35
|
+
},
|
|
36
|
+
times: {
|
|
37
|
+
default: () => Array.from({ length: 24 }, (_, i) => i.toString().padStart(2, '0')),
|
|
38
|
+
type: Array as PropType<string[]>,
|
|
39
|
+
},
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
const emit = defineEmits(['selectTime']);
|
|
43
|
+
|
|
44
|
+
const hoveredIndex = ref('' as string | null);
|
|
45
|
+
const selectedValue = ref('' as string | null);
|
|
46
|
+
const timeValue = ref('' as string | null);
|
|
47
|
+
|
|
48
|
+
const hourElements = ref<Array<HTMLElement | null>>([]);
|
|
49
|
+
const minuteElements = ref<Array<HTMLElement | null>>([]);
|
|
50
|
+
const secondElements = ref<Array<HTMLElement | null>>([]);
|
|
51
|
+
|
|
52
|
+
const selectTime = async (value: string, type: string, time: string) => {
|
|
53
|
+
selectedValue.value = value;
|
|
54
|
+
|
|
55
|
+
timeValue.value = time;
|
|
56
|
+
|
|
57
|
+
let element = [] as (HTMLElement | null)[];
|
|
58
|
+
|
|
59
|
+
if (props.type === 'hour') {
|
|
60
|
+
element = hourElements.value;
|
|
61
|
+
}
|
|
62
|
+
if (props.type === 'minute') {
|
|
63
|
+
element = minuteElements.value;
|
|
64
|
+
}
|
|
65
|
+
if (props.type === 'second') {
|
|
66
|
+
element = secondElements.value;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
scrollToSelectedValue(props.container, element);
|
|
70
|
+
|
|
71
|
+
emit('selectTime', timeValue.value, type);
|
|
72
|
+
};
|
|
73
|
+
|
|
74
|
+
const scrollToSelectedValue = (
|
|
75
|
+
timeContainer: HTMLElement | null,
|
|
76
|
+
timeElement: (HTMLElement | null)[],
|
|
77
|
+
behavior: 'auto' | 'instant' | 'smooth' | undefined = 'smooth'
|
|
78
|
+
) => {
|
|
79
|
+
|
|
80
|
+
console.log('timeContainer', timeContainer, 'timeValue', timeValue.value);
|
|
81
|
+
|
|
82
|
+
if (!timeContainer || !timeValue.value) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
const selectedIndex = props.times.indexOf(timeValue.value);
|
|
87
|
+
|
|
88
|
+
const targetElement = timeElement[selectedIndex];
|
|
89
|
+
|
|
90
|
+
if (targetElement) {
|
|
91
|
+
const containerHeight = timeContainer.clientHeight;
|
|
92
|
+
const elementHeight = targetElement.clientHeight;
|
|
93
|
+
const offsetTop = targetElement.offsetTop;
|
|
94
|
+
const scrollTop = (offsetTop - (containerHeight - elementHeight) / 2);
|
|
95
|
+
|
|
96
|
+
timeContainer.scrollTo({ top: scrollTop, behavior: behavior as any });
|
|
97
|
+
}
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
watch(
|
|
101
|
+
() => props.container,
|
|
102
|
+
() => {
|
|
103
|
+
if (props.value) {
|
|
104
|
+
const [hour, minute, second] = props.value.split(':');
|
|
105
|
+
|
|
106
|
+
let element = [] as (HTMLElement | null)[];
|
|
107
|
+
if (props.type === 'hour') {
|
|
108
|
+
timeValue.value = hour;
|
|
109
|
+
selectedValue.value = `hour-${hour}`;
|
|
110
|
+
element = hourElements.value;
|
|
111
|
+
}
|
|
112
|
+
if (props.type === 'minute') {
|
|
113
|
+
timeValue.value = minute;
|
|
114
|
+
selectedValue.value = `minute-${minute}`;
|
|
115
|
+
element = minuteElements.value;
|
|
116
|
+
}
|
|
117
|
+
if (props.type === 'second') {
|
|
118
|
+
timeValue.value = second;
|
|
119
|
+
selectedValue.value = `second-${second}`;
|
|
120
|
+
element = secondElements.value;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
scrollToSelectedValue(props.container, element, 'instant');
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
},
|
|
127
|
+
{ immediate: true }
|
|
128
|
+
);
|
|
129
|
+
|
|
130
|
+
</script>
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
import { createFieldStory } from '../../.storybook/utils';
|
|
2
|
+
import BaseTimePicker from './BaseTimePicker.vue';
|
|
3
|
+
import ShowValue from '@/../.storybook/components/ShowValue.vue';
|
|
4
|
+
|
|
5
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
6
|
+
|
|
7
|
+
export default {
|
|
8
|
+
title: 'Form/BaseTimePicker',
|
|
9
|
+
component: BaseTimePicker,
|
|
10
|
+
argTypes: {
|
|
11
|
+
size: {
|
|
12
|
+
control: { type: 'select' },
|
|
13
|
+
options: sizes,
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
const Template = (args) => ({
|
|
19
|
+
components: { BaseTimePicker, ShowValue },
|
|
20
|
+
setup() {
|
|
21
|
+
const value = ref(null);
|
|
22
|
+
return { value, args };
|
|
23
|
+
},
|
|
24
|
+
template: `
|
|
25
|
+
<BaseTimePicker v-model="value" v-bind="args">
|
|
26
|
+
</BaseTimePicker>
|
|
27
|
+
<ShowValue :value="value" />
|
|
28
|
+
`,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const Demo = Template.bind({});
|
|
32
|
+
|
|
33
|
+
export const Disabled = Template.bind({});
|
|
34
|
+
Disabled.args = {
|
|
35
|
+
disabled: true,
|
|
36
|
+
};
|
|
37
|
+
|
|
38
|
+
export const DisabledSeconds = Template.bind({});
|
|
39
|
+
DisabledSeconds.args = {
|
|
40
|
+
disabledSeconds: true,
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
export const WithSteps = Template.bind({});
|
|
44
|
+
WithSteps.args = {
|
|
45
|
+
hourStep: 3,
|
|
46
|
+
minuteStep: 15,
|
|
47
|
+
secondStep: 10,
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
const TemplateSizes = (args) => ({
|
|
51
|
+
components: { BaseTimePicker },
|
|
52
|
+
setup() {
|
|
53
|
+
const value = ref(null);
|
|
54
|
+
const sizes = ['xs', 'sm', 'md'];
|
|
55
|
+
return { args, value, sizes };
|
|
56
|
+
},
|
|
57
|
+
template: `
|
|
58
|
+
<div v-for="size in sizes" :key="size" class="mb-4">
|
|
59
|
+
<p class="text-xs text-slate-600 leading-tight mb-1">{{ size }}</p>
|
|
60
|
+
<BaseTimePicker v-model="value" v-bind="args" :size="size" class="w-full"></BaseTimePicker>
|
|
61
|
+
</div>
|
|
62
|
+
`,
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
export const Sizes = TemplateSizes.bind({});
|
|
66
|
+
|
|
67
|
+
export const Field = createFieldStory({
|
|
68
|
+
component: BaseTimePicker,
|
|
69
|
+
componentName: 'BaseTimePicker',
|
|
70
|
+
label: 'Time',
|
|
71
|
+
});
|