@saasmakers/ui 2.0.61 → 2.0.63

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.
@@ -4,6 +4,16 @@ html,
4
4
  body {
5
5
  scrollbar-gutter: stable;
6
6
  touch-action: manipulation;
7
+ -webkit-touch-callout: none;
8
+ -webkit-user-select: none;
9
+ user-select: none;
10
+ }
11
+
12
+ input,
13
+ textarea,
14
+ [contenteditable='true'] {
15
+ -webkit-user-select: text;
16
+ user-select: text;
7
17
  }
8
18
 
9
19
  /* Theme backgrounds */
@@ -215,6 +215,7 @@ function resetTurnstile() {
215
215
  full-width
216
216
  :loading="forgettingPassword"
217
217
  reverse
218
+ :size="size"
218
219
  :text="{
219
220
  sm: t('buttons.forgotPassword.sm'),
220
221
  base: t('buttons.forgotPassword.base'),
@@ -141,14 +141,23 @@ function processGoogleCallback(event: MessageEvent) {
141
141
  <img
142
142
  v-if="provider === 'apple'"
143
143
  :alt="t('appleLogo')"
144
- class="mr-2.5 w-4.5 dark:invert"
144
+ class="dark:invert"
145
+ :class="{
146
+ 'mr-2 w-4': size === 'xs' || size === 'sm',
147
+ 'mr-2.5 w-4.5': size === 'base',
148
+ 'mr-2.5 w-5': size === 'lg',
149
+ }"
145
150
  src="/images/auth/AuthSocialConnect/apple.svg"
146
151
  >
147
152
 
148
153
  <img
149
154
  v-else-if="provider === 'google'"
150
155
  :alt="t('googleLogo')"
151
- class="mr-2.5 w-5"
156
+ :class="{
157
+ 'mr-2 w-4': size === 'xs' || size === 'sm',
158
+ 'mr-2.5 w-4.5': size === 'base',
159
+ 'mr-2.5 w-5': size === 'lg',
160
+ }"
152
161
  src="/images/auth/AuthSocialConnect/google.svg"
153
162
  >
154
163
  </BaseButton>
@@ -37,6 +37,23 @@ const hasFixedSize = computed(() => {
37
37
  return props.shape === 'square' || props.shape === 'circle'
38
38
  })
39
39
 
