orio-ui 1.23.3 → 1.24.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 (32) hide show
  1. package/README.md +3 -3
  2. package/dist/module.json +1 -1
  3. package/dist/runtime/components/Calendar.d.vue.ts +33 -0
  4. package/dist/runtime/components/Calendar.vue +251 -0
  5. package/dist/runtime/components/Calendar.vue.d.ts +33 -0
  6. package/dist/runtime/components/Form.d.vue.ts +1 -1
  7. package/dist/runtime/components/Form.vue.d.ts +1 -1
  8. package/dist/runtime/components/date/Picker.d.vue.ts +26 -0
  9. package/dist/runtime/components/date/Picker.vue +54 -0
  10. package/dist/runtime/components/date/Picker.vue.d.ts +26 -0
  11. package/dist/runtime/components/date/PickerTrigger.d.vue.ts +23 -0
  12. package/dist/runtime/components/date/PickerTrigger.vue +80 -0
  13. package/dist/runtime/components/date/PickerTrigger.vue.d.ts +23 -0
  14. package/dist/runtime/components/date/RangePicker.d.vue.ts +28 -0
  15. package/dist/runtime/components/date/RangePicker.vue +148 -0
  16. package/dist/runtime/components/date/RangePicker.vue.d.ts +28 -0
  17. package/dist/runtime/components/view/Dates.d.vue.ts +2 -5
  18. package/dist/runtime/components/view/Dates.vue +17 -23
  19. package/dist/runtime/components/view/Dates.vue.d.ts +2 -5
  20. package/dist/runtime/i18n/en.json +8 -5
  21. package/dist/runtime/i18n/uk.json +8 -5
  22. package/dist/runtime/index.d.ts +4 -2
  23. package/dist/runtime/index.js +6 -2
  24. package/dist/runtime/utils/date.d.ts +10 -0
  25. package/dist/runtime/utils/date.js +38 -0
  26. package/package.json +1 -1
  27. package/dist/runtime/components/DatePicker.d.vue.ts +0 -15
  28. package/dist/runtime/components/DatePicker.vue +0 -24
  29. package/dist/runtime/components/DatePicker.vue.d.ts +0 -15
  30. package/dist/runtime/components/DateRangePicker.d.vue.ts +0 -18
  31. package/dist/runtime/components/DateRangePicker.vue +0 -67
  32. package/dist/runtime/components/DateRangePicker.vue.d.ts +0 -18
package/README.md CHANGED
@@ -8,7 +8,7 @@ A delightful, lightweight component library for Nuxt 3+ applications. Built with
8
8
 
9
9
  ## Features
10
10
 
11
- ✨ **56 Components** - Beautiful, accessible components ready to use
11
+ ✨ **58 Components** - Beautiful, accessible components ready to use
12
12
  🎨 **Themeable** - 5 built-in accent themes with light/dark mode support
13
13
  🚀 **Auto-imported** - Works seamlessly with Nuxt's auto-import system
14
14
  📦 **Tree-shakeable** - Only bundle what you use
