@umbra.ui/core 0.4.3 → 0.4.5
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.
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ChevronRightIcon, CalendarDaysIcon } from "@umbra.ui/icons";
|
|
3
3
|
// - Imports
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ref,
|
|
6
|
+
watch,
|
|
7
|
+
onMounted,
|
|
8
|
+
nextTick,
|
|
9
|
+
computed,
|
|
10
|
+
onUnmounted,
|
|
11
|
+
useSlots,
|
|
12
|
+
} from "vue";
|
|
5
13
|
import {
|
|
6
14
|
offset,
|
|
7
15
|
flip,
|
|
@@ -28,10 +36,14 @@ interface Day {
|
|
|
28
36
|
// - Props
|
|
29
37
|
export interface Props {
|
|
30
38
|
date: Date;
|
|
39
|
+
label?: boolean;
|
|
31
40
|
}
|
|
32
41
|
const props = withDefaults(defineProps<Props>(), {
|
|
33
42
|
date: () => new Date(),
|
|
43
|
+
label: true,
|
|
34
44
|
});
|
|
45
|
+
const slots = useSlots();
|
|
46
|
+
const hasCustomLabelSlot = computed(() => Boolean(slots.label));
|
|
35
47
|
// - Emits
|
|
36
48
|
const emits = defineEmits(["update:date"]);
|
|
37
49
|
// - State Management
|
|
@@ -379,14 +391,19 @@ const handleOverlayClick = () => {
|
|
|
379
391
|
<div
|
|
380
392
|
:class="[
|
|
381
393
|
$style.button,
|
|
382
|
-
|
|
394
|
+
!hasCustomLabelSlot &&
|
|
395
|
+
(showPopover ? $style.button_selected : $style.button_normal),
|
|
383
396
|
]"
|
|
384
397
|
@click="togglePopover"
|
|
385
398
|
ref="button"
|
|
399
|
+
data-date-picker-button
|
|
400
|
+
:data-date-picker-open="showPopover ? 'true' : 'false'"
|
|
386
401
|
>
|
|
387
|
-
<
|
|
388
|
-
|
|
389
|
-
|
|
402
|
+
<slot v-if="label" name="label">
|
|
403
|
+
<CalendarDaysIcon :size="16" />
|
|
404
|
+
<p :class="['callout', $style.button_label]">{{ dateString }}</p>
|
|
405
|
+
<p :class="['callout', $style.button_sublabel]">{{ yearString }}</p>
|
|
406
|
+
</slot>
|
|
390
407
|
</div>
|
|
391
408
|
|
|
392
409
|
<!-- Teleport the overlay and picker to body -->
|
|
@@ -66,11 +66,77 @@ const handleDateChange = (date: Date) => {
|
|
|
66
66
|
</style>
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## Custom Label Slot
|
|
70
|
+
|
|
71
|
+
When you provide a custom `label` slot, the default button hover/selected
|
|
72
|
+
styles are disabled so you can fully control the label visuals. The
|
|
73
|
+
DatePicker button exposes a `data-date-picker-button` attribute you can use
|
|
74
|
+
to target hover/open states from your custom label styles.
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<script setup lang="ts">
|
|
78
|
+
import { ref, computed } from "vue";
|
|
79
|
+
import { DatePicker } from "@umbra-ui/core";
|
|
80
|
+
import { CalendarDaysIcon } from "@umbra-ui/icons";
|
|
81
|
+
|
|
82
|
+
const selectedDate = ref(new Date());
|
|
83
|
+
const formattedDate = computed(() =>
|
|
84
|
+
selectedDate.value.toLocaleDateString("en-US", {
|
|
85
|
+
month: "short",
|
|
86
|
+
day: "numeric",
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<DatePicker v-model:date="selectedDate">
|
|
93
|
+
<template #label>
|
|
94
|
+
<span class="date-chip">
|
|
95
|
+
<CalendarDaysIcon :size="14" />
|
|
96
|
+
{{ formattedDate }}
|
|
97
|
+
</span>
|
|
98
|
+
</template>
|
|
99
|
+
</DatePicker>
|
|
100
|
+
</template>
|
|
101
|
+
|
|
102
|
+
<style module>
|
|
103
|
+
.date-chip {
|
|
104
|
+
display: inline-flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: 0.353rem;
|
|
107
|
+
transition: transform 0.2s ease, opacity 0.2s ease;
|
|
108
|
+
transform: translateY(0);
|
|
109
|
+
opacity: 0.9;
|
|
110
|
+
}
|
|
111
|
+
:global([data-date-picker-button]:hover) .date-chip,
|
|
112
|
+
:global([data-date-picker-button][data-date-picker-open="true"]) .date-chip {
|
|
113
|
+
transform: translateY(-1px);
|
|
114
|
+
opacity: 1;
|
|
115
|
+
}
|
|
116
|
+
</style>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Hiding the Label
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<script setup lang="ts">
|
|
123
|
+
import { ref } from "vue";
|
|
124
|
+
import { DatePicker } from "@umbra-ui/core";
|
|
125
|
+
|
|
126
|
+
const selectedDate = ref(new Date());
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<template>
|
|
130
|
+
<DatePicker v-model:date="selectedDate" :label="false" />
|
|
131
|
+
</template>
|
|
132
|
+
```
|
|
133
|
+
|
|
69
134
|
## Props
|
|
70
135
|
|
|
71
|
-
| Prop Name | Type
|
|
72
|
-
| --------- |
|
|
73
|
-
| `date` | `Date`
|
|
136
|
+
| Prop Name | Type | Required | Default | Description |
|
|
137
|
+
| --------- | --------- | -------- | ------------ | ------------------------------------- |
|
|
138
|
+
| `date` | `Date` | Yes | `new Date()` | Currently selected date |
|
|
139
|
+
| `label` | `boolean` | No | `true` | Show or hide the label content/slot |
|
|
74
140
|
|
|
75
141
|
## Events
|
|
76
142
|
|
package/package.json
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { ChevronRightIcon, CalendarDaysIcon } from "@umbra.ui/icons";
|
|
3
3
|
// - Imports
|
|
4
|
-
import {
|
|
4
|
+
import {
|
|
5
|
+
ref,
|
|
6
|
+
watch,
|
|
7
|
+
onMounted,
|
|
8
|
+
nextTick,
|
|
9
|
+
computed,
|
|
10
|
+
onUnmounted,
|
|
11
|
+
useSlots,
|
|
12
|
+
} from "vue";
|
|
5
13
|
import {
|
|
6
14
|
offset,
|
|
7
15
|
flip,
|
|
@@ -28,10 +36,14 @@ interface Day {
|
|
|
28
36
|
// - Props
|
|
29
37
|
export interface Props {
|
|
30
38
|
date: Date;
|
|
39
|
+
label?: boolean;
|
|
31
40
|
}
|
|
32
41
|
const props = withDefaults(defineProps<Props>(), {
|
|
33
42
|
date: () => new Date(),
|
|
43
|
+
label: true,
|
|
34
44
|
});
|
|
45
|
+
const slots = useSlots();
|
|
46
|
+
const hasCustomLabelSlot = computed(() => Boolean(slots.label));
|
|
35
47
|
// - Emits
|
|
36
48
|
const emits = defineEmits(["update:date"]);
|
|
37
49
|
// - State Management
|
|
@@ -379,14 +391,19 @@ const handleOverlayClick = () => {
|
|
|
379
391
|
<div
|
|
380
392
|
:class="[
|
|
381
393
|
$style.button,
|
|
382
|
-
|
|
394
|
+
!hasCustomLabelSlot &&
|
|
395
|
+
(showPopover ? $style.button_selected : $style.button_normal),
|
|
383
396
|
]"
|
|
384
397
|
@click="togglePopover"
|
|
385
398
|
ref="button"
|
|
399
|
+
data-date-picker-button
|
|
400
|
+
:data-date-picker-open="showPopover ? 'true' : 'false'"
|
|
386
401
|
>
|
|
387
|
-
<
|
|
388
|
-
|
|
389
|
-
|
|
402
|
+
<slot v-if="label" name="label">
|
|
403
|
+
<CalendarDaysIcon :size="16" />
|
|
404
|
+
<p :class="['callout', $style.button_label]">{{ dateString }}</p>
|
|
405
|
+
<p :class="['callout', $style.button_sublabel]">{{ yearString }}</p>
|
|
406
|
+
</slot>
|
|
390
407
|
</div>
|
|
391
408
|
|
|
392
409
|
<!-- Teleport the overlay and picker to body -->
|
|
@@ -66,11 +66,77 @@ const handleDateChange = (date: Date) => {
|
|
|
66
66
|
</style>
|
|
67
67
|
```
|
|
68
68
|
|
|
69
|
+
## Custom Label Slot
|
|
70
|
+
|
|
71
|
+
When you provide a custom `label` slot, the default button hover/selected
|
|
72
|
+
styles are disabled so you can fully control the label visuals. The
|
|
73
|
+
DatePicker button exposes a `data-date-picker-button` attribute you can use
|
|
74
|
+
to target hover/open states from your custom label styles.
|
|
75
|
+
|
|
76
|
+
```vue
|
|
77
|
+
<script setup lang="ts">
|
|
78
|
+
import { ref, computed } from "vue";
|
|
79
|
+
import { DatePicker } from "@umbra-ui/core";
|
|
80
|
+
import { CalendarDaysIcon } from "@umbra-ui/icons";
|
|
81
|
+
|
|
82
|
+
const selectedDate = ref(new Date());
|
|
83
|
+
const formattedDate = computed(() =>
|
|
84
|
+
selectedDate.value.toLocaleDateString("en-US", {
|
|
85
|
+
month: "short",
|
|
86
|
+
day: "numeric",
|
|
87
|
+
})
|
|
88
|
+
);
|
|
89
|
+
</script>
|
|
90
|
+
|
|
91
|
+
<template>
|
|
92
|
+
<DatePicker v-model:date="selectedDate">
|
|
93
|
+
<template #label>
|
|
94
|
+
<span class="date-chip">
|
|
95
|
+
<CalendarDaysIcon :size="14" />
|
|
96
|
+
{{ formattedDate }}
|
|
97
|
+
</span>
|
|
98
|
+
</template>
|
|
99
|
+
</DatePicker>
|
|
100
|
+
</template>
|
|
101
|
+
|
|
102
|
+
<style module>
|
|
103
|
+
.date-chip {
|
|
104
|
+
display: inline-flex;
|
|
105
|
+
align-items: center;
|
|
106
|
+
gap: 0.353rem;
|
|
107
|
+
transition: transform 0.2s ease, opacity 0.2s ease;
|
|
108
|
+
transform: translateY(0);
|
|
109
|
+
opacity: 0.9;
|
|
110
|
+
}
|
|
111
|
+
:global([data-date-picker-button]:hover) .date-chip,
|
|
112
|
+
:global([data-date-picker-button][data-date-picker-open="true"]) .date-chip {
|
|
113
|
+
transform: translateY(-1px);
|
|
114
|
+
opacity: 1;
|
|
115
|
+
}
|
|
116
|
+
</style>
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
### Hiding the Label
|
|
120
|
+
|
|
121
|
+
```vue
|
|
122
|
+
<script setup lang="ts">
|
|
123
|
+
import { ref } from "vue";
|
|
124
|
+
import { DatePicker } from "@umbra-ui/core";
|
|
125
|
+
|
|
126
|
+
const selectedDate = ref(new Date());
|
|
127
|
+
</script>
|
|
128
|
+
|
|
129
|
+
<template>
|
|
130
|
+
<DatePicker v-model:date="selectedDate" :label="false" />
|
|
131
|
+
</template>
|
|
132
|
+
```
|
|
133
|
+
|
|
69
134
|
## Props
|
|
70
135
|
|
|
71
|
-
| Prop Name | Type
|
|
72
|
-
| --------- |
|
|
73
|
-
| `date` | `Date`
|
|
136
|
+
| Prop Name | Type | Required | Default | Description |
|
|
137
|
+
| --------- | --------- | -------- | ------------ | ------------------------------------- |
|
|
138
|
+
| `date` | `Date` | Yes | `new Date()` | Currently selected date |
|
|
139
|
+
| `label` | `boolean` | No | `true` | Show or hide the label content/slot |
|
|
74
140
|
|
|
75
141
|
## Events
|
|
76
142
|
|