40
+ const contentSize = computed((): BaseSize => {
41
+ switch (props.size) {
42
+ case 'lg': {
43
+ return 'base'
44
+ }
45
+ case 'sm': {
46
+ return 'xs'
47
+ }
48
+ case 'xs': {
49
+ return '2xs'
50
+ }
51
+ default: {
52
+ return 'sm'
53
+ }
54
+ }
55
+ })
56
+
40
57
  function onClick(event: MouseEvent) {
41
58
  if (!props.loading) {
42
59
  if (props.confirmation) {
@@ -69,12 +86,10 @@ function onClick(event: MouseEvent) {
69
86
  'shadow-sm': !light,
70
87
  'rounded-lg': shape !== 'circle',
71
88
  'rounded-full': shape === 'circle',
72
- 'h-6 w-6': size === '2xs' && hasFixedSize,
73
89
  'h-8 w-8': size === 'xs' && hasFixedSize && !confirming,
74
90
  'h-10 w-10': size === 'sm' && hasFixedSize && !confirming,
75
91
  'h-12 w-12': size === 'base' && hasFixedSize && !confirming,
76
92
  'h-14 w-14': size === 'lg' && hasFixedSize && !confirming,
77
- 'h-16 w-16': size === 'xl' && hasFixedSize && !confirming,
78
93
  'border-gray-900 dark:border-gray-100 bg-gray-900 dark:bg-gray-100 text-white dark:text-black': color === 'black' && !light,
79
94
  'hover:bg-black dark:hover:bg-white hover:text-white dark:hover:text-black': color === 'black' && !light && !disabled && !loading,
80
95
  'border-gray-900 dark:border-gray-100 text-gray-900 dark:text-gray-100': color === 'black' && light,
@@ -98,12 +113,10 @@ function onClick(event: MouseEvent) {
98
113
  'border-white dark:border-gray-900 text-white dark:text-black': color === 'white' && light,
99
114
  'hover:border-black dark:hover:border-white hover:text-black dark:hover:text-white': color !== 'white' && light && !disabled && !loading,
100
115
  'hover:bg-white dark:hover:bg-gray-900 hover:text-gray-800 dark:hover:text-gray-200': color === 'white' && light && !disabled && !loading,
101
- 'h-6 px-3': size === '2xs' && (!hasFixedSize || confirming),
102
116
  'h-8 px-4': size === 'xs' && (!hasFixedSize || confirming),
103
117
  'h-10 px-5': size === 'sm' && (!hasFixedSize || confirming),
104
118
  'h-12 px-6': size === 'base' && (!hasFixedSize || confirming),
105
- 'h-13 px-6.5': size === 'lg' && (!hasFixedSize || confirming),
106
- 'h-14 px-7': size === 'xl' && (!hasFixedSize || confirming),
119
+ 'h-14 px-6.5': size === 'lg' && (!hasFixedSize || confirming),
107
120
  }"
108
121
  :disabled="disabled"
109
122
  :to="to"
@@ -121,7 +134,7 @@ function onClick(event: MouseEvent) {
121
134
  :color="iconColor"
122
135
  :icon="confirming ? undefined : icon"
123
136
  :reverse="reverse"
124
- :size="size"
137
+ :size="contentSize"
125
138
  :text="confirming ? t('confirm') : text"
126
139
  />
127
140
  </span>
@@ -130,7 +143,7 @@ function onClick(event: MouseEvent) {
130
143
  v-if="loading"
131
144
  class="absolute left-1/2 top-1/2 -translate-x-1/2 -translate-y-1/2"
132
145
  :color="!background ? 'black' : light ? color : color === 'white' ? 'indigo' : 'white'"
133
- :size="size"
146
+ :size="contentSize"
134
147
  />
135
148
  </component>
136
149
  </template>
@@ -67,6 +67,8 @@ function focus() {
67
67
  }
68
68
 
69
69
  function onFieldBlur(event: FocusEvent) {
70
+ syncModelValueFromTarget(event.target)
71
+
70
72
  if (props.trim) {
71
73
  modelValue.value = modelValue.value.toString().trim()
72
74
  }
@@ -79,23 +81,12 @@ function onFieldFocus(event: FocusEvent) {
79
81
  }
80
82
 
81
83
  function onFieldInput(event: Event) {
82
- let value = (event.target as HTMLInputElement).value
83
-
84
- if (props.type === 'number' && props.max && Number.parseInt(value) > props.max) {
85
- value = props.max.toString()
86
- }
87
-
88
- if (props.slugOnly) {
89
- value = value.toString().toLowerCase().replace(/[^a-z0-9_-]/g, '')
90
- }
91
- else if (props.lowercaseOnly) {
92
- value = value.toString().toLowerCase()
93
- }
94
-
95
- modelValue.value = value
84
+ syncModelValueFromTarget(event.target)
96
85
  }
97
86
 
98
87
  function onFieldKeyDown(event: KeyboardEvent) {
88
+ syncModelValueFromTarget(event.target)
89
+
99
90
  const value = (event.target as HTMLInputElement).value
100
91
 
101
92
  if (['Control', 'Escape'].includes(event.key)) {
@@ -138,6 +129,27 @@ function onTogglePasswordVisibility() {
138
129
  showPassword.value = !showPassword.value
139
130
  }
140
131
 
132
+ function syncModelValueFromTarget(target: EventTarget | null) {
133
+ if (!(target instanceof HTMLInputElement)) {
134
+ return
135
+ }
136
+
137
+ let value = target.value
138
+
139
+ if (props.type === 'number' && props.max && Number.parseInt(value) > props.max) {
140
+ value = props.max.toString()
141
+ }
142
+
143
+ if (props.slugOnly) {
144
+ value = value.toString().toLowerCase().replace(/[^a-z0-9_-]/g, '')
145
+ }
146
+ else if (props.lowercaseOnly) {
147
+ value = value.toString().toLowerCase()
148
+ }
149
+
150
+ modelValue.value = value
151
+ }
152
+
141
153
  defineExpose({
142
154
  blur,
143
155
  focus,
@@ -39,12 +39,21 @@ onMounted(() => {
39
39
  })
40
40
 
41
41
  function onFieldBlur(event: FocusEvent) {
42
+ syncModelValueFromTarget(event.target)
42
43
  emit('blur', event, modelValue.value || '')
43
44
  }
44
45
 
45
46
  function onFieldClick(event: MouseEvent) {
46
47
  emit('click', event, modelValue.value || '')
47
48
  }
49
+
50
+ function syncModelValueFromTarget(target: EventTarget | null) {
51
+ if (!(target instanceof HTMLTextAreaElement)) {
52
+ return
53
+ }
54
+
55
+ modelValue.value = target.value
56
+ }
48
57
  </script>
49
58
 
50
59
  <template>
@@ -1,10 +1,21 @@
1
1
  export default function useDevice() {
2
+ const { isNative } = useCapacitor()
3
+
2
4
  const isDesktopBrowser = computed(() => {
3
5
  if (typeof navigator === 'undefined') {
4
6
  return true
5
7
  }
6
8
 
7
- return !navigator.userAgentData?.mobile
9
+ if (isNative.value) {
10
+ return false
11
+ }
12
+
13
+ // Chromium Client Hints — unavailable on Safari / Firefox / iOS WebKit
14
+ if (navigator.userAgentData) {
15
+ return !navigator.userAgentData.mobile
16
+ }
17
+
18
+ return !/Android|iPad|iPhone|iPod|Mobile/i.test(navigator.userAgent)
8
19
  })
9
20
 
10
21
  return { isDesktopBrowser }
@@ -71,11 +71,9 @@ export interface BaseButton {
71
71
  export type BaseButtonShape = 'circle' | 'default' | 'square'
72
72
 
73
73
  export type BaseButtonSize
74
- = | '2xs'
75
- | 'base'
74
+ = | 'base'
76
75
  | 'lg'
77
76
  | 'sm'
78
- | 'xl'
79
77
  | 'xs'
80
78
 
81
79
  export type BaseButtonType = 'button' | 'reset' | 'submit'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@saasmakers/ui",
3
- "version": "2.0.61",
3
+ "version": "2.0.63",
4
4
  "private": false,
5
5
  "description": "Reusable Nuxt UI components for SaaS Makers projects",
6
6
  "license": "MIT",