@@ -67,7 +67,7 @@ function handleClick() {
67
67
 
68
68
  ## What's Included
69
69
 
70
- ### Components (56)
70
+ ### Components (58)
71
71
 
72
72
  #### Form Controls
73
73
 
@@ -194,7 +194,7 @@ npm run docs:dev
194
194
  orio-ui/
195
195
  ├── src/
196
196
  │ ├── runtime/
197
- │ │ ├── components/ # 56 Vue components
197
+ │ │ ├── components/ # 58 Vue components
198
198
  │ │ ├── composables/ # 13 composables
199
199
  │ │ ├── assets/css/ # Theme CSS files
200
200
  │ │ └── utils/ # Icon registry
package/dist/module.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "compatibility": {
5
5
  "nuxt": "^3.0.0 || ^4.0.0"
6
6
  },
7
- "version": "1.23.3",
7
+ "version": "1.24.0",
8
8
  "builder": {
9
9
  "@nuxt/module-builder": "1.0.2",
10
10
  "unbuild": "3.6.1"
@@ -0,0 +1,33 @@
1
+ export type MarkerVariant = "accent" | "success" | "alert" | "danger" | "muted";
2
+ export interface CalendarMarker {
3
+ variant: MarkerVariant;
4
+ start: string;
5
+ end: string;
6
+ }
7
+ export interface CalendarProps {
8
+ selected?: string | null;
9
+ markers?: CalendarMarker[];
10
+ getMarker?: (iso: string) => CalendarMarker | null;
11
+ isDisabled?: (iso: string) => boolean;
12
+ weekStartsOn?: 0 | 1;
13
+ }
14
+ type __VLS_Props = CalendarProps;
15
+ type __VLS_ModelProps = {
16
+ "anchor"?: string | null;
17
+ };
18
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ select: (iso: string) => any;
21
+ dayEnter: (iso: string) => any;
22
+ "update:anchor": (value: string | null) => any;
23
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
24
+ onSelect?: ((iso: string) => any) | undefined;
25
+ onDayEnter?: ((iso: string) => any) | undefined;
26
+ "onUpdate:anchor"?: ((value: string | null) => any) | undefined;
27
+ }>, {
28
+ selected: string | null;
29
+ markers: CalendarMarker[];
30
+ weekStartsOn: 0 | 1;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
@@ -0,0 +1,251 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { useI18n } from "vue-i18n";
4
+ import {
5
+ addMonths,
6
+ formatISO,
7
+ isSameDay,
8
+ parseISO,
9
+ startOfMonth
10
+ } from "../utils/date";
11
+ const props = defineProps({
12
+ selected: { type: [String, null], required: false, default: null },
13
+ markers: { type: Array, required: false, default: () => [] },
14
+ getMarker: { type: Function, required: false },
15
+ isDisabled: { type: Function, required: false },
16
+ weekStartsOn: { type: Number, required: false, default: 1 }
17
+ });
18
+ const anchor = defineModel("anchor", { type: [String, null], ...{ default: null } });
19
+ const emit = defineEmits(["select", "dayEnter"]);
20
+ const { locale, t } = useI18n();
21
+ const today = /* @__PURE__ */ new Date();
22
+ const visibleMonth = computed(
23
+ () => startOfMonth(parseISO(anchor.value) ?? /* @__PURE__ */ new Date())
24
+ );
25
+ function shift(delta) {
26
+ anchor.value = formatISO(addMonths(visibleMonth.value, delta));
27
+ }
28
+ const monthLabel = computed(
29
+ () => new Intl.DateTimeFormat(locale.value, {
30
+ month: "long",
31
+ year: "numeric"
32
+ }).format(visibleMonth.value)
33
+ );
34
+ const weekdayLabels = computed(() => {
35
+ const sunday = new Date(2024, 0, 7);
36
+ return Array.from({ length: 7 }, (_, i) => {
37
+ const d = new Date(sunday);
38
+ d.setDate(sunday.getDate() + (i + props.weekStartsOn) % 7);
39
+ return new Intl.DateTimeFormat(locale.value, { weekday: "short" }).format(
40
+ d
41
+ );
42
+ });
43
+ });
44
+ function resolveMarker(iso) {
45
+ if (props.getMarker) {
46
+ const m = props.getMarker(iso);
47
+ if (m) {
48
+ return {
49
+ variant: m.variant,
50
+ isStart: iso === m.start,
51
+ isEnd: iso === m.end
52
+ };
53
+ }
54
+ }
55
+ for (let i = props.markers.length - 1; i >= 0; i--) {
56
+ const m = props.markers[i];
57
+ if (iso >= m.start && iso <= m.end) {
58
+ return {
59
+ variant: m.variant,
60
+ isStart: iso === m.start,
61
+ isEnd: iso === m.end
62
+ };
63
+ }
64
+ }
65
+ return null;
66
+ }
67
+ const days = computed(() => {
68
+ const first = visibleMonth.value;
69
+ const startWeekday = first.getDay();
70
+ const offset = (startWeekday - props.weekStartsOn + 7) % 7;
71
+ const gridStart = new Date(first);
72
+ gridStart.setDate(gridStart.getDate() - offset);
73
+ const sel = parseISO(props.selected);
74
+ const result = [];
75
+ for (let i = 0; i < 42; i++) {
76
+ const d = new Date(gridStart);
77
+ d.setDate(gridStart.getDate() + i);
78
+ const iso = formatISO(d);
79
+ result.push({
80
+ iso,
81
+ label: d.getDate(),
82
+ inMonth: d.getMonth() === first.getMonth(),
83
+ isToday: isSameDay(d, today),
84
+ isSelected: !!sel && isSameDay(d, sel),
85
+ isDisabled: props.isDisabled?.(iso) ?? false,
86
+ marker: resolveMarker(iso)
87
+ });
88
+ }
89
+ return result;
90
+ });
91
+ function onSelect(day) {
92
+ if (day.isDisabled) return;
93
+ emit("select", day.iso);
94
+ }
95
+ function onEnter(day) {
96
+ emit("dayEnter", day.iso);
97
+ }
98
+ </script>
99
+
100
+ <template>
101
+ <div class="calendar">
102
+ <div class="calendar-nav">
103
+ <orio-button
104
+ variant="subdued"
105
+ icon="chevron-left"
106
+ :aria-label="t('calendar.previousMonth')"
107
+ @click="shift(-1)"
108
+ />
109
+ <span class="calendar-month-title">{{ monthLabel }}</span>
110
+ <orio-button
111
+ variant="subdued"
112
+ icon="chevron-right"
113
+ :aria-label="t('calendar.nextMonth')"
114
+ @click="shift(1)"
115
+ />
116
+ </div>
117
+ <div class="calendar-weekdays">
118
+ <span v-for="w in weekdayLabels" :key="w" class="calendar-weekday">
119
+ {{ w }}
120
+ </span>
121
+ </div>
122
+ <div class="calendar-grid">
123
+ <button
124
+ v-for="day in days"
125
+ :key="day.iso"
126
+ type="button"
127
+ class="calendar-day"
128
+ :class="{
129
+ 'out-of-month': !day.inMonth,
130
+ today: day.isToday,
131
+ selected: day.isSelected,
132
+ 'has-marker': !!day.marker,
133
+ [`marker-${day.marker?.variant}`]: !!day.marker,
134
+ 'marker-start': day.marker?.isStart,
135
+ 'marker-end': day.marker?.isEnd
136
+ }"
137
+ :disabled="day.isDisabled"
138
+ @click="onSelect(day)"
139
+ @mouseenter="onEnter(day)"
140
+ >
141
+ <orio-badge v-if="day.isSelected" pill variant="primary">
142
+ {{ day.label }}
143
+ </orio-badge>
144
+ <template v-else>{{ day.label }}</template>
145
+ </button>
146
+ </div>
147
+ </div>
148
+ </template>
149
+
150
+ <style scoped>
151
+ .calendar {
152
+ display: inline-block;
153
+ background: var(--color-bg);
154
+ border: 1px solid var(--color-border);
155
+ border-radius: var(--border-radius-md);
156
+ padding: 0.75rem;
157
+ user-select: none;
158
+ font-size: var(--control-font-size, var(--font-md));
159
+ color: var(--color-text);
160
+ min-width: 17rem;
161
+ }
162
+
163
+ .calendar-nav {
164
+ display: flex;
165
+ align-items: center;
166
+ justify-content: space-between;
167
+ gap: 0.5rem;
168
+ margin-bottom: 0.5rem;
169
+ }
170
+
171
+ .calendar-month-title {
172
+ font-weight: 600;
173
+ text-transform: capitalize;
174
+ }
175
+
176
+ .calendar-weekdays,
177
+ .calendar-grid {
178
+ display: grid;
179
+ grid-template-columns: repeat(7, 1fr);
180
+ }
181
+
182
+ .calendar-weekday {
183
+ text-align: center;
184
+ font-size: var(--font-xs);
185
+ color: var(--color-muted);
186
+ padding: 0.25rem 0;
187
+ text-transform: uppercase;
188
+ }
189
+
190
+ .calendar-day {
191
+ aspect-ratio: 1;
192
+ display: flex;
193
+ align-items: center;
194
+ justify-content: center;
195
+ background: transparent;
196
+ border: 0;
197
+ color: inherit;
198
+ cursor: pointer;
199
+ border-radius: var(--border-radius-sm);
200
+ font-size: inherit;
201
+ transition: background-color 0.15s ease, color 0.15s ease;
202
+ }
203
+ .calendar-day:hover:not(:disabled):not(.has-marker):not(.selected) {
204
+ background-color: var(--color-surface);
205
+ }
206
+ .calendar-day.out-of-month {
207
+ color: var(--color-muted);
208
+ opacity: 0.45;
209
+ }
210
+ .calendar-day.today {
211
+ box-shadow: inset 0 0 0 1px var(--color-accent);
212
+ }
213
+ .calendar-day.has-marker {
214
+ background-color: var(--marker-bg);
215
+ color: var(--marker-color);
216
+ border-radius: 0;
217
+ }
218
+ .calendar-day.has-marker.marker-start {
219
+ border-top-left-radius: var(--border-radius-sm);
220
+ border-bottom-left-radius: var(--border-radius-sm);
221
+ }
222
+ .calendar-day.has-marker.marker-end {
223
+ border-top-right-radius: var(--border-radius-sm);
224
+ border-bottom-right-radius: var(--border-radius-sm);
225
+ }
226
+ .calendar-day.marker-accent {
227
+ --marker-bg: var(--color-accent-soft);
228
+ --marker-color: var(--color-accent);
229
+ }
230
+ .calendar-day.marker-success {
231
+ --marker-bg: var(--color-success-soft);
232
+ --marker-color: var(--color-success);
233
+ }
234
+ .calendar-day.marker-alert {
235
+ --marker-bg: var(--color-alert-soft);
236
+ --marker-color: var(--color-alert);
237
+ }
238
+ .calendar-day.marker-danger {
239
+ --marker-bg: var(--color-danger-soft);
240
+ --marker-color: var(--color-danger);
241
+ }
242
+ .calendar-day.marker-muted {
243
+ --marker-bg: var(--color-surface);
244
+ --marker-color: var(--color-muted);
245
+ }
246
+ .calendar-day:disabled {
247
+ color: var(--color-muted);
248
+ cursor: not-allowed;
249
+ opacity: 0.4;
250
+ }
251
+ </style>
@@ -0,0 +1,33 @@
1
+ export type MarkerVariant = "accent" | "success" | "alert" | "danger" | "muted";
2
+ export interface CalendarMarker {
3
+ variant: MarkerVariant;
4
+ start: string;
5
+ end: string;
6
+ }
7
+ export interface CalendarProps {
8
+ selected?: string | null;
9
+ markers?: CalendarMarker[];
10
+ getMarker?: (iso: string) => CalendarMarker | null;
11
+ isDisabled?: (iso: string) => boolean;
12
+ weekStartsOn?: 0 | 1;
13
+ }
14
+ type __VLS_Props = CalendarProps;
15
+ type __VLS_ModelProps = {
16
+ "anchor"?: string | null;
17
+ };
18
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
19
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
20
+ select: (iso: string) => any;
21
+ dayEnter: (iso: string) => any;
22
+ "update:anchor": (value: string | null) => any;
23
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
24
+ onSelect?: ((iso: string) => any) | undefined;
25
+ onDayEnter?: ((iso: string) => any) | undefined;
26
+ "onUpdate:anchor"?: ((value: string | null) => any) | undefined;
27
+ }>, {
28
+ selected: string | null;
29
+ markers: CalendarMarker[];
30
+ weekStartsOn: 0 | 1;
31
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
32
+ declare const _default: typeof __VLS_export;
33
+ export default _default;
@@ -12,8 +12,8 @@ declare const __VLS_export: <T extends object>(__VLS_props: NonNullable<Awaited<
12
12
  props: import("vue").PublicProps & __VLS_PrettifyLocal<(FormProps & {
13
13
  modelValue?: T;
14
14
  }) & {
15
- "onUpdate:modelValue"?: ((value: T | undefined) => any) | undefined;
16
15
  onSubmit?: (() => any) | undefined;
16
+ "onUpdate:modelValue"?: ((value: T | undefined) => any) | undefined;
17
17
  }> & (typeof globalThis extends {
18
18
  __VLS_PROPS_FALLBACK: infer P;
19
19
  } ? P : {});
@@ -12,8 +12,8 @@ declare const __VLS_export: <T extends object>(__VLS_props: NonNullable<Awaited<
12
12
  props: import("vue").PublicProps & __VLS_PrettifyLocal<(FormProps & {
13
13
  modelValue?: T;
14
14
  }) & {
15
- "onUpdate:modelValue"?: ((value: T | undefined) => any) | undefined;
16
15
  onSubmit?: (() => any) | undefined;
16
+ "onUpdate:modelValue"?: ((value: T | undefined) => any) | undefined;
17
17
  }> & (typeof globalThis extends {
18
18
  __VLS_PROPS_FALLBACK: infer P;
19
19
  } ? P : {});
@@ -0,0 +1,26 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ import type { CalendarMarker } from "../Calendar.vue.js";
3
+ interface Props extends ControlProps {
4
+ placeholder?: string;
5
+ min?: string | null;
6
+ max?: string | null;
7
+ markers?: CalendarMarker[];
8
+ getMarker?: (iso: string) => CalendarMarker | null;
9
+ isDisabled?: (iso: string) => boolean;
10
+ }
11
+ type __VLS_Props = Props;
12
+ type __VLS_ModelProps = {
13
+ modelValue?: string | null;
14
+ };
15
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ "update:modelValue": (value: string | null) => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
19
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
20
+ }>, {
21
+ markers: CalendarMarker[];
22
+ min: string | null;
23
+ max: string | null;
24
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
+ declare const _default: typeof __VLS_export;
26
+ export default _default;
@@ -0,0 +1,54 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ import { useI18n } from "vue-i18n";
4
+ import { formatDate } from "../../utils/date";
5
+ const props = defineProps({
6
+ placeholder: { type: String, required: false },
7
+ min: { type: [String, null], required: false, default: null },
8
+ max: { type: [String, null], required: false, default: null },
9
+ markers: { type: Array, required: false, default: () => [] },
10
+ getMarker: { type: Function, required: false },
11
+ isDisabled: { type: Function, required: false },
12
+ appearance: { type: String, required: false },
13
+ error: { type: [String, null], required: false },
14
+ group: { type: Boolean, required: false },
15
+ id: { type: String, required: false },
16
+ label: { type: String, required: false },
17
+ layout: { type: String, required: false },
18
+ size: { type: String, required: false },
19
+ fill: { type: Boolean, required: false }
20
+ });
21
+ const value = defineModel({ type: [String, null], ...{ default: null } });
22
+ const { locale, t } = useI18n();
23
+ const display = computed(() => formatDate(value.value, locale.value));
24
+ const placeholderText = computed(
25
+ () => props.placeholder ?? t("datePicker.placeholder")
26
+ );
27
+ const calendarIsDisabled = computed(() => (iso) => {
28
+ if (props.min && iso < props.min) return true;
29
+ if (props.max && iso > props.max) return true;
30
+ return props.isDisabled?.(iso) ?? false;
31
+ });
32
+ function pick(iso, toggle) {
33
+ value.value = iso;
34
+ toggle(false);
35
+ }
36
+ </script>
37
+
38
+ <template>
39
+ <orio-date-picker-trigger
40
+ v-bind="props"
41
+ :text="display"
42
+ :placeholder="placeholderText"
43
+ >
44
+ <template #default="{ toggle }">
45
+ <orio-calendar
46
+ :selected="value"
47
+ :markers
48
+ :get-marker="getMarker"
49
+ :is-disabled="calendarIsDisabled"
50
+ @select="pick($event, toggle)"
51
+ />
52
+ </template>
53
+ </orio-date-picker-trigger>
54
+ </template>
@@ -0,0 +1,26 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ import type { CalendarMarker } from "../Calendar.vue.js";
3
+ interface Props extends ControlProps {
4
+ placeholder?: string;
5
+ min?: string | null;
6
+ max?: string | null;
7
+ markers?: CalendarMarker[];
8
+ getMarker?: (iso: string) => CalendarMarker | null;
9
+ isDisabled?: (iso: string) => boolean;
10
+ }
11
+ type __VLS_Props = Props;
12
+ type __VLS_ModelProps = {
13
+ modelValue?: string | null;
14
+ };
15
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
16
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
17
+ "update:modelValue": (value: string | null) => any;
18
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
19
+ "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
20
+ }>, {
21
+ markers: CalendarMarker[];
22
+ min: string | null;
23
+ max: string | null;
24
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
25
+ declare const _default: typeof __VLS_export;
26
+ export default _default;
@@ -0,0 +1,23 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ interface Props extends ControlProps {
3
+ text?: string;
4
+ placeholder?: string;
5
+ }
6
+ declare var __VLS_21: {
7
+ toggle: any;
8
+ };
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_21) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
13
+ text: string;
14
+ placeholder: string;
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,80 @@
1
+ <script setup>
2
+ import { computed } from "vue";
3
+ const props = defineProps({
4
+ text: { type: String, required: false, default: "" },
5
+ placeholder: { type: String, required: false, default: "" },
6
+ appearance: { type: String, required: false },
7
+ error: { type: [String, null], required: false },
8
+ group: { type: Boolean, required: false },
9
+ id: { type: String, required: false },
10
+ label: { type: String, required: false },
11
+ layout: { type: String, required: false },
12
+ size: { type: String, required: false },
13
+ fill: { type: Boolean, required: false }
14
+ });
15
+ const controlProps = computed(() => {
16
+ const { text, placeholder, ...rest } = props;
17
+ return rest;
18
+ });
19
+ </script>
20
+
21
+ <template>
22
+ <orio-control-element v-slot="{ id }" v-bind="controlProps">
23
+ <orio-popover position="bottom-right" :offset="5">
24
+ <template #default="{ toggle, isOpen }">
25
+ <button
26
+ :id
27
+ type="button"
28
+ class="date-trigger"
29
+ :aria-expanded="isOpen"
30
+ @click="toggle()"
31
+ >
32
+ <span :class="{ placeholder: !text }">
33
+ {{ text || placeholder }}
34
+ </span>
35
+ <orio-icon name="calendar" />
36
+ </button>
37
+ </template>
38
+ <template #content="{ toggle }">
39
+ <slot :toggle />
40
+ </template>
41
+ </orio-popover>
42
+ </orio-control-element>
43
+ </template>
44
+
45
+ <style scoped>
46
+ .date-trigger {
47
+ width: 100%;
48
+ display: flex;
49
+ align-items: center;
50
+ justify-content: space-between;
51
+ gap: var(--control-gap);
52
+ background: var(--color-bg);
53
+ border: 1px solid var(--color-border);
54
+ border-radius: var(--control-radius);
55
+ padding: var(--control-py) var(--control-px);
56
+ color: var(--color-text);
57
+ cursor: pointer;
58
+ user-select: none;
59
+ transition: border-color 0.2s ease, background-color 0.2s ease, box-shadow 0.2s ease;
60
+ }
61
+ .date-trigger:hover {
62
+ border-color: var(--color-accent);
63
+ background-color: var(--color-surface);
64
+ }
65
+ .date-trigger[aria-expanded=true], .date-trigger:focus-visible {
66
+ border-color: var(--color-accent);
67
+ box-shadow: 0 0 0 2px var(--color-surface);
68
+ outline: none;
69
+ }
70
+ .date-trigger .placeholder {
71
+ color: var(--color-muted);
72
+ }
73
+ .date-trigger .icon {
74
+ color: var(--color-muted);
75
+ transition: color 0.2s ease;
76
+ }
77
+ .date-trigger:hover .icon {
78
+ color: var(--color-accent);
79
+ }
80
+ </style>
@@ -0,0 +1,23 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ interface Props extends ControlProps {
3
+ text?: string;
4
+ placeholder?: string;
5
+ }
6
+ declare var __VLS_21: {
7
+ toggle: any;
8
+ };
9
+ type __VLS_Slots = {} & {
10
+ default?: (props: typeof __VLS_21) => any;
11
+ };
12
+ declare const __VLS_base: import("vue").DefineComponent<Props, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<Props> & Readonly<{}>, {
13
+ text: string;
14
+ placeholder: string;
15
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
16
+ declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
17
+ declare const _default: typeof __VLS_export;
18
+ export default _default;
19
+ type __VLS_WithSlots<T, S> = T & {
20
+ new (): {
21
+ $slots: S;
22
+ };
23
+ };
@@ -0,0 +1,28 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ import type { CalendarMarker } from "../Calendar.vue.js";
3
+ import { type DateRange } from "../../utils/date.js";
4
+ export type { DateRange };
5
+ interface Props extends ControlProps {
6
+ placeholder?: string;
7
+ min?: string | null;
8
+ max?: string | null;
9
+ markers?: CalendarMarker[];
10
+ getMarker?: (iso: string) => CalendarMarker | null;
11
+ isDisabled?: (iso: string) => boolean;
12
+ }
13
+ type __VLS_Props = Props;
14
+ type __VLS_ModelProps = {
15
+ modelValue?: DateRange;
16
+ };
17
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
18
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (value: DateRange) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
21
+ "onUpdate:modelValue"?: ((value: DateRange) => any) | undefined;
22
+ }>, {
23
+ markers: CalendarMarker[];
24
+ min: string | null;
25
+ max: string | null;
26
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
+ declare const _default: typeof __VLS_export;
28
+ export default _default;
@@ -0,0 +1,148 @@
1
+ <script setup>
2
+ import { computed, ref, watch } from "vue";
3
+ import { useI18n } from "vue-i18n";
4
+ import {
5
+ addMonths,
6
+ formatDate,
7
+ formatISO,
8
+ parseISO,
9
+ startOfMonth
10
+ } from "../../utils/date";
11
+ const props = defineProps({
12
+ placeholder: { type: String, required: false },
13
+ min: { type: [String, null], required: false, default: null },
14
+ max: { type: [String, null], required: false, default: null },
15
+ markers: { type: Array, required: false, default: () => [] },
16
+ getMarker: { type: Function, required: false },
17
+ isDisabled: { type: Function, required: false },
18
+ appearance: { type: String, required: false },
19
+ error: { type: [String, null], required: false },
20
+ group: { type: Boolean, required: false },
21
+ id: { type: String, required: false },
22
+ label: { type: String, required: false },
23
+ layout: { type: String, required: false },
24
+ size: { type: String, required: false },
25
+ fill: { type: Boolean, required: false }
26
+ });
27
+ const range = defineModel({ type: Object, ...{
28
+ default: () => ({ start: null, end: null })
29
+ } });
30
+ const { locale, t } = useI18n();
31
+ const display = computed(() => {
32
+ const start = formatDate(range.value?.start, locale.value);
33
+ const end = formatDate(range.value?.end, locale.value);
34
+ if (start && end) return `${start} \u2013 ${end}`;
35
+ return start || end || "";
36
+ });
37
+ const placeholderText = computed(
38
+ () => props.placeholder ?? t("dateRangePicker.placeholder")
39
+ );
40
+ const seedMonth = startOfMonth(parseISO(range.value?.start) ?? /* @__PURE__ */ new Date());
41
+ const leftAnchor = ref(formatISO(seedMonth));
42
+ const rightAnchor = ref(formatISO(addMonths(seedMonth, 1)));
43
+ watch(
44
+ () => range.value?.start,
45
+ (start) => {
46
+ const date = parseISO(start);
47
+ if (!date) return;
48
+ const monthIso = formatISO(startOfMonth(date));
49
+ if (leftAnchor.value === monthIso || rightAnchor.value === monthIso) return;
50
+ leftAnchor.value = monthIso;
51
+ rightAnchor.value = formatISO(addMonths(startOfMonth(date), 1));
52
+ }
53
+ );
54
+ const hovering = ref(null);
55
+ const previewEnd = computed(() => {
56
+ if (range.value?.end) return range.value.end;
57
+ if (!hovering.value || !range.value?.start) return null;
58
+ const start = parseISO(range.value.start);
59
+ const hover = parseISO(hovering.value);
60
+ if (!start || !hover) return null;
61
+ return hover > start ? hovering.value : null;
62
+ });
63
+ const previewStart = computed(() => {
64
+ if (range.value?.start && range.value?.end) return range.value.start;
65
+ if (!hovering.value || !range.value?.start) return range.value?.start ?? null;
66
+ const start = parseISO(range.value.start);
67
+ const hover = parseISO(hovering.value);
68
+ if (!start || !hover) return range.value.start;
69
+ return hover < start ? hovering.value : range.value.start;
70
+ });
71
+ const previewMarker = computed(() => {
72
+ if (!previewStart.value || !previewEnd.value) return null;
73
+ return {
74
+ variant: "accent",
75
+ start: previewStart.value,
76
+ end: previewEnd.value
77
+ };
78
+ });
79
+ const calendarGetMarker = computed(() => (iso) => {
80
+ const preview = previewMarker.value;
81
+ if (preview && iso >= preview.start && iso <= preview.end) return preview;
82
+ return props.getMarker?.(iso) ?? null;
83
+ });
84
+ const calendarIsDisabled = computed(() => (iso) => {
85
+ if (props.min && iso < props.min) return true;
86
+ if (props.max && iso > props.max) return true;
87
+ return props.isDisabled?.(iso) ?? false;
88
+ });
89
+ function pick(iso, toggle) {
90
+ const current = range.value ?? { start: null, end: null };
91
+ if (!current.start || current.start && current.end) {
92
+ range.value = { start: iso, end: null };
93
+ return;
94
+ }
95
+ const startDate = parseISO(current.start);
96
+ const picked = parseISO(iso);
97
+ if (!startDate || !picked) return;
98
+ if (picked < startDate) {
99
+ range.value = { start: iso, end: current.start };
100
+ } else {
101
+ range.value = { start: current.start, end: iso };
102
+ }
103
+ hovering.value = null;
104
+ toggle(false);
105
+ }
106
+ function onHover(iso) {
107
+ hovering.value = iso;
108
+ }
109
+ function clearHover() {
110
+ hovering.value = null;
111
+ }
112
+ </script>
113
+
114
+ <template>
115
+ <orio-date-picker-trigger
116
+ v-bind="props"
117
+ :text="display"
118
+ :placeholder="placeholderText"
119
+ >
120
+ <template #default="{ toggle }">
121
+ <div class="range-content" @mouseleave="clearHover">
122
+ <orio-calendar
123
+ v-model:anchor="leftAnchor"
124
+ :markers
125
+ :get-marker="calendarGetMarker"
126
+ :is-disabled="calendarIsDisabled"
127
+ @select="pick($event, toggle)"
128
+ @day-enter="onHover"
129
+ />
130
+ <orio-calendar
131
+ v-model:anchor="rightAnchor"
132
+ :markers
133
+ :get-marker="calendarGetMarker"
134
+ :is-disabled="calendarIsDisabled"
135
+ @select="pick($event, toggle)"
136
+ @day-enter="onHover"
137
+ />
138
+ </div>
139
+ </template>
140
+ </orio-date-picker-trigger>
141
+ </template>
142
+
143
+ <style scoped>
144
+ .range-content {
145
+ display: flex;
146
+ gap: 0.75rem;
147
+ }
148
+ </style>
@@ -0,0 +1,28 @@
1
+ import type { ControlProps } from "../ControlElement.vue.js";
2
+ import type { CalendarMarker } from "../Calendar.vue.js";
3
+ import { type DateRange } from "../../utils/date.js";
4
+ export type { DateRange };
5
+ interface Props extends ControlProps {
6
+ placeholder?: string;
7
+ min?: string | null;
8
+ max?: string | null;
9
+ markers?: CalendarMarker[];
10
+ getMarker?: (iso: string) => CalendarMarker | null;
11
+ isDisabled?: (iso: string) => boolean;
12
+ }
13
+ type __VLS_Props = Props;
14
+ type __VLS_ModelProps = {
15
+ modelValue?: DateRange;
16
+ };
17
+ type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
18
+ declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
19
+ "update:modelValue": (value: DateRange) => any;
20
+ }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
21
+ "onUpdate:modelValue"?: ((value: DateRange) => any) | undefined;
22
+ }>, {
23
+ markers: CalendarMarker[];
24
+ min: string | null;
25
+ max: string | null;
26
+ }, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
27
+ declare const _default: typeof __VLS_export;
28
+ export default _default;
@@ -1,9 +1,6 @@
1
- export interface ResumeDate {
2
- startDate: string;
3
- endDate?: string | null;
4
- }
1
+ import { type DateRange } from "../../utils/date.js";
5
2
  interface Props {
6
- dates: ResumeDate;
3
+ dates: DateRange;
7
4
  month?: boolean;
8
5
  size?: "small" | "medium" | "large";
9
6
  type?: "text" | "title" | "subtitle" | "italics";
@@ -1,6 +1,7 @@
1
1
  <script setup>
2
2
  import { computed, toRefs } from "vue";
3
3
  import { useI18n } from "vue-i18n";
4
+ import { formatDate } from "../../utils/date";
4
5
  const props = defineProps({
5
6
  dates: { type: Object, required: true },
6
7
  month: { type: Boolean, required: false },
@@ -8,33 +9,26 @@ const props = defineProps({
8
9
  type: { type: String, required: false, default: "italics" }
9
10
  });
10
11
  const { dates } = toRefs(props);
11
- const { t, locale } = useI18n();
12
- function formatMonthYear(value) {
13
- if (!value) return "";
14
- if (!props.month)
15
- return new Intl.DateTimeFormat(locale.value, {
16
- day: "numeric",
17
- month: "short",
18
- year: "numeric"
19
- }).format(new Date(value));
20
- return new Intl.DateTimeFormat(locale.value, {
21
- month: "short",
22
- year: "numeric"
23
- }).format(new Date(value));
24
- }
25
- const startDate = computed(() => formatMonthYear(dates.value.startDate));
26
- const endDate = computed(() => {
27
- if (dates.value.endDate === void 0) return null;
28
- return dates.value.endDate !== null ? formatMonthYear(dates.value.endDate) : t("dates.present");
29
- });
12
+ const { locale } = useI18n();
13
+ const formatOptions = computed(() => ({
14
+ day: props.month ? void 0 : "numeric",
15
+ month: "short",
16
+ year: "numeric"
17
+ }));
18
+ const startText = computed(
19
+ () => formatDate(dates.value?.start, locale.value, formatOptions.value)
20
+ );
21
+ const endText = computed(
22
+ () => formatDate(dates.value?.end, locale.value, formatOptions.value)
23
+ );
30
24
  </script>
31
25
 
32
26
  <template>
33
27
  <div class="view-date">
34
- <orio-view-text :model-value="startDate" :type :size />
35
- <template v-if="endDate">
36
- <span v-if="startDate"> - </span>
37
- <orio-view-text :model-value="endDate" :type :size />
28
+ <orio-view-text :model-value="startText" :type :size />
29
+ <template v-if="endText">
30
+ <span v-if="startText"> - </span>
31
+ <orio-view-text :model-value="endText" :type :size />
38
32
  </template>
39
33
  </div>
40
34
  </template>
@@ -1,9 +1,6 @@
1
- export interface ResumeDate {
2
- startDate: string;
3
- endDate?: string | null;
4
- }
1
+ import { type DateRange } from "../../utils/date.js";
5
2
  interface Props {
6
- dates: ResumeDate;
3
+ dates: DateRange;
7
4
  month?: boolean;
8
5
  size?: "small" | "medium" | "large";
9
6
  type?: "text" | "title" | "subtitle" | "italics";
@@ -4,12 +4,15 @@
4
4
  "selected": "{count} selected",
5
5
  "noOptions": "No options found"
6
6
  },
7
- "dateRangePicker": {
8
- "startBeforeEnd": "Start date must be before end date.",
9
- "present": "Present"
7
+ "calendar": {
8
+ "previousMonth": "Previous month",
9
+ "nextMonth": "Next month"
10
+ },
11
+ "datePicker": {
12
+ "placeholder": "Select a date"
10
13
  },
11
- "dates": {
12
- "present": "Present"
14
+ "dateRangePicker": {
15
+ "placeholder": "Select a date range"
13
16
  },
14
17
  "validation": {
15
18
  "fieldError": "Error on this field"
@@ -4,12 +4,15 @@
4
4
  "selected": "{count} обрано",
5
5
  "noOptions": "Опцій не знайдено"
6
6
  },
7
- "dateRangePicker": {
8
- "startBeforeEnd": "Дата початку має бути раніше дати завершення.",
9
- "present": "Теперішній час"
7
+ "calendar": {
8
+ "previousMonth": "Попередній місяць",
9
+ "nextMonth": "Наступний місяць"
10
+ },
11
+ "datePicker": {
12
+ "placeholder": "Оберіть дату"
10
13
  },
11
- "dates": {
12
- "present": "Теперішній час"
14
+ "dateRangePicker": {
15
+ "placeholder": "Оберіть діапазон дат"
13
16
  },
14
17
  "validation": {
15
18
  "fieldError": "Помилка в цьому полі"
@@ -11,8 +11,10 @@ export { default as CheckBox } from "./components/CheckBox.vue.js";
11
11
  export { default as CheckboxGroup, type CheckboxOption, type CheckboxGroupProps, } from "./components/CheckboxGroup.vue.js";
12
12
  export { default as RadioButton, type RadioButtonProps, } from "./components/RadioButton.vue.js";
13
13
  export { default as SwitchButton } from "./components/SwitchButton.vue.js";
14
- export { default as DatePicker } from "./components/DatePicker.vue.js";
15
- export { default as DateRangePicker } from "./components/DateRangePicker.vue.js";
14
+ export { default as Calendar, type CalendarProps, } from "./components/Calendar.vue.js";
15
+ export { default as DatePicker } from "./components/date/Picker.vue.js";
16
+ export { default as DateRangePicker } from "./components/date/RangePicker.vue.js";
17
+ export { type DateRange, parseISO, formatISO, formatDate } from "./utils/date.js";
16
18
  export { default as Selector } from "./components/Selector.vue.js";
17
19
  export { default as TaggableSelector } from "./components/TaggableSelector.vue.js";
18
20
  export { default as Tag } from "./components/Tag.vue.js";
@@ -15,8 +15,12 @@ export {
15
15
  default as RadioButton
16
16
  } from "./components/RadioButton.vue";
17
17
  export { default as SwitchButton } from "./components/SwitchButton.vue";
18
- export { default as DatePicker } from "./components/DatePicker.vue";
19
- export { default as DateRangePicker } from "./components/DateRangePicker.vue";
18
+ export {
19
+ default as Calendar
20
+ } from "./components/Calendar.vue";
21
+ export { default as DatePicker } from "./components/date/Picker.vue";
22
+ export { default as DateRangePicker } from "./components/date/RangePicker.vue";
23
+ export { parseISO, formatISO, formatDate } from "./utils/date.js";
20
24
  export { default as Selector } from "./components/Selector.vue";
21
25
  export { default as TaggableSelector } from "./components/TaggableSelector.vue";
22
26
  export { default as Tag } from "./components/Tag.vue";
@@ -0,0 +1,10 @@
1
+ export interface DateRange {
2
+ start: string | null;
3
+ end: string | null;
4
+ }
5
+ export declare function parseISO(value: string | null | undefined): Date | null;
6
+ export declare function formatISO(date: Date): string;
7
+ export declare function isSameDay(a: Date, b: Date): boolean;
8
+ export declare function startOfMonth(date: Date): Date;
9
+ export declare function addMonths(date: Date, count: number): Date;
10
+ export declare function formatDate(value: string | null | undefined, locale: string, options?: Intl.DateTimeFormatOptions): string;
@@ -0,0 +1,38 @@
1
+ const ISO_DATE = /^(\d{4})-(\d{2})-(\d{2})$/;
2
+ export function parseISO(value) {
3
+ if (!value) return null;
4
+ const match = ISO_DATE.exec(value);
5
+ if (!match) return null;
6
+ const [, y, m, d] = match;
7
+ const date = new Date(Number(y), Number(m) - 1, Number(d));
8
+ if (Number.isNaN(date.getTime())) return null;
9
+ if (date.getFullYear() !== Number(y) || date.getMonth() !== Number(m) - 1 || date.getDate() !== Number(d)) {
10
+ return null;
11
+ }
12
+ return date;
13
+ }
14
+ export function formatISO(date) {
15
+ const y = date.getFullYear();
16
+ const m = String(date.getMonth() + 1).padStart(2, "0");
17
+ const d = String(date.getDate()).padStart(2, "0");
18
+ return `${y}-${m}-${d}`;
19
+ }
20
+ export function isSameDay(a, b) {
21
+ return a.getFullYear() === b.getFullYear() && a.getMonth() === b.getMonth() && a.getDate() === b.getDate();
22
+ }
23
+ export function startOfMonth(date) {
24
+ return new Date(date.getFullYear(), date.getMonth(), 1);
25
+ }
26
+ export function addMonths(date, count) {
27
+ return new Date(date.getFullYear(), date.getMonth() + count, 1);
28
+ }
29
+ const DEFAULT_DATE_FORMAT = {
30
+ day: "numeric",
31
+ month: "short",
32
+ year: "numeric"
33
+ };
34
+ export function formatDate(value, locale, options = DEFAULT_DATE_FORMAT) {
35
+ const date = parseISO(value);
36
+ if (!date) return "";
37
+ return new Intl.DateTimeFormat(locale, options).format(date);
38
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orio-ui",
3
- "version": "1.23.3",
3
+ "version": "1.24.0",
4
4
  "description": "Modern Nuxt component library with theme support",
5
5
  "type": "module",
6
6
  "main": "./dist/module.mjs",
@@ -1,15 +0,0 @@
1
- interface Props {
2
- month?: boolean;
3
- }
4
- type __VLS_Props = Props;
5
- type __VLS_ModelProps = {
6
- "date": string | null | undefined;
7
- };
8
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
9
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
- "update:date": (value: string | null | undefined) => any;
11
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
- "onUpdate:date"?: ((value: string | null | undefined) => any) | undefined;
13
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
- declare const _default: typeof __VLS_export;
15
- export default _default;
@@ -1,24 +0,0 @@
1
- <script setup>
2
- defineProps({
3
- month: { type: Boolean, required: false }
4
- });
5
- const date = defineModel("date", { type: null, ...{
6
- required: true
7
- } });
8
- </script>
9
-
10
- <template>
11
- <orio-control-element v-slot="{ id }" class="date-picker" v-bind="$attrs">
12
- <input
13
- :id
14
- v-model="date"
15
- :type="month ? 'month' : 'date'"
16
- class="date-input"
17
- :name="id"
18
- />
19
- </orio-control-element>
20
- </template>
21
-
22
- <style scoped>
23
- .date-picker *{cursor:pointer;width:100%}.date-input{-webkit-appearance:none;-moz-appearance:none;appearance:none;background-color:var(--color-bg);border:1px solid var(--color-border);border-radius:var(--border-radius-md);box-sizing:border-box;color:var(--color-text);padding:.4rem .6rem;transition:border-color .2s ease}.date-input:focus,.date-input:hover{border-color:var(--color-accent)}.date-input:focus{outline:none}.date-input:disabled{background-color:var(--color-surface);color:var(--color-muted);cursor:not-allowed}.date-input::-webkit-calendar-picker-indicator{cursor:pointer;filter:invert(36%) sepia(65%) saturate(325%) hue-rotate(180deg);opacity:.7;-webkit-transition:opacity .2s ease;transition:opacity .2s ease}.date-input::-webkit-calendar-picker-indicator:hover{opacity:1}
24
- </style>
@@ -1,15 +0,0 @@
1
- interface Props {
2
- month?: boolean;
3
- }
4
- type __VLS_Props = Props;
5
- type __VLS_ModelProps = {
6
- "date": string | null | undefined;
7
- };
8
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
9
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
10
- "update:date": (value: string | null | undefined) => any;
11
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
12
- "onUpdate:date"?: ((value: string | null | undefined) => any) | undefined;
13
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
14
- declare const _default: typeof __VLS_export;
15
- export default _default;
@@ -1,18 +0,0 @@
1
- import type { ResumeDate } from "./view/Dates.vue.js";
2
- export interface DateRangePickerProps {
3
- month?: boolean;
4
- }
5
- type __VLS_Props = DateRangePickerProps;
6
- type __VLS_ModelProps = {
7
- "dates": ResumeDate;
8
- };
9
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
10
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
11
- dateIsCorrect: import("vue").ComputedRef<boolean>;
12
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
- "update:dates": (value: ResumeDate) => any;
14
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
- "onUpdate:dates"?: ((value: ResumeDate) => any) | undefined;
16
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
- declare const _default: typeof __VLS_export;
18
- export default _default;
@@ -1,67 +0,0 @@
1
- <script setup>
2
- import { ref, watch, computed } from "vue";
3
- import { useI18n } from "vue-i18n";
4
- defineProps({
5
- month: { type: Boolean, required: false }
6
- });
7
- const { t } = useI18n();
8
- const dates = defineModel("dates", { type: Object, ...{ required: true } });
9
- const present = ref(dates.value.endDate !== "" && !dates.value.endDate);
10
- watch(present, (value) => {
11
- if (value) {
12
- dates.value.endDate = null;
13
- } else {
14
- dates.value.endDate = "";
15
- }
16
- });
17
- const dateIsCorrect = computed(() => {
18
- if (dates.value.startDate && dates.value.endDate) {
19
- return new Date(dates.value.startDate) <= new Date(dates.value.endDate);
20
- }
21
- return true;
22
- });
23
- defineExpose({ dateIsCorrect });
24
- </script>
25
-
26
- <template>
27
- <orio-control-element
28
- v-bind="$attrs"
29
- :error="!dateIsCorrect ? t('dateRangePicker.startBeforeEnd') : null"
30
- >
31
- <div class="date-range-picker">
32
- <orio-date-picker
33
- v-model:date="dates.startDate"
34
- class="error-fields"
35
- :month
36
- />
37
- <orio-date-picker
38
- v-model:date="dates.endDate"
39
- class="error-fields"
40
- :month
41
- />
42
- <orio-check-box v-model="present">
43
- {{ t("dateRangePicker.present") }}
44
- </orio-check-box>
45
- </div>
46
- </orio-control-element>
47
- </template>
48
-
49
- <style scoped>
50
- .date-range-picker {
51
- display: flex;
52
- align-items: center;
53
- flex-wrap: wrap;
54
- }
55
- .date-range-picker > * {
56
- min-width: 0;
57
- }
58
- .date-range-picker .date-picker {
59
- margin-inline: 0;
60
- }
61
- .date-range-picker .date-picker:first-child {
62
- margin-inline-end: 0.5rem;
63
- }
64
- .date-range-picker .checkbox {
65
- margin-inline-start: 0.25rem;
66
- }
67
- </style>
@@ -1,18 +0,0 @@
1
- import type { ResumeDate } from "./view/Dates.vue.js";
2
- export interface DateRangePickerProps {
3
- month?: boolean;
4
- }
5
- type __VLS_Props = DateRangePickerProps;
6
- type __VLS_ModelProps = {
7
- "dates": ResumeDate;
8
- };
9
- type __VLS_PublicProps = __VLS_Props & __VLS_ModelProps;
10
- declare const __VLS_export: import("vue").DefineComponent<__VLS_PublicProps, {
11
- dateIsCorrect: import("vue").ComputedRef<boolean>;
12
- }, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {
13
- "update:dates": (value: ResumeDate) => any;
14
- }, string, import("vue").PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
15
- "onUpdate:dates"?: ((value: ResumeDate) => any) | undefined;
16
- }>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, false, {}, any>;
17
- declare const _default: typeof __VLS_export;
18
- export default _default;