@saasmakers/ui 2.0.5 → 2.0.7
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/bases/BaseAction.vue +138 -0
- package/app/components/bases/BaseCard.vue +4 -12
- package/app/components/bases/BaseEmoji.vue +6 -2
- package/app/components/bases/BaseIcon.vue +16 -2
- package/app/components/bases/BaseToast.vue +15 -6
- package/app/components/fields/FieldDays.vue +3 -1
- package/app/components/fields/FieldInput.vue +3 -1
- package/app/components/fields/FieldTextarea.vue +3 -1
- package/app/components/layout/LayoutBottomSheet.vue +1 -1
- package/app/components/layout/LayoutModal.vue +1 -1
- package/app/types/bases.d.ts +15 -0
- package/app/types/fields.d.ts +2 -0
- package/app/types/global.d.ts +2 -0
- package/package.json +1 -1
- package/uno.config.ts +1 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { BaseAction } from '../../types/bases'
|
|
3
|
+
|
|
4
|
+
const props = withDefaults(defineProps<BaseAction>(), {
|
|
5
|
+
active: false,
|
|
6
|
+
color: 'black',
|
|
7
|
+
confirmation: false,
|
|
8
|
+
disabled: false,
|
|
9
|
+
icon: undefined,
|
|
10
|
+
loading: false,
|
|
11
|
+
size: 'base',
|
|
12
|
+
text: '',
|
|
13
|
+
variant: 'outline',
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits<{
|
|
17
|
+
click: [event: MouseEvent]
|
|
18
|
+
confirm: [event: MouseEvent]
|
|
19
|
+
}>()
|
|
20
|
+
|
|
21
|
+
const confirming = ref(false)
|
|
22
|
+
const { t } = useI18n()
|
|
23
|
+
|
|
24
|
+
function onClick(event: MouseEvent) {
|
|
25
|
+
if (props.loading || props.disabled) {
|
|
26
|
+
return
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
if (props.confirmation) {
|
|
30
|
+
if (confirming.value) {
|
|
31
|
+
emit('confirm', event)
|
|
32
|
+
}
|
|
33
|
+
else {
|
|
34
|
+
setTimeout(() => (confirming.value = false), 3 * 1000)
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
confirming.value = !confirming.value
|
|
38
|
+
}
|
|
39
|
+
else {
|
|
40
|
+
emit('click', event)
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
</script>
|
|
44
|
+
|
|
45
|
+
<template>
|
|
46
|
+
<button
|
|
47
|
+
class="relative flex flex-col items-center rounded-lg text-center transition-colors"
|
|
48
|
+
:aria-busy="loading"
|
|
49
|
+
:class="{
|
|
50
|
+
'cursor-not-allowed opacity-50': disabled,
|
|
51
|
+
'cursor-pointer': !disabled && !loading,
|
|
52
|
+
'gap-1 p-2': size === 'sm',
|
|
53
|
+
'gap-1.5 p-3': size === 'base',
|
|
54
|
+
'gap-2 p-4': size === 'lg',
|
|
55
|
+
'border border-gray-200 bg-white dark:border-gray-800 dark:bg-gray-900': variant === 'outline' && !active,
|
|
56
|
+
'border border-gray-300 bg-gray-100 dark:border-gray-700 dark:bg-gray-800': variant === 'outline' && active,
|
|
57
|
+
'hover:border-gray-300 dark:hover:border-gray-700': variant === 'outline' && !disabled && !loading,
|
|
58
|
+
'bg-gray-100 dark:bg-gray-800': variant === 'filled',
|
|
59
|
+
}"
|
|
60
|
+
:disabled="disabled || loading"
|
|
61
|
+
type="button"
|
|
62
|
+
@click="onClick"
|
|
63
|
+
>
|
|
64
|
+
<span
|
|
65
|
+
class="flex flex-col items-center"
|
|
66
|
+
:class="{
|
|
67
|
+
'opacity-0': loading,
|
|
68
|
+
'gap-1': size === 'sm',
|
|
69
|
+
'gap-1.5': size === 'base',
|
|
70
|
+
'gap-2': size === 'lg',
|
|
71
|
+
}"
|
|
72
|
+
>
|
|
73
|
+
<BaseIcon
|
|
74
|
+
:color="color"
|
|
75
|
+
:icon="icon"
|
|
76
|
+
:size="size === 'lg' ? 'xl' : size === 'base' ? 'lg' : 'base'"
|
|
77
|
+
/>
|
|
78
|
+
|
|
79
|
+
<BaseText
|
|
80
|
+
bold
|
|
81
|
+
class="tracking-tight uppercase"
|
|
82
|
+
:size="size === 'lg' ? 'xs' : '2xs'"
|
|
83
|
+
:text="confirming ? t('confirm') : text"
|
|
84
|
+
/>
|
|
85
|
+
</span>
|
|
86
|
+
|
|
87
|
+
<BaseSpinner
|
|
88
|
+
v-if="loading"
|
|
89
|
+
class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
|
|
90
|
+
:color="color === 'green' || color === 'orange' || color === 'red' ? color : 'black'"
|
|
91
|
+
:size="size === 'sm' ? 'xs' : size === 'lg' ? 'base' : 'sm'"
|
|
92
|
+
/>
|
|
93
|
+
</button>
|
|
94
|
+
</template>
|
|
95
|
+
|
|
96
|
+
<i18n lang="json">
|
|
97
|
+
{
|
|
98
|
+
"de": {
|
|
99
|
+
"confirm": "Bestätigen?"
|
|
100
|
+
},
|
|
101
|
+
"en": {
|
|
102
|
+
"confirm": "Confirm?"
|
|
103
|
+
},
|
|
104
|
+
"es": {
|
|
105
|
+
"confirm": "¿Confirmar?"
|
|
106
|
+
},
|
|
107
|
+
"fr": {
|
|
108
|
+
"confirm": "Confirmer ?"
|
|
109
|
+
},
|
|
110
|
+
"id": {
|
|
111
|
+
"confirm": "Konfirmasi?"
|
|
112
|
+
},
|
|
113
|
+
"it": {
|
|
114
|
+
"confirm": "Confermare?"
|
|
115
|
+
},
|
|
116
|
+
"ja": {
|
|
117
|
+
"confirm": "確認しますか?"
|
|
118
|
+
},
|
|
119
|
+
"ko": {
|
|
120
|
+
"confirm": "확인할까요?"
|
|
121
|
+
},
|
|
122
|
+
"nl": {
|
|
123
|
+
"confirm": "Bevestigen?"
|
|
124
|
+
},
|
|
125
|
+
"pl": {
|
|
126
|
+
"confirm": "Potwierdzić?"
|
|
127
|
+
},
|
|
128
|
+
"pt": {
|
|
129
|
+
"confirm": "Confirmar?"
|
|
130
|
+
},
|
|
131
|
+
"pt-BR": {
|
|
132
|
+
"confirm": "Confirmar?"
|
|
133
|
+
},
|
|
134
|
+
"vi": {
|
|
135
|
+
"confirm": "Xác nhận?"
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
</i18n>
|
|
@@ -118,12 +118,9 @@ function onClick(event: MouseEvent) {
|
|
|
118
118
|
|
|
119
119
|
<BaseIcon
|
|
120
120
|
v-else-if="icon"
|
|
121
|
-
:class="{
|
|
122
|
-
'text-lg': size === 'base',
|
|
123
|
-
'text-2xl': size === 'lg',
|
|
124
|
-
}"
|
|
125
121
|
:color="color"
|
|
126
122
|
:icon="icon"
|
|
123
|
+
:size="size === 'lg' ? '2xl' : 'lg'"
|
|
127
124
|
/>
|
|
128
125
|
|
|
129
126
|
<img
|
|
@@ -193,22 +190,17 @@ function onClick(event: MouseEvent) {
|
|
|
193
190
|
'mr-1.5 self-center': orientation === 'horizontal',
|
|
194
191
|
'absolute right-2 top-2': orientation === 'vertical' && size === 'base',
|
|
195
192
|
'absolute right-2.5 top-2.5': orientation === 'vertical' && size === 'lg',
|
|
196
|
-
'text-xl': size === 'base',
|
|
197
|
-
'text-2xl': size === 'lg',
|
|
198
193
|
}"
|
|
199
194
|
color="green"
|
|
200
195
|
:icon="getLayerIcon('checkCircle')"
|
|
196
|
+
:size="size === 'lg' ? '2xl' : 'xl'"
|
|
201
197
|
/>
|
|
202
198
|
|
|
203
199
|
<BaseIcon
|
|
204
200
|
v-else-if="orientation === 'horizontal' && (to || hasChevron)"
|
|
205
|
-
class="self-center text-gray-500 flex-initial dark:text-gray-500"
|
|
206
|
-
:class="{
|
|
207
|
-
'group-hover:text-gray-900 dark:group-hover:text-gray-100': isClickable,
|
|
208
|
-
'text-xl': size === 'base',
|
|
209
|
-
'text-2xl': size === 'lg',
|
|
210
|
-
}"
|
|
201
|
+
class="self-center text-gray-500 flex-initial dark:text-gray-500 group-hover:text-gray-900 dark:group-hover:text-gray-100"
|
|
211
202
|
:icon="getLayerIcon('chevronRight')"
|
|
203
|
+
:size="size === 'lg' ? '2xl' : 'xl'"
|
|
212
204
|
/>
|
|
213
205
|
|
|
214
206
|
<slot name="right" />
|
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
import type { BaseEmoji } from '../../types/bases'
|
|
3
3
|
|
|
4
4
|
const props = withDefaults(defineProps<BaseEmoji>(), {
|
|
5
|
+
background: 'gray',
|
|
5
6
|
clickable: true,
|
|
6
7
|
emoji: undefined,
|
|
7
8
|
hasBox: false,
|
|
@@ -33,8 +34,11 @@ function onKeyDown(event: KeyboardEvent) {
|
|
|
33
34
|
<span
|
|
34
35
|
class="flex items-center justify-center transition"
|
|
35
36
|
:class="{
|
|
36
|
-
'border border-gray-200 dark:border-gray-800
|
|
37
|
-
'
|
|
37
|
+
'border border-gray-200 dark:border-gray-800': hasBox,
|
|
38
|
+
'bg-gray-100 dark:bg-gray-900 shadow-inner': hasBox && background === 'gray',
|
|
39
|
+
'bg-white dark:bg-gray-900 shadow-sm': hasBox && background === 'white',
|
|
40
|
+
'cursor-pointer hover:border-gray-400 dark:hover:border-gray-600': clickable && (!hasBox || background === 'gray'),
|
|
41
|
+
'cursor-pointer hover:border-gray-300 focus-visible:border-gray-400 dark:hover:border-gray-700 dark:focus-visible:border-gray-600': clickable && hasBox && background === 'white',
|
|
38
42
|
'rounded': ['xs'].includes(size) && hasBox,
|
|
39
43
|
'rounded-md': ['sm', 'base'].includes(size) && hasBox,
|
|
40
44
|
'rounded-lg': ['lg', 'xl'].includes(size) && hasBox,
|
|
@@ -78,6 +78,10 @@ const finalColor = computed(() => {
|
|
|
78
78
|
return statusColor.value || props.color
|
|
79
79
|
})
|
|
80
80
|
|
|
81
|
+
const shouldSizeIcon = computed(() => {
|
|
82
|
+
return !!props.text || props.size !== 'base'
|
|
83
|
+
})
|
|
84
|
+
|
|
81
85
|
function onClick(event: MouseEvent) {
|
|
82
86
|
if (props.confirmation) {
|
|
83
87
|
if (confirming.value) {
|
|
@@ -122,13 +126,23 @@ function onKeyDown(event: KeyboardEvent) {
|
|
|
122
126
|
v-if="finalIcon && !loading"
|
|
123
127
|
class="flex items-center justify-center"
|
|
124
128
|
:class="{
|
|
129
|
+
'text-2xl': shouldSizeIcon && size === '2xl',
|
|
130
|
+
'text-2xs': shouldSizeIcon && size === '2xs',
|
|
131
|
+
'text-3xl': shouldSizeIcon && size === '3xl',
|
|
132
|
+
'text-3xs': shouldSizeIcon && size === '3xs',
|
|
133
|
+
'text-4xl': shouldSizeIcon && size === '4xl',
|
|
134
|
+
'text-base': shouldSizeIcon && size === 'base',
|
|
135
|
+
'text-lg': shouldSizeIcon && size === 'lg',
|
|
136
|
+
'text-sm': shouldSizeIcon && size === 'sm',
|
|
137
|
+
'text-xl': shouldSizeIcon && size === 'xl',
|
|
138
|
+
'text-xs': shouldSizeIcon && size === 'xs',
|
|
139
|
+
'text-gray-100 dark:text-gray-900': finalColor === 'white',
|
|
140
|
+
'text-gray-600 dark:text-gray-400': finalColor === 'gray',
|
|
125
141
|
'text-gray-900 dark:text-gray-100': finalColor === 'black',
|
|
126
142
|
'text-green-600 dark:text-green-400': finalColor === 'green',
|
|
127
|
-
'text-gray-600 dark:text-gray-400': finalColor === 'gray',
|
|
128
143
|
'text-indigo-600 dark:text-indigo-400': finalColor === 'indigo',
|
|
129
144
|
'text-orange-600 dark:text-orange-400': finalColor === 'orange',
|
|
130
145
|
'text-red-600 dark:text-red-400': finalColor === 'red',
|
|
131
|
-
'text-gray-100 dark:text-gray-900': finalColor === 'white',
|
|
132
146
|
}"
|
|
133
147
|
:to="to"
|
|
134
148
|
>
|
|
@@ -37,11 +37,19 @@ function onClose(event: KeyboardEvent | MouseEvent) {
|
|
|
37
37
|
@keydown.enter="onClose"
|
|
38
38
|
@keydown.space.prevent="onClose"
|
|
39
39
|
>
|
|
40
|
-
<
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
40
|
+
<div class="pointer-events-none flex items-center flex-initial">
|
|
41
|
+
<BaseIcon
|
|
42
|
+
size="lg"
|
|
43
|
+
:status="status"
|
|
44
|
+
/>
|
|
45
|
+
|
|
46
|
+
<BaseText
|
|
47
|
+
class="ml-2"
|
|
48
|
+
no-wrap
|
|
49
|
+
size="base"
|
|
50
|
+
:text="text"
|
|
51
|
+
/>
|
|
52
|
+
</div>
|
|
45
53
|
|
|
46
54
|
<button
|
|
47
55
|
v-if="action"
|
|
@@ -73,7 +81,7 @@ function onClose(event: KeyboardEvent | MouseEvent) {
|
|
|
73
81
|
<div class="ml-2 mr-1.5 h-5 border-l border-gray-200 flex-initial dark:border-gray-700" />
|
|
74
82
|
|
|
75
83
|
<BaseIcon
|
|
76
|
-
class="text-
|
|
84
|
+
class="text-gray-400 transition-colors flex-initial dark:text-gray-500"
|
|
77
85
|
:class="{
|
|
78
86
|
'group-hover:text-red-600 dark:group-hover:text-red-400': status === 'error',
|
|
79
87
|
'group-hover:text-indigo-600 dark:group-hover:text-indigo-400': status === 'info',
|
|
@@ -81,6 +89,7 @@ function onClose(event: KeyboardEvent | MouseEvent) {
|
|
|
81
89
|
'group-hover:text-orange-600 dark:group-hover:text-orange-400': status === 'warning',
|
|
82
90
|
}"
|
|
83
91
|
:icon="getLayerIcon('close')"
|
|
92
|
+
size="lg"
|
|
84
93
|
/>
|
|
85
94
|
</template>
|
|
86
95
|
</div>
|
|
@@ -67,10 +67,12 @@ function onUpdateDays(event: MouseEvent, day: number) {
|
|
|
67
67
|
<BaseText
|
|
68
68
|
v-for="day in daysToDisplay"
|
|
69
69
|
:key="day.value"
|
|
70
|
-
class="mr-2 h-7 w-7 flex
|
|
70
|
+
class="mr-2 h-7 w-7 flex items-center justify-center border rounded-full shadow-inner transition-colors last:mr-0"
|
|
71
71
|
:class="{
|
|
72
72
|
'border-indigo-700 dark:border-indigo-300 bg-gray-100 dark:bg-gray-900 text-indigo-700 dark:text-indigo-300': modelValue.includes(day.value),
|
|
73
73
|
'border-red-700 dark:border-red-300 bg-red-100 dark:bg-red-900 text-red-700 dark:text-red-300': !modelValue.includes(day.value),
|
|
74
|
+
'cursor-pointer hover:border-indigo-800 hover:text-indigo-800 dark:hover:border-indigo-200 dark:hover:text-indigo-200': modelValue.includes(day.value) && !disabled,
|
|
75
|
+
'cursor-pointer hover:border-red-800 hover:text-red-800 dark:hover:border-red-200 dark:hover:text-red-200': !modelValue.includes(day.value) && !disabled,
|
|
74
76
|
}"
|
|
75
77
|
size="xs"
|
|
76
78
|
:text="day.label.charAt(0)"
|
|
@@ -24,6 +24,7 @@ const props = withDefaults(defineProps<Omit<FieldInput, 'modelValue'>>(), {
|
|
|
24
24
|
slugOnly: false,
|
|
25
25
|
trim: false,
|
|
26
26
|
type: 'text',
|
|
27
|
+
uppercase: true,
|
|
27
28
|
validation: undefined,
|
|
28
29
|
})
|
|
29
30
|
|
|
@@ -178,8 +179,9 @@ defineExpose({ focus })
|
|
|
178
179
|
:id="id"
|
|
179
180
|
ref="input"
|
|
180
181
|
:autocomplete="autocomplete ? 'on' : 'off'"
|
|
181
|
-
class="h-full w-full appearance-none items-center rounded-lg font-medium tracking-tight
|
|
182
|
+
class="h-full w-full appearance-none items-center rounded-lg font-medium tracking-tight outline-none placeholder-gray-600 dark:placeholder-gray-400"
|
|
182
183
|
:class="{
|
|
184
|
+
'uppercase': uppercase,
|
|
183
185
|
'field-disabled': disabled,
|
|
184
186
|
'focus:placeholder-gray-900 hover:placeholder-gray-900 dark:focus:placeholder-gray-100 dark:hover:placeholder-gray-100': !disabled,
|
|
185
187
|
'text-gray-900 dark:text-gray-100': !lineThrough,
|
|
@@ -18,6 +18,7 @@ const props = withDefaults(defineProps<Omit<FieldTextarea, 'modelValue'>>(), {
|
|
|
18
18
|
resize: false,
|
|
19
19
|
rows: 3,
|
|
20
20
|
size: 'base',
|
|
21
|
+
uppercase: true,
|
|
21
22
|
validation: undefined,
|
|
22
23
|
})
|
|
23
24
|
|
|
@@ -67,8 +68,9 @@ function onFieldClick(event: MouseEvent) {
|
|
|
67
68
|
ref="textarea"
|
|
68
69
|
v-model="modelValue"
|
|
69
70
|
v-bind="{ 'data-enable-grammarly': 'false' }"
|
|
70
|
-
class="w-full flex-1 appearance-none rounded-lg text-gray-900 font-medium tracking-tight
|
|
71
|
+
class="w-full flex-1 appearance-none rounded-lg text-gray-900 font-medium tracking-tight outline-none dark:text-gray-100 placeholder-gray-600 dark:placeholder-gray-400"
|
|
71
72
|
:class="{
|
|
73
|
+
'uppercase': uppercase,
|
|
72
74
|
'field-disabled': disabled,
|
|
73
75
|
'focus:placeholder-gray-900 hover:placeholder-gray-900 dark:focus:placeholder-gray-100 dark:hover:placeholder-gray-100': !disabled,
|
|
74
76
|
'p-2.5': padding,
|
|
@@ -242,7 +242,7 @@ watch(visible, (isVisible) => {
|
|
|
242
242
|
|
|
243
243
|
<div
|
|
244
244
|
ref="contentRef"
|
|
245
|
-
class="min-h-0 flex-1
|
|
245
|
+
class="scroll-y-stable min-h-0 flex-1 px-6 pt-2 md:px-8"
|
|
246
246
|
:class="{
|
|
247
247
|
'pb-4': $slots.footer,
|
|
248
248
|
'pb-6': !($slots.footer),
|
|
@@ -52,7 +52,7 @@ function onClose() {
|
|
|
52
52
|
ref="panelRef"
|
|
53
53
|
:aria-label="title"
|
|
54
54
|
aria-modal="true"
|
|
55
|
-
class="pointer-events-auto max-h-[85dvh] max-w-md w-full
|
|
55
|
+
class="scroll-y-stable pointer-events-auto max-h-[85dvh] max-w-md w-full rounded-2xl bg-white p-5 text-gray-900 app-text shadow-lg outline-none dark:bg-gray-900 dark:text-gray-100"
|
|
56
56
|
role="dialog"
|
|
57
57
|
tabindex="-1"
|
|
58
58
|
>
|
package/app/types/bases.d.ts
CHANGED
|
@@ -1,4 +1,18 @@
|
|
|
1
1
|
// Components
|
|
2
|
+
export interface BaseAction {
|
|
3
|
+
active?: boolean
|
|
4
|
+
color?: BaseColor
|
|
5
|
+
confirmation?: boolean
|
|
6
|
+
disabled?: boolean
|
|
7
|
+
icon?: string
|
|
8
|
+
loading?: boolean
|
|
9
|
+
size?: BaseSize
|
|
10
|
+
text?: BaseTextText
|
|
11
|
+
variant?: BaseActionVariant
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export type BaseActionVariant = 'filled' | 'outline'
|
|
15
|
+
|
|
2
16
|
export interface BaseAlert {
|
|
3
17
|
closingId?: string
|
|
4
18
|
isClosable?: boolean
|
|
@@ -151,6 +165,7 @@ export type BaseDividerNavigateDirection = 'next' | 'previous'
|
|
|
151
165
|
export type BaseDividerSize = 'base' | 'sm'
|
|
152
166
|
|
|
153
167
|
export interface BaseEmoji {
|
|
168
|
+
background?: BaseBackground
|
|
154
169
|
clickable?: boolean
|
|
155
170
|
emoji?: string
|
|
156
171
|
hasBox?: boolean
|
package/app/types/fields.d.ts
CHANGED
|
@@ -71,6 +71,7 @@ export interface FieldInput {
|
|
|
71
71
|
slugOnly?: boolean
|
|
72
72
|
trim?: boolean
|
|
73
73
|
type?: FieldInputType
|
|
74
|
+
uppercase?: boolean
|
|
74
75
|
validation?: VuelidateValidation
|
|
75
76
|
}
|
|
76
77
|
|
|
@@ -204,6 +205,7 @@ export interface FieldTextarea {
|
|
|
204
205
|
resize?: boolean
|
|
205
206
|
rows?: number
|
|
206
207
|
size?: FieldSize
|
|
208
|
+
uppercase?: boolean
|
|
207
209
|
validation?: VuelidateValidation
|
|
208
210
|
}
|
|
209
211
|
|
package/app/types/global.d.ts
CHANGED
|
@@ -9,6 +9,8 @@ declare global {
|
|
|
9
9
|
type AuthSocialConnectSuccess = import('./auth').AuthSocialConnectSuccess
|
|
10
10
|
|
|
11
11
|
// Bases
|
|
12
|
+
type BaseAction = import('./bases').BaseAction
|
|
13
|
+
type BaseActionVariant = import('./bases').BaseActionVariant
|
|
12
14
|
type BaseAlert = import('./bases').BaseAlert
|
|
13
15
|
type BaseAlignment = import('./bases').BaseAlignment
|
|
14
16
|
type BaseAvatar = import('./bases').BaseAvatar
|
package/package.json
CHANGED
package/uno.config.ts
CHANGED
|
@@ -27,6 +27,7 @@ export const rules: [string, Record<string, string>][] = [
|
|
|
27
27
|
export const shortcuts: Record<string, string> = {
|
|
28
28
|
'app-text': 'font-bold leading-relaxed tracking-tight uppercase',
|
|
29
29
|
'field-disabled': 'opacity-50 cursor-not-allowed',
|
|
30
|
+
'scroll-y-stable': 'overflow-y-auto [scrollbar-gutter:stable]',
|
|
30
31
|
}
|
|
31
32
|
|
|
32
33
|
export const theme = {
|