daisy-ui-kit 5.0.0-pre.26 → 5.0.0-pre.29
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/app/components/CalendarInput.vue +4 -4
- package/app/components/Dock.vue +3 -6
- package/app/components/DockItem.vue +3 -2
- package/app/components/Dropdown.vue +1 -1
- package/app/components/MenuExpand.vue +4 -6
- package/app/components/Range.vue +183 -43
- package/app/components/TextArea.vue +43 -1
- package/app/components/Tooltip.vue +1 -1
- package/package.json +5 -5
- package/app/utils/random-string.ts +0 -19
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { CalendarOptions } from '../composables/use-calendar'
|
|
3
|
-
import { computed, ref, watch } from 'vue'
|
|
3
|
+
import { computed, ref, useId, watch } from 'vue'
|
|
4
4
|
import { useCalendar } from '../composables/use-calendar'
|
|
5
|
-
import { randomString } from '../utils/random-string'
|
|
6
5
|
|
|
7
6
|
const props = defineProps<{
|
|
8
7
|
/** Bound value: Date object or ISO string or null */
|
|
@@ -37,8 +36,9 @@ const emit = defineEmits<{
|
|
|
37
36
|
(e: 'update:inputValue', v: string | null): void
|
|
38
37
|
}>()
|
|
39
38
|
|
|
40
|
-
const
|
|
41
|
-
const
|
|
39
|
+
const uniqueId = useId()
|
|
40
|
+
const popoverId = `calendar-popover-${uniqueId}`
|
|
41
|
+
const anchorName = `--calendar-anchor-${uniqueId}`
|
|
42
42
|
const inputRef = ref<HTMLInputElement | null>(null)
|
|
43
43
|
const popoverRef = ref<HTMLElement | null>(null)
|
|
44
44
|
|
package/app/components/Dock.vue
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { Ref } from 'vue'
|
|
3
3
|
import { provide, ref } from 'vue'
|
|
4
|
-
import { randomString } from '../utils/random-string'
|
|
5
4
|
|
|
6
5
|
const { size, xl, lg, md, sm, xs } = defineProps<{
|
|
7
6
|
size?: string
|
|
@@ -15,16 +14,14 @@ const { size, xl, lg, md, sm, xs } = defineProps<{
|
|
|
15
14
|
const activeItemId = ref<string | null>(null)
|
|
16
15
|
const itemIds = ref<string[]>([])
|
|
17
16
|
|
|
18
|
-
function registerItem() {
|
|
19
|
-
const itemId = randomString()
|
|
17
|
+
function registerItem(itemId: string) {
|
|
20
18
|
itemIds.value.push(itemId)
|
|
21
|
-
function unregister() {
|
|
19
|
+
return function unregister() {
|
|
22
20
|
itemIds.value = itemIds.value.filter(id => id !== itemId)
|
|
23
21
|
if (activeItemId.value === itemId) {
|
|
24
22
|
activeItemId.value = null
|
|
25
23
|
}
|
|
26
24
|
}
|
|
27
|
-
return { id: itemId, unregister }
|
|
28
25
|
}
|
|
29
26
|
|
|
30
27
|
function setActiveItemId(itemId: string) {
|
|
@@ -33,7 +30,7 @@ function setActiveItemId(itemId: string) {
|
|
|
33
30
|
|
|
34
31
|
export interface DockState {
|
|
35
32
|
activeItemId: Ref<string | null>
|
|
36
|
-
registerItem: (
|
|
33
|
+
registerItem: (itemId: string) => () => void
|
|
37
34
|
setActiveItemId: (itemId: string) => void
|
|
38
35
|
}
|
|
39
36
|
|
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import type { DockState } from './Dock.vue'
|
|
3
|
-
import { inject, onUnmounted } from 'vue'
|
|
3
|
+
import { inject, onUnmounted, useId } from 'vue'
|
|
4
4
|
|
|
5
5
|
const { active } = defineProps<{
|
|
6
6
|
active?: boolean
|
|
7
7
|
}>()
|
|
8
8
|
|
|
9
|
+
const itemId = useId()
|
|
9
10
|
const { registerItem, setActiveItemId, activeItemId } = inject<DockState>('dockState')!
|
|
10
|
-
const
|
|
11
|
+
const unregister = registerItem(itemId)
|
|
11
12
|
|
|
12
13
|
onUnmounted(() => {
|
|
13
14
|
unregister()
|
|
@@ -2,8 +2,7 @@
|
|
|
2
2
|
import type { Ref } from 'vue'
|
|
3
3
|
|
|
4
4
|
import { onClickOutside, useElementHover } from '@vueuse/core'
|
|
5
|
-
import { onMounted, provide, ref } from 'vue'
|
|
6
|
-
import { randomString } from '../utils/random-string'
|
|
5
|
+
import { onMounted, provide, ref, useId } from 'vue'
|
|
7
6
|
|
|
8
7
|
// Define the MenuExpandState interface
|
|
9
8
|
export interface MenuExpandState {
|
|
@@ -16,12 +15,10 @@ export interface MenuExpandState {
|
|
|
16
15
|
|
|
17
16
|
// Props with defaults
|
|
18
17
|
const {
|
|
19
|
-
randomId = randomString(12),
|
|
20
18
|
hover = false,
|
|
21
19
|
delayLeave = 300,
|
|
22
20
|
closeOnClickOutside = false,
|
|
23
21
|
} = defineProps<{
|
|
24
|
-
randomId?: string
|
|
25
22
|
hover?: boolean
|
|
26
23
|
delayLeave?: number
|
|
27
24
|
closeOnClickOutside?: boolean
|
|
@@ -31,8 +28,9 @@ const {
|
|
|
31
28
|
const isOpen = defineModel('open', { default: false, type: Boolean })
|
|
32
29
|
|
|
33
30
|
// Generate IDs for accessibility and targeting
|
|
34
|
-
const
|
|
35
|
-
const
|
|
31
|
+
const uniqueId = useId()
|
|
32
|
+
const wrapperId = `expand-wrapper-${uniqueId}`
|
|
33
|
+
const id = `expand-${uniqueId}`
|
|
36
34
|
|
|
37
35
|
// Element reference for click outside detection
|
|
38
36
|
const expandEl = ref()
|
package/app/components/Range.vue
CHANGED
|
@@ -1,61 +1,201 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
import { computed } from 'vue'
|
|
3
3
|
|
|
4
|
-
const props =
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
4
|
+
const props = withDefaults(
|
|
5
|
+
defineProps<{
|
|
6
|
+
modelValue?: number | [number, number]
|
|
7
|
+
min?: number
|
|
8
|
+
max?: number
|
|
9
|
+
step?: number
|
|
10
|
+
disabled?: boolean
|
|
11
|
+
|
|
12
|
+
color?: string
|
|
13
|
+
neutral?: boolean
|
|
14
|
+
primary?: boolean
|
|
15
|
+
secondary?: boolean
|
|
16
|
+
accent?: boolean
|
|
17
|
+
success?: boolean
|
|
18
|
+
warning?: boolean
|
|
19
|
+
info?: boolean
|
|
20
|
+
error?: boolean
|
|
21
|
+
|
|
22
|
+
size?: 'xl' | 'lg' | 'md' | 'sm' | 'xs'
|
|
23
|
+
xl?: boolean
|
|
24
|
+
lg?: boolean
|
|
25
|
+
md?: boolean
|
|
26
|
+
sm?: boolean
|
|
27
|
+
xs?: boolean
|
|
28
|
+
}>(),
|
|
29
|
+
{
|
|
30
|
+
min: 0,
|
|
31
|
+
max: 100,
|
|
32
|
+
step: 1,
|
|
33
|
+
},
|
|
34
|
+
)
|
|
28
35
|
const emit = defineEmits(['update:modelValue'])
|
|
29
36
|
|
|
30
|
-
const
|
|
31
|
-
|
|
32
|
-
|
|
37
|
+
const isRange = computed(() => {
|
|
38
|
+
return Array.isArray(props.modelValue)
|
|
39
|
+
})
|
|
40
|
+
|
|
41
|
+
const singleValue = computed({
|
|
42
|
+
get: () => (isRange.value ? 0 : (props.modelValue as number)),
|
|
43
|
+
set: val => emit('update:modelValue', Number(val)),
|
|
44
|
+
})
|
|
45
|
+
|
|
46
|
+
const lowValue = computed({
|
|
47
|
+
get: () => (isRange.value ? (props.modelValue as [number, number])[0] : 0),
|
|
48
|
+
set: val => {
|
|
49
|
+
const v = Number(val)
|
|
50
|
+
const high = (props.modelValue as [number, number])[1]
|
|
51
|
+
emit('update:modelValue', [Math.min(v, high), high])
|
|
52
|
+
},
|
|
53
|
+
})
|
|
54
|
+
|
|
55
|
+
const highValue = computed({
|
|
56
|
+
get: () => (isRange.value ? (props.modelValue as [number, number])[1] : 100),
|
|
57
|
+
set: val => {
|
|
58
|
+
const v = Number(val)
|
|
59
|
+
const low = (props.modelValue as [number, number])[0]
|
|
60
|
+
emit('update:modelValue', [low, Math.max(v, low)])
|
|
61
|
+
},
|
|
62
|
+
})
|
|
63
|
+
|
|
64
|
+
const rangeClasses = computed(() => ({
|
|
65
|
+
'range-neutral': props.neutral || props.color === 'neutral',
|
|
66
|
+
'range-primary': props.primary || props.color === 'primary',
|
|
67
|
+
'range-secondary': props.secondary || props.color === 'secondary',
|
|
68
|
+
'range-accent': props.accent || props.color === 'accent',
|
|
69
|
+
'range-success': props.success || props.color === 'success',
|
|
70
|
+
'range-info': props.info || props.color === 'info',
|
|
71
|
+
'range-warning': props.warning || props.color === 'warning',
|
|
72
|
+
'range-error': props.error || props.color === 'error',
|
|
73
|
+
'range-xl': props.xl || props.size === 'xl',
|
|
74
|
+
'range-lg': props.lg || props.size === 'lg',
|
|
75
|
+
'range-md': props.md || props.size === 'md',
|
|
76
|
+
'range-sm': props.sm || props.size === 'sm',
|
|
77
|
+
'range-xs': props.xs || props.size === 'xs',
|
|
78
|
+
}))
|
|
79
|
+
|
|
80
|
+
// Calculate percentage positions for the filled track
|
|
81
|
+
const lowPercent = computed(() => {
|
|
82
|
+
const range = props.max - props.min
|
|
83
|
+
return ((lowValue.value - props.min) / range) * 100
|
|
84
|
+
})
|
|
85
|
+
|
|
86
|
+
const highPercent = computed(() => {
|
|
87
|
+
const range = props.max - props.min
|
|
88
|
+
return ((highValue.value - props.min) / range) * 100
|
|
33
89
|
})
|
|
34
90
|
</script>
|
|
35
91
|
|
|
36
92
|
<template>
|
|
93
|
+
<!-- Single value mode -->
|
|
37
94
|
<input
|
|
38
|
-
v-
|
|
95
|
+
v-if="!isRange"
|
|
96
|
+
v-model="singleValue"
|
|
39
97
|
type="range"
|
|
40
98
|
class="range"
|
|
41
|
-
:class="
|
|
42
|
-
'range-neutral': neutral || color === 'neutral',
|
|
43
|
-
'range-primary': primary || color === 'primary',
|
|
44
|
-
'range-secondary': secondary || color === 'secondary',
|
|
45
|
-
'range-accent': accent || color === 'accent',
|
|
46
|
-
'range-success': success || color === 'success',
|
|
47
|
-
'range-info': info || color === 'info',
|
|
48
|
-
'range-warning': warning || color === 'warning',
|
|
49
|
-
'range-error': error || color === 'error',
|
|
50
|
-
'range-xl': xl || size === 'xl',
|
|
51
|
-
'range-lg': lg || size === 'lg',
|
|
52
|
-
'range-md': md || size === 'md',
|
|
53
|
-
'range-sm': sm || size === 'sm',
|
|
54
|
-
'range-xs': xs || size === 'xs',
|
|
55
|
-
}"
|
|
99
|
+
:class="rangeClasses"
|
|
56
100
|
:min="min"
|
|
57
101
|
:max="max"
|
|
58
102
|
:step="step"
|
|
59
103
|
:disabled="disabled"
|
|
60
104
|
/>
|
|
105
|
+
|
|
106
|
+
<!-- Dual handle range mode -->
|
|
107
|
+
<div v-else class="range range-slider-wrapper" :class="rangeClasses">
|
|
108
|
+
<div class="range-slider-track" />
|
|
109
|
+
<div
|
|
110
|
+
class="range-slider-fill"
|
|
111
|
+
:style="{
|
|
112
|
+
left: `calc(${lowPercent}% + (var(--range-thumb-size, 1.5rem) / 2) - (${lowPercent} * var(--range-thumb-size, 1.5rem) / 100))`,
|
|
113
|
+
width: `calc(${highPercent - lowPercent}% - (${highPercent - lowPercent} * var(--range-thumb-size, 1.5rem) / 100))`,
|
|
114
|
+
}"
|
|
115
|
+
/>
|
|
116
|
+
<input
|
|
117
|
+
v-model="lowValue"
|
|
118
|
+
type="range"
|
|
119
|
+
class="range range-slider-input"
|
|
120
|
+
:class="rangeClasses"
|
|
121
|
+
:min="min"
|
|
122
|
+
:max="max"
|
|
123
|
+
:step="step"
|
|
124
|
+
:disabled="disabled"
|
|
125
|
+
/>
|
|
126
|
+
<input
|
|
127
|
+
v-model="highValue"
|
|
128
|
+
type="range"
|
|
129
|
+
class="range range-slider-input"
|
|
130
|
+
:class="rangeClasses"
|
|
131
|
+
:min="min"
|
|
132
|
+
:max="max"
|
|
133
|
+
:step="step"
|
|
134
|
+
:disabled="disabled"
|
|
135
|
+
/>
|
|
136
|
+
</div>
|
|
61
137
|
</template>
|
|
138
|
+
|
|
139
|
+
<style>
|
|
140
|
+
.range-slider-wrapper {
|
|
141
|
+
position: relative;
|
|
142
|
+
width: 100%;
|
|
143
|
+
height: var(--range-thumb-size, 1.5rem);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
.range-slider-track {
|
|
147
|
+
position: absolute;
|
|
148
|
+
top: 50%;
|
|
149
|
+
left: 0;
|
|
150
|
+
right: 0;
|
|
151
|
+
height: calc(var(--range-thumb-size, 1.5rem) / 3);
|
|
152
|
+
transform: translateY(-50%);
|
|
153
|
+
background: color-mix(in oklab, currentColor 10%, transparent);
|
|
154
|
+
border-radius: var(--radius-selector, 1rem);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
.range-slider-fill {
|
|
158
|
+
position: absolute;
|
|
159
|
+
top: 50%;
|
|
160
|
+
height: var(--range-thumb-size, 1.5rem);
|
|
161
|
+
transform: translateY(-50%);
|
|
162
|
+
background: currentColor;
|
|
163
|
+
border-radius: 0;
|
|
164
|
+
z-index: 1;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
.range-slider-input {
|
|
168
|
+
position: absolute;
|
|
169
|
+
top: 0;
|
|
170
|
+
left: 0;
|
|
171
|
+
width: 100%;
|
|
172
|
+
height: 100%;
|
|
173
|
+
pointer-events: none;
|
|
174
|
+
background: transparent;
|
|
175
|
+
--range-fill: 0 !important;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/* Hide both tracks - we draw our own */
|
|
179
|
+
.range-slider-input::-webkit-slider-runnable-track {
|
|
180
|
+
background: transparent !important;
|
|
181
|
+
box-shadow: none !important;
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
.range-slider-input::-moz-range-track {
|
|
185
|
+
background: transparent !important;
|
|
186
|
+
box-shadow: none !important;
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/* Enable pointer events only on thumbs */
|
|
190
|
+
.range-slider-input::-webkit-slider-thumb {
|
|
191
|
+
pointer-events: auto;
|
|
192
|
+
position: relative;
|
|
193
|
+
z-index: 3;
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
.range-slider-input::-moz-range-thumb {
|
|
197
|
+
pointer-events: auto;
|
|
198
|
+
position: relative;
|
|
199
|
+
z-index: 3;
|
|
200
|
+
}
|
|
201
|
+
</style>
|
|
@@ -1,9 +1,13 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { nextTick, onMounted, ref, watch } from 'vue'
|
|
3
|
+
|
|
2
4
|
const props = withDefaults(
|
|
3
5
|
defineProps<{
|
|
4
6
|
modelValue?: string
|
|
5
7
|
placeholder?: string
|
|
6
8
|
type?: 'text' | 'phone' | 'email' | 'search'
|
|
9
|
+
rows?: number
|
|
10
|
+
autoExpand?: boolean
|
|
7
11
|
|
|
8
12
|
color?: string
|
|
9
13
|
neutral?: boolean
|
|
@@ -28,15 +32,48 @@ const props = withDefaults(
|
|
|
28
32
|
}>(),
|
|
29
33
|
{
|
|
30
34
|
type: 'text',
|
|
35
|
+
rows: 2,
|
|
31
36
|
},
|
|
32
37
|
)
|
|
33
38
|
defineEmits(['update:modelValue'])
|
|
39
|
+
|
|
40
|
+
const textareaRef = ref<HTMLTextAreaElement | null>(null)
|
|
41
|
+
|
|
42
|
+
let minHeight = 0
|
|
43
|
+
|
|
44
|
+
function adjustHeight() {
|
|
45
|
+
if (!props.autoExpand || !textareaRef.value) return
|
|
46
|
+
const el = textareaRef.value
|
|
47
|
+
|
|
48
|
+
// Capture the initial rendered height as minimum (respects rows attribute)
|
|
49
|
+
if (minHeight === 0) {
|
|
50
|
+
minHeight = el.offsetHeight
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
el.style.height = 'auto'
|
|
54
|
+
el.style.height = `${Math.max(el.scrollHeight, minHeight)}px`
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
watch(
|
|
58
|
+
() => props.modelValue,
|
|
59
|
+
() => {
|
|
60
|
+
nextTick(adjustHeight)
|
|
61
|
+
},
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
onMounted(() => {
|
|
65
|
+
if (props.autoExpand) {
|
|
66
|
+
nextTick(adjustHeight)
|
|
67
|
+
}
|
|
68
|
+
})
|
|
34
69
|
</script>
|
|
35
70
|
|
|
36
71
|
<template>
|
|
37
72
|
<textarea
|
|
73
|
+
ref="textareaRef"
|
|
38
74
|
:value="modelValue"
|
|
39
75
|
:type="type"
|
|
76
|
+
:rows="rows"
|
|
40
77
|
:placeholder="placeholder"
|
|
41
78
|
:disabled="disabled"
|
|
42
79
|
class="textarea"
|
|
@@ -59,6 +96,11 @@ defineEmits(['update:modelValue'])
|
|
|
59
96
|
'textarea-sm': props.sm || props.size === 'sm',
|
|
60
97
|
'textarea-xs': props.xs || props.size === 'xs',
|
|
61
98
|
}"
|
|
62
|
-
@input="
|
|
99
|
+
@input="
|
|
100
|
+
event => {
|
|
101
|
+
$emit('update:modelValue', (event.target as HTMLTextAreaElement).value)
|
|
102
|
+
adjustHeight()
|
|
103
|
+
}
|
|
104
|
+
"
|
|
63
105
|
/>
|
|
64
106
|
</template>
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "daisy-ui-kit",
|
|
3
3
|
"type": "module",
|
|
4
|
-
"version": "5.0.0-pre.
|
|
4
|
+
"version": "5.0.0-pre.29",
|
|
5
5
|
"packageManager": "pnpm@10.10.0",
|
|
6
6
|
"author": "feathers.dev",
|
|
7
7
|
"exports": {
|
|
@@ -39,10 +39,10 @@
|
|
|
39
39
|
"preview": "nuxt preview",
|
|
40
40
|
"postinstall": "nuxt prepare",
|
|
41
41
|
"publish": "git push origin --tags && git push origin",
|
|
42
|
-
"release:pre": "
|
|
43
|
-
"release:patch": "
|
|
44
|
-
"release:minor": "
|
|
45
|
-
"release:major": "
|
|
42
|
+
"release:pre": "node scripts/release.js prerelease",
|
|
43
|
+
"release:patch": "node scripts/release.js patch",
|
|
44
|
+
"release:minor": "node scripts/release.js minor",
|
|
45
|
+
"release:major": "node scripts/release.js major",
|
|
46
46
|
"deploy": "pnpm run build && npx wrangler deploy"
|
|
47
47
|
},
|
|
48
48
|
"peerDependencies": {
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Generate a random string of `length` characters
|
|
3
|
-
*
|
|
4
|
-
* Usage:
|
|
5
|
-
* const myString = randomString(15); // This will give you a random string of 15 characters
|
|
6
|
-
* @param length The length of the string to generate
|
|
7
|
-
* @returns A random string of `length` characters
|
|
8
|
-
*/
|
|
9
|
-
export function randomString(length: number = 10): string {
|
|
10
|
-
const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'
|
|
11
|
-
let result = ''
|
|
12
|
-
|
|
13
|
-
for (let i = 0; i < length; i++) {
|
|
14
|
-
const randomIndex = Math.floor(Math.random() * characters.length)
|
|
15
|
-
result += characters[randomIndex]
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
return result
|
|
19
|
-
}
|