mirror of
https://github.com/ArthurDanjou/ui.git
synced 2026-01-30 03:38:54 +01:00
chore: update components
This commit is contained in:
@@ -2,15 +2,11 @@
|
|||||||
<span class="relative inline-flex items-center justify-center" :class="avatarClass" @click="goto">
|
<span class="relative inline-flex items-center justify-center" :class="avatarClass" @click="goto">
|
||||||
<img v-if="url" :src="url" :alt="alt" :class="[sizeClass, roundedClass]">
|
<img v-if="url" :src="url" :alt="alt" :class="[sizeClass, roundedClass]">
|
||||||
<!-- eslint-disable-next-line vue/no-v-html -->
|
<!-- eslint-disable-next-line vue/no-v-html -->
|
||||||
<span v-else-if="gradientPlaceholder" class="w-full h-full" v-html="gradientPlaceholder" />
|
<span v-else-if="gradientPlaceholder" class="w-full h-full overflow-hidden" :class="roundedClass" v-html="gradientPlaceholder" />
|
||||||
<span
|
<span
|
||||||
v-else-if="placeholder"
|
v-else-if="placeholder"
|
||||||
class="font-bold leading-none text-white uppercase"
|
class="font-medium leading-none text-white uppercase"
|
||||||
>{{ placeholder }}</span>
|
>{{ placeholder }}</span>
|
||||||
<span
|
|
||||||
v-else-if="text"
|
|
||||||
class="leading-snug"
|
|
||||||
>{{ text }}</span>
|
|
||||||
<svg
|
<svg
|
||||||
v-else
|
v-else
|
||||||
class="w-full h-full text-tw-gray-300"
|
class="w-full h-full text-tw-gray-300"
|
||||||
@@ -40,10 +36,6 @@ export default {
|
|||||||
type: [String, Boolean],
|
type: [String, Boolean],
|
||||||
default: null
|
default: null
|
||||||
},
|
},
|
||||||
text: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
alt: {
|
alt: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
@@ -117,7 +109,7 @@ export default {
|
|||||||
},
|
},
|
||||||
placeholderClass () {
|
placeholderClass () {
|
||||||
return ({
|
return ({
|
||||||
true: 'bg-tw-white',
|
true: 'bg-tw-gray-500',
|
||||||
false: 'bg-tw-gray-100'
|
false: 'bg-tw-gray-100'
|
||||||
})[!!this.alt]
|
})[!!this.alt]
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default {
|
|||||||
},
|
},
|
||||||
strategy: {
|
strategy: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'absolute'
|
default: 'fixed'
|
||||||
},
|
},
|
||||||
wrapperClass: {
|
wrapperClass: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@@ -3,26 +3,23 @@
|
|||||||
<textarea
|
<textarea
|
||||||
:id="name"
|
:id="name"
|
||||||
ref="textarea"
|
ref="textarea"
|
||||||
:name="name"
|
|
||||||
:value="modelValue"
|
:value="modelValue"
|
||||||
|
:name="name"
|
||||||
:rows="rows"
|
:rows="rows"
|
||||||
:required="required"
|
:required="required"
|
||||||
:disabled="disabled"
|
:disabled="disabled"
|
||||||
:placeholder="placeholder"
|
:placeholder="placeholder"
|
||||||
:autocomplete="autocomplete"
|
:autocomplete="autocomplete"
|
||||||
:class="textareaClass"
|
:class="[baseClass, customClass, sizeClass, paddingClass, appearanceClass, resizeClass]"
|
||||||
@input="updateValue($event.target.value)"
|
@input="onInput($event.target.value)"
|
||||||
|
@focus="$emit('focus', $event)"
|
||||||
|
@blur="$emit('blur', $event)"
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
// import Focus from '../../directives/focus'
|
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// directives: {
|
|
||||||
// focus: Focus
|
|
||||||
// },
|
|
||||||
props: {
|
props: {
|
||||||
modelValue: {
|
modelValue: {
|
||||||
type: [String, Number],
|
type: [String, Number],
|
||||||
@@ -48,6 +45,10 @@ export default {
|
|||||||
type: Number,
|
type: Number,
|
||||||
default: 3
|
default: 3
|
||||||
},
|
},
|
||||||
|
autoresize: {
|
||||||
|
type: Boolean,
|
||||||
|
default: false
|
||||||
|
},
|
||||||
autofocus: {
|
autofocus: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false
|
||||||
@@ -63,6 +64,13 @@ export default {
|
|||||||
return ['default', 'none'].includes(value)
|
return ['default', 'none'].includes(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
resize: {
|
||||||
|
type: Boolean,
|
||||||
|
default: null,
|
||||||
|
validator (value) {
|
||||||
|
return ['none'].includes(value)
|
||||||
|
}
|
||||||
|
},
|
||||||
size: {
|
size: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'md',
|
default: 'md',
|
||||||
@@ -70,88 +78,90 @@ export default {
|
|||||||
return ['', 'xxs', 'xs', 'sm', 'md', 'lg', 'xl'].includes(value)
|
return ['', 'xxs', 'xs', 'sm', 'md', 'lg', 'xl'].includes(value)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
wrapperClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'relative'
|
||||||
|
},
|
||||||
baseClass: {
|
baseClass: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'block w-full bg-tw-white disabled:cursor-not-allowed disabled:bg-tw-gray-50'
|
default: 'block w-full bg-tw-white disabled:cursor-not-allowed disabled:bg-tw-gray-50 focus:outline-none'
|
||||||
},
|
},
|
||||||
customClass: {
|
customClass: {
|
||||||
type: String,
|
type: String,
|
||||||
default: null
|
default: null
|
||||||
},
|
|
||||||
noResize: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
emits: ['update:modelValue'],
|
emits: ['update:modelValue'],
|
||||||
computed: {
|
setup (props, { emit }) {
|
||||||
sizeClass () {
|
const textarea = ref(null)
|
||||||
return ({
|
|
||||||
xxs: 'text-xs',
|
const autoFocus = () => {
|
||||||
xs: 'text-xs',
|
if (props.autofocus) {
|
||||||
sm: 'text-sm leading-4',
|
textarea.value.focus()
|
||||||
md: 'text-sm',
|
}
|
||||||
lg: 'text-base',
|
|
||||||
xl: 'text-base'
|
|
||||||
})[this.size]
|
|
||||||
},
|
|
||||||
paddingClass () {
|
|
||||||
return ({
|
|
||||||
xxs: 'px-1 py-0.5',
|
|
||||||
xs: 'px-2.5 py-1.5',
|
|
||||||
sm: 'px-3 py-2',
|
|
||||||
md: 'px-4 py-2',
|
|
||||||
lg: 'px-4 py-2',
|
|
||||||
xl: 'px-6 py-3'
|
|
||||||
})[this.size]
|
|
||||||
},
|
|
||||||
appearanceClass () {
|
|
||||||
return ({
|
|
||||||
default: 'focus:ring-primary-500 focus:border-primary-500 border-tw-gray-300 rounded-md',
|
|
||||||
none: 'border-0 bg-transparent focus:ring-0 focus:shadow-none'
|
|
||||||
})[this.appearance]
|
|
||||||
},
|
|
||||||
resizeClass () {
|
|
||||||
return ({
|
|
||||||
true: 'resize-none',
|
|
||||||
false: ''
|
|
||||||
})[this.noResize]
|
|
||||||
},
|
|
||||||
textareaClass () {
|
|
||||||
return [
|
|
||||||
this.baseClass,
|
|
||||||
this.customClass,
|
|
||||||
this.sizeClass,
|
|
||||||
this.paddingClass,
|
|
||||||
this.resizeClass,
|
|
||||||
this.appearanceClass
|
|
||||||
].join(' ')
|
|
||||||
},
|
|
||||||
wrapperClass () {
|
|
||||||
return [
|
|
||||||
'relative',
|
|
||||||
this.appearance !== 'none' ? 'shadow-sm' : ''
|
|
||||||
].filter(Boolean).join(' ')
|
|
||||||
}
|
}
|
||||||
},
|
|
||||||
watch: {
|
const autoResize = () => {
|
||||||
value () {
|
if (props.autoresize) {
|
||||||
this.resizeTextarea()
|
const styles = window.getComputedStyle(textarea.value)
|
||||||
|
const paddingTop = parseInt(styles.paddingTop)
|
||||||
|
const paddingBottom = parseInt(styles.paddingBottom)
|
||||||
|
const padding = paddingTop + paddingBottom
|
||||||
|
const initialHeight = (parseInt(styles.height) - padding) / textarea.value.rows
|
||||||
|
const scrollHeight = textarea.value.scrollHeight - padding
|
||||||
|
const newRows = Math.ceil(scrollHeight / initialHeight)
|
||||||
|
|
||||||
|
textarea.value.rows = newRows
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
mounted () {
|
const onInput = (value) => {
|
||||||
this.resizeTextarea()
|
autoResize()
|
||||||
},
|
|
||||||
methods: {
|
emit('update:modelValue', value)
|
||||||
resizeTextarea () {
|
}
|
||||||
this.$nextTick(() => {
|
|
||||||
const textarea = this.$refs.textarea
|
onMounted(() => {
|
||||||
textarea.style.height = 'auto'
|
setTimeout(() => {
|
||||||
textarea.style.height = `${textarea.scrollHeight}px`
|
autoFocus()
|
||||||
})
|
autoResize()
|
||||||
},
|
}, 100)
|
||||||
updateValue (value) {
|
})
|
||||||
this.$emit('update:modelValue', value)
|
|
||||||
|
const sizeClass = computed(() => ({
|
||||||
|
xxs: 'text-xs',
|
||||||
|
xs: 'text-xs',
|
||||||
|
sm: 'text-sm leading-4',
|
||||||
|
md: 'text-sm',
|
||||||
|
lg: 'text-base',
|
||||||
|
xl: 'text-base'
|
||||||
|
})[props.size])
|
||||||
|
|
||||||
|
const paddingClass = computed(() => ({
|
||||||
|
xxs: 'px-1 py-0.5',
|
||||||
|
xs: 'px-2.5 py-1.5',
|
||||||
|
sm: 'px-3 py-2',
|
||||||
|
md: 'px-4 py-2',
|
||||||
|
lg: 'px-4 py-2',
|
||||||
|
xl: 'px-6 py-3'
|
||||||
|
})[props.size])
|
||||||
|
|
||||||
|
const appearanceClass = computed(() => ({
|
||||||
|
default: 'focus:ring-1 focus:ring-primary-500 focus:border-primary-500 border border-tw-gray-300 rounded-md',
|
||||||
|
none: 'border-0 bg-transparent focus:ring-0 focus:shadow-none'
|
||||||
|
})[props.appearance])
|
||||||
|
|
||||||
|
const resizeClass = computed(() => {
|
||||||
|
return props.resize === 'none' ? 'resize-none' : ''
|
||||||
|
})
|
||||||
|
|
||||||
|
return {
|
||||||
|
textarea,
|
||||||
|
onInput,
|
||||||
|
sizeClass,
|
||||||
|
paddingClass,
|
||||||
|
appearanceClass,
|
||||||
|
resizeClass
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ export default {
|
|||||||
},
|
},
|
||||||
strategy: {
|
strategy: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'absolute'
|
default: 'fixed'
|
||||||
},
|
},
|
||||||
wrapperClass: {
|
wrapperClass: {
|
||||||
type: String,
|
type: String,
|
||||||
|
|||||||
@@ -14,11 +14,7 @@
|
|||||||
<div
|
<div
|
||||||
v-show="show && (text || shortcuts.length || $slots.text)"
|
v-show="show && (text || shortcuts.length || $slots.text)"
|
||||||
ref="tooltip"
|
ref="tooltip"
|
||||||
class="fixed z-30 flex items-center justify-center invisible w-auto h-6 max-w-xs px-2 space-x-1 truncate rounded shadow lg:visible"
|
class="fixed z-30 flex bg-gray-800 items-center justify-center invisible w-auto h-6 max-w-xs px-2 space-x-1 truncate rounded shadow lg:visible"
|
||||||
:class="{
|
|
||||||
'bg-gray-800': !darken,
|
|
||||||
'bg-gray-900': darken
|
|
||||||
}"
|
|
||||||
>
|
>
|
||||||
<span v-if="text || $slots.text" class="truncate text-gray-50 text-xxs">
|
<span v-if="text || $slots.text" class="truncate text-gray-50 text-xxs">
|
||||||
<slot name="text">{{ text }}</slot>
|
<slot name="text">{{ text }}</slot>
|
||||||
@@ -43,113 +39,66 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
import { createPopper } from '@popperjs/core'
|
import { Popover, PopoverButton, PopoverPanel } from '@headlessui/vue'
|
||||||
// import { directive as onClickaway } from 'vue-clickaway'
|
|
||||||
|
import { usePopper } from '../../utils'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
// directives: {
|
components: {
|
||||||
// onClickaway
|
Popover,
|
||||||
// },
|
PopoverButton,
|
||||||
|
PopoverPanel
|
||||||
|
},
|
||||||
props: {
|
props: {
|
||||||
text: {
|
|
||||||
type: String,
|
|
||||||
default: null
|
|
||||||
},
|
|
||||||
shortcuts: {
|
|
||||||
type: Array,
|
|
||||||
default: () => []
|
|
||||||
},
|
|
||||||
darken: {
|
|
||||||
type: Boolean,
|
|
||||||
default: false
|
|
||||||
},
|
|
||||||
openDelay: {
|
|
||||||
type: Number,
|
|
||||||
default: 0
|
|
||||||
},
|
|
||||||
closeDelay: {
|
|
||||||
type: Number,
|
|
||||||
default: 100
|
|
||||||
},
|
|
||||||
placement: {
|
placement: {
|
||||||
type: String,
|
type: String,
|
||||||
default: 'bottom'
|
default: 'bottom'
|
||||||
|
},
|
||||||
|
strategy: {
|
||||||
|
type: String,
|
||||||
|
default: 'absolute'
|
||||||
|
},
|
||||||
|
wrapperClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'relative'
|
||||||
|
},
|
||||||
|
tooltipClass: {
|
||||||
|
type: String,
|
||||||
|
default: 'z-10'
|
||||||
|
},
|
||||||
|
label: {
|
||||||
|
type: String,
|
||||||
|
default: ''
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
data () {
|
setup (props) {
|
||||||
|
const [trigger, container] = usePopper({
|
||||||
|
placement: props.placement,
|
||||||
|
strategy: props.strategy,
|
||||||
|
modifiers: [{
|
||||||
|
name: 'offset',
|
||||||
|
options: {
|
||||||
|
offset: [0, 8]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'computeStyles',
|
||||||
|
options: {
|
||||||
|
gpuAcceleration: false,
|
||||||
|
adaptive: false
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'preventOverflow',
|
||||||
|
options: {
|
||||||
|
padding: 8
|
||||||
|
}
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
return {
|
return {
|
||||||
show: false,
|
trigger,
|
||||||
instance: null,
|
container
|
||||||
openTimeout: null,
|
|
||||||
closeTimeout: null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
watch: {
|
|
||||||
show (value) {
|
|
||||||
if (!value) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this.instance) {
|
|
||||||
this.instance.destroy()
|
|
||||||
this.instance = null
|
|
||||||
}
|
|
||||||
|
|
||||||
this.instance = createPopper(this.$refs.container, this.$refs.tooltip, {
|
|
||||||
strategy: 'fixed',
|
|
||||||
placement: this.placement,
|
|
||||||
modifiers: [
|
|
||||||
{
|
|
||||||
name: 'offset',
|
|
||||||
options: {
|
|
||||||
offset: [0, 8]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'computeStyles',
|
|
||||||
options: {
|
|
||||||
gpuAcceleration: false,
|
|
||||||
adaptive: false
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: 'preventOverflow',
|
|
||||||
options: {
|
|
||||||
padding: 8
|
|
||||||
}
|
|
||||||
}
|
|
||||||
]
|
|
||||||
})
|
|
||||||
}
|
|
||||||
},
|
|
||||||
beforeDestroy () {
|
|
||||||
if (this.instance) {
|
|
||||||
this.instance.destroy()
|
|
||||||
this.instance = null
|
|
||||||
}
|
|
||||||
},
|
|
||||||
methods: {
|
|
||||||
mouseover () {
|
|
||||||
clearTimeout(this.closeTimeout)
|
|
||||||
this.closeTimeout = null
|
|
||||||
this.openTimeout = this.openTimeout || setTimeout(() => {
|
|
||||||
this.open()
|
|
||||||
this.openTimeout = null
|
|
||||||
}, this.openDelay)
|
|
||||||
},
|
|
||||||
mouseleave () {
|
|
||||||
clearTimeout(this.openTimeout)
|
|
||||||
this.openTimeout = null
|
|
||||||
this.closeTimeout = this.closeTimeout || setTimeout(() => {
|
|
||||||
this.close()
|
|
||||||
this.closeTimeout = null
|
|
||||||
}, this.closeDelay)
|
|
||||||
},
|
|
||||||
open () {
|
|
||||||
this.show = true
|
|
||||||
},
|
|
||||||
close () {
|
|
||||||
this.show = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user