@alikhalilll/ui 1.0.0 → 1.1.1
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/README.md +155 -187
- package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs +108 -0
- package/dist/chunks/ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs.map +1 -0
- package/dist/chunks/AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs +81 -0
- package/dist/chunks/AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs.map +1 -0
- package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs +132 -0
- package/dist/chunks/APopoverContent.vue_vue_type_script_setup_true_lang-o1XhV9DM.mjs.map +1 -0
- package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs +92 -0
- package/dist/chunks/AResponsivePopoverContent.vue_vue_type_script_setup_true_lang-BYEb5UBL.mjs.map +1 -0
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs +1353 -0
- package/dist/chunks/ATellInput.vue_vue_type_script_setup_true_lang-Clc-B8SW.mjs.map +1 -0
- package/dist/chunks/cn-B6yFEsav.mjs +9 -0
- package/dist/chunks/cn-B6yFEsav.mjs.map +1 -0
- package/dist/chunks/sizes-B_9MfLkz.mjs +34 -0
- package/dist/chunks/sizes-B_9MfLkz.mjs.map +1 -0
- package/dist/drawer.d.ts +116 -0
- package/dist/drawer.mjs +8 -0
- package/dist/drawer.mjs.map +1 -0
- package/dist/index.d.ts +84 -57
- package/dist/index.mjs +35 -1516
- package/dist/index.mjs.map +1 -1
- package/dist/input.d.ts +65 -0
- package/dist/input.mjs +5 -0
- package/dist/input.mjs.map +1 -0
- package/dist/popover.d.ts +117 -0
- package/dist/popover.mjs +8 -0
- package/dist/popover.mjs.map +1 -0
- package/dist/responsive-popover.d.ts +124 -0
- package/dist/responsive-popover.mjs +7 -0
- package/dist/responsive-popover.mjs.map +1 -0
- package/dist/tell-input.d.ts +637 -0
- package/dist/tell-input.mjs +13 -0
- package/dist/tell-input.mjs.map +1 -0
- package/dist/utils.d.ts +29 -0
- package/dist/utils.mjs +12 -0
- package/dist/utils.mjs.map +1 -0
- package/entries/drawer/README.md +39 -0
- package/entries/input/README.md +42 -0
- package/entries/popover/README.md +37 -0
- package/entries/responsive-popover/README.md +47 -0
- package/entries/tell-input/README.md +52 -0
- package/package.json +30 -4
- /package/dist/{styles.css → assets/styles.css} +0 -0
package/README.md
CHANGED
|
@@ -1,13 +1,29 @@
|
|
|
1
1
|
# @alikhalilll/ui
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://www.npmjs.com/package/@alikhalilll/ui)
|
|
4
|
+
[](https://www.npmjs.com/package/@alikhalilll/ui)
|
|
5
|
+
[](https://bundlephobia.com/package/@alikhalilll/ui)
|
|
6
|
+
[](./LICENSE)
|
|
4
7
|
|
|
5
|
-
|
|
8
|
+
Headless, shadcn-vue style Vue 3 component library — every component lives behind its own subpath import so consumers only ship the components they actually use. Built on [reka-ui](https://reka-ui.com) and [vaul-vue](https://github.com/unovue/vaul-vue), themed via prefixed CSS variables, fully typed.
|
|
6
9
|
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
10
|
+
📚 **Live docs:** <https://alikhalilll.github.io/ali-nuxt-toolkit/ui>
|
|
11
|
+
📦 **npm:** <https://www.npmjs.com/package/@alikhalilll/ui>
|
|
12
|
+
🐙 **Source:** <https://github.com/alikhalilll/ali-nuxt-toolkit/tree/master/packages/ui>
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## Components
|
|
17
|
+
|
|
18
|
+
| Component | Subpath | Per-component README | Live docs |
|
|
19
|
+
| -------------------- | ------------------------------------ | -------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
|
|
20
|
+
| `ATellInput` | `@alikhalilll/ui/tell-input` | [./entries/tell-input/README.md](./entries/tell-input/README.md) | [/ui/tell-input](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/tell-input) |
|
|
21
|
+
| `AInput` | `@alikhalilll/ui/input` | [./entries/input/README.md](./entries/input/README.md) | [/ui/input](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/input) |
|
|
22
|
+
| `APopover` | `@alikhalilll/ui/popover` | [./entries/popover/README.md](./entries/popover/README.md) | [/ui/popover](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/popover) |
|
|
23
|
+
| `ADrawer` | `@alikhalilll/ui/drawer` | [./entries/drawer/README.md](./entries/drawer/README.md) | [/ui/drawer](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/drawer) |
|
|
24
|
+
| `AResponsivePopover` | `@alikhalilll/ui/responsive-popover` | [./entries/responsive-popover/README.md](./entries/responsive-popover/README.md) | [/ui/responsive-popover](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/responsive-popover) |
|
|
25
|
+
|
|
26
|
+
Each README ships inside the npm tarball at `node_modules/@alikhalilll/ui/entries/<name>/README.md` and is rendered on the file browser at <https://www.npmjs.com/package/@alikhalilll/ui?activeTab=code>.
|
|
11
27
|
|
|
12
28
|
## Install
|
|
13
29
|
|
|
@@ -15,113 +31,164 @@ The first component shipped is **`ATellInput`** — a phone-number input that:
|
|
|
15
31
|
pnpm add @alikhalilll/ui
|
|
16
32
|
```
|
|
17
33
|
|
|
18
|
-
Peer dependency: `vue ^3.5.0`.
|
|
34
|
+
Peer dependency: `vue ^3.5.0`. Bundled deps: `reka-ui`, `vaul-vue`, `libphonenumber-js`, `lucide-vue-next`, `@vueuse/core`, `class-variance-authority`, `clsx`, `tailwind-merge`.
|
|
35
|
+
|
|
36
|
+
### Subpath imports (recommended)
|
|
37
|
+
|
|
38
|
+
```ts
|
|
39
|
+
// Only the tell-input chunk ships into the bundle.
|
|
40
|
+
import { ATellInput } from '@alikhalilll/ui/tell-input';
|
|
41
|
+
|
|
42
|
+
// Main entry — bundlers still tree-shake unused exports via `sideEffects`.
|
|
43
|
+
import { ATellInput, APopover } from '@alikhalilll/ui';
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
Available subpaths: `/tell-input`, `/input`, `/popover`, `/drawer`, `/responsive-popover`, `/utils`.
|
|
19
47
|
|
|
20
48
|
## Setup
|
|
21
49
|
|
|
22
|
-
|
|
50
|
+
Components style themselves with Tailwind utility classes (`bg-popover`, `text-muted-foreground`, …) resolving to CSS variables shipped at `@alikhalilll/ui/styles.css`. Three steps:
|
|
23
51
|
|
|
24
|
-
1.
|
|
52
|
+
### 1. Import the tokens
|
|
25
53
|
|
|
26
|
-
|
|
27
|
-
// In a Nuxt config or your main entry
|
|
28
|
-
import '@alikhalilll/ui/styles.css';
|
|
29
|
-
```
|
|
54
|
+
**Nuxt 3 / 4:**
|
|
30
55
|
|
|
31
|
-
|
|
56
|
+
```ts
|
|
57
|
+
// nuxt.config.ts
|
|
58
|
+
export default defineNuxtConfig({
|
|
59
|
+
css: ['@alikhalilll/ui/styles.css'],
|
|
60
|
+
});
|
|
61
|
+
```
|
|
32
62
|
|
|
33
|
-
|
|
34
|
-
@import 'tailwindcss';
|
|
35
|
-
@import '@alikhalilll/ui/styles.css';
|
|
63
|
+
**Vue + Vite (no Nuxt):**
|
|
36
64
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
--color-muted-foreground: hsl(var(--ak-ui-muted-foreground));
|
|
46
|
-
--color-accent: hsl(var(--ak-ui-accent));
|
|
47
|
-
--color-accent-foreground: hsl(var(--ak-ui-accent-foreground));
|
|
48
|
-
--color-destructive: hsl(var(--ak-ui-destructive));
|
|
49
|
-
--color-destructive-foreground: hsl(var(--ak-ui-destructive-foreground));
|
|
50
|
-
--color-border: hsl(var(--ak-ui-border));
|
|
51
|
-
--color-input: hsl(var(--ak-ui-input));
|
|
52
|
-
--color-ring: hsl(var(--ak-ui-ring));
|
|
53
|
-
}
|
|
54
|
-
```
|
|
65
|
+
```ts
|
|
66
|
+
// main.ts
|
|
67
|
+
import { createApp } from 'vue';
|
|
68
|
+
import App from './App.vue';
|
|
69
|
+
import '@alikhalilll/ui/styles.css';
|
|
70
|
+
|
|
71
|
+
createApp(App).mount('#app');
|
|
72
|
+
```
|
|
55
73
|
|
|
56
|
-
|
|
74
|
+
Every variable is prefixed `--ak-ui-` — guaranteed not to collide with your own CSS.
|
|
75
|
+
|
|
76
|
+
### 2. Map to Tailwind v4
|
|
77
|
+
|
|
78
|
+
```css
|
|
79
|
+
@import 'tailwindcss';
|
|
80
|
+
@import '@alikhalilll/ui/styles.css';
|
|
81
|
+
@source '../node_modules/@alikhalilll/ui/dist/index.mjs';
|
|
82
|
+
|
|
83
|
+
@theme inline {
|
|
84
|
+
--color-background: hsl(var(--ak-ui-background));
|
|
85
|
+
--color-foreground: hsl(var(--ak-ui-foreground));
|
|
86
|
+
--color-popover: hsl(var(--ak-ui-popover));
|
|
87
|
+
--color-popover-foreground: hsl(var(--ak-ui-popover-foreground));
|
|
88
|
+
--color-muted: hsl(var(--ak-ui-muted));
|
|
89
|
+
--color-muted-foreground: hsl(var(--ak-ui-muted-foreground));
|
|
90
|
+
--color-accent: hsl(var(--ak-ui-accent));
|
|
91
|
+
--color-accent-foreground: hsl(var(--ak-ui-accent-foreground));
|
|
92
|
+
--color-destructive: hsl(var(--ak-ui-destructive));
|
|
93
|
+
--color-destructive-foreground: hsl(var(--ak-ui-destructive-foreground));
|
|
94
|
+
--color-border: hsl(var(--ak-ui-border));
|
|
95
|
+
--color-input: hsl(var(--ak-ui-input));
|
|
96
|
+
--color-ring: hsl(var(--ak-ui-ring));
|
|
97
|
+
}
|
|
98
|
+
```
|
|
57
99
|
|
|
58
|
-
|
|
100
|
+
`@source` tells Tailwind v4 to scan the lib's compiled templates — it skips `node_modules` by default. Inside a pnpm workspace, point at the source so HMR works:
|
|
59
101
|
|
|
60
|
-
|
|
102
|
+
```css
|
|
103
|
+
@source '../../packages/ui/index.ts';
|
|
104
|
+
@source '../../packages/ui/entries/**/*.{vue,ts}';
|
|
105
|
+
@source '../../packages/ui/utils/**/*.ts';
|
|
106
|
+
```
|
|
61
107
|
|
|
62
|
-
|
|
63
|
-
// Locked dark
|
|
64
|
-
export default defineNuxtConfig({
|
|
65
|
-
app: { head: { htmlAttrs: { class: 'dark' } } },
|
|
66
|
-
});
|
|
67
|
-
```
|
|
108
|
+
### 3. Dark mode
|
|
68
109
|
|
|
69
|
-
|
|
110
|
+
The lib ships both `.light` and `.dark` blocks. Toggle the class on `<html>` — portaled popovers and drawers inherit via the cascade.
|
|
70
111
|
|
|
71
|
-
|
|
112
|
+
**Nuxt 3 / 4 — locked dark:**
|
|
113
|
+
|
|
114
|
+
```ts
|
|
115
|
+
// nuxt.config.ts
|
|
116
|
+
export default defineNuxtConfig({
|
|
117
|
+
app: { head: { htmlAttrs: { class: 'dark' } } },
|
|
118
|
+
});
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
**Vue + Vite — locked dark:**
|
|
122
|
+
|
|
123
|
+
```html
|
|
124
|
+
<!-- index.html -->
|
|
125
|
+
<html class="dark">
|
|
126
|
+
...
|
|
127
|
+
</html>
|
|
128
|
+
```
|
|
129
|
+
|
|
130
|
+
For Light / Dark / System (persisted, OS-aware, no flash of wrong theme), see [`apps/docs/composables/useColorMode.ts`](https://github.com/alikhalilll/ali-nuxt-toolkit/blob/master/apps/docs/composables/useColorMode.ts) — the pattern is framework-agnostic.
|
|
131
|
+
|
|
132
|
+
## Quick start
|
|
72
133
|
|
|
73
134
|
```vue
|
|
74
135
|
<script setup lang="ts">
|
|
75
136
|
import { ref } from 'vue';
|
|
76
|
-
import { ATellInput } from '@alikhalilll/ui';
|
|
137
|
+
import { ATellInput } from '@alikhalilll/ui/tell-input';
|
|
77
138
|
|
|
78
139
|
const phone = ref('');
|
|
79
|
-
const country = ref(
|
|
140
|
+
const country = ref<number | null>(null); // dial number, e.g. 20 for Egypt
|
|
80
141
|
</script>
|
|
81
142
|
|
|
82
143
|
<template>
|
|
83
|
-
<ATellInput
|
|
84
|
-
v-model:phone="phone"
|
|
85
|
-
v-model:country="country"
|
|
86
|
-
default-country="SA"
|
|
87
|
-
show-validation
|
|
88
|
-
/>
|
|
144
|
+
<ATellInput v-model:phone="phone" v-model:country="country" show-validation />
|
|
89
145
|
</template>
|
|
90
146
|
```
|
|
91
147
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
| `disabled` | `boolean` | `false` | |
|
|
100
|
-
| `loading` | `boolean` | `false` | Disables interaction. |
|
|
101
|
-
| `size` | `'sm' \| 'default' \| 'lg'` | `'default'` | Controls input height (32 / 36 / 40 px). |
|
|
102
|
-
| `allowedDialCodes` | `string[]` | _all_ | Whitelist of dial-digit codes (no `+`). Countries outside the list are shown but disabled. |
|
|
103
|
-
| `showValidation` | `boolean` | `false` | Renders an error message below the input when invalid. |
|
|
104
|
-
| `detectCountry` | `'auto' \| 'locale' \| 'none'` | `'auto'` | Country auto-detect strategy. |
|
|
105
|
-
| `defaultCountry` | `string` | `'US'` | Fallback ISO2 when detection fails or is disabled. |
|
|
106
|
-
| `ipEndpoint` | `string` | `'https://ipapi.co/json/'` | Override the geolocation endpoint. Must return JSON with `country_code` or `country`. |
|
|
107
|
-
| `searchPlaceholder` | `string` | `'Search by country or code…'` | Country picker search input placeholder. |
|
|
108
|
-
| `emptyText` | `string` | `'No countries found.'` | Shown when the search yields no results. |
|
|
109
|
-
| `loadingText` | `string` | `'Loading…'` | Shown while the country list is loading. |
|
|
110
|
-
| `errorMessages` | `Partial<Record<PhoneValidationReason, string>>` | English defaults | Override the validation error labels. |
|
|
111
|
-
| `class` | `string \| any[] \| Record<string, boolean>` | — | Merged into the outer wrapper via `tailwind-merge`. |
|
|
112
|
-
|
|
113
|
-
### Exposed (via template ref)
|
|
148
|
+
The picker stays hidden until the user types or pastes something that matches a known dial code, then slides in pre-filled and `phone` is normalised to the national significant number (`01066105963` → `1066105963`, `+447911123456` → `7911123456`).
|
|
149
|
+
|
|
150
|
+
Full props, slots, theming recipes, and live demos → [tell-input docs](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/tell-input) or [./entries/tell-input/README.md](./entries/tell-input/README.md).
|
|
151
|
+
|
|
152
|
+
## Nuxt integration
|
|
153
|
+
|
|
154
|
+
`@alikhalilll/ui` is a plain Vue 3 library — works in Nuxt 3 / 4 without a module wrapper. Full guide (auto-imports, SSR behaviour, source globs) on the [docs site](https://alikhalilll.github.io/ali-nuxt-toolkit/ui#nuxt-integration).
|
|
114
155
|
|
|
115
156
|
```ts
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
157
|
+
// nuxt.config.ts — optional auto-import
|
|
158
|
+
export default defineNuxtConfig({
|
|
159
|
+
components: [{ path: '@alikhalilll/ui', pathPrefix: false, global: true }],
|
|
160
|
+
});
|
|
120
161
|
```
|
|
121
162
|
|
|
122
|
-
##
|
|
163
|
+
## Theming
|
|
123
164
|
|
|
124
|
-
|
|
165
|
+
Override any `--ak-ui-*` variable globally, per wrapper, or inline:
|
|
166
|
+
|
|
167
|
+
```css
|
|
168
|
+
.tenant-acme {
|
|
169
|
+
--ak-ui-popover: 220 70% 8%;
|
|
170
|
+
--ak-ui-accent: 220 50% 30%;
|
|
171
|
+
--ak-ui-ring: 220 100% 65%;
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Values are HSL **triplets** — no `hsl(…)` wrapper. Full token list + recipes (brand-only, day/night, multi-tenant, server-driven, state-specific) → [theming guide](https://alikhalilll.github.io/ali-nuxt-toolkit/ui#theming).
|
|
176
|
+
|
|
177
|
+
## Size scale
|
|
178
|
+
|
|
179
|
+
| Token | Height | Tailwind |
|
|
180
|
+
| ----- | ------------------- | ---------- |
|
|
181
|
+
| `xs` | 28 px | `h-7` |
|
|
182
|
+
| `sm` | 36 px | `h-9` |
|
|
183
|
+
| `md` | **43 px (default)** | `h-[43px]` |
|
|
184
|
+
| `lg` | 52 px | `h-[52px]` |
|
|
185
|
+
| `xl` | 60 px | `h-[60px]` |
|
|
186
|
+
|
|
187
|
+
`controlHeight`, `controlPaddingX`, `controlTextSize`, `controlHeightPx`, `SIZES`, `DEFAULT_SIZE`, and the `Size` type are exported so you can build size-aware components in lockstep with the library.
|
|
188
|
+
|
|
189
|
+
## Compose your own variant
|
|
190
|
+
|
|
191
|
+
Every primitive, composable, and helper is re-exported — fork-free composition:
|
|
125
192
|
|
|
126
193
|
```ts
|
|
127
194
|
import {
|
|
@@ -149,102 +216,13 @@ import {
|
|
|
149
216
|
ACountryFlag,
|
|
150
217
|
aTellInputVariants,
|
|
151
218
|
DEFAULT_ERROR_MESSAGES,
|
|
219
|
+
defaultFlagUrl,
|
|
152
220
|
|
|
153
|
-
//
|
|
221
|
+
// Helpers
|
|
154
222
|
cn,
|
|
155
223
|
} from '@alikhalilll/ui';
|
|
156
|
-
|
|
157
|
-
// Build your own tel input from the same composables
|
|
158
|
-
const { validate, getCountries, searchCountries } = usePhoneValidation();
|
|
159
|
-
const detected = await detectCountry({ strategy: 'auto' });
|
|
160
224
|
```
|
|
161
225
|
|
|
162
|
-
Or pull the country select on its own (any list-of-countries UI):
|
|
163
|
-
|
|
164
|
-
```vue
|
|
165
|
-
<ACountrySelect v-model:selected="iso2" />
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
Or build any responsive popover (popover-on-desktop, drawer-on-mobile):
|
|
169
|
-
|
|
170
|
-
```vue
|
|
171
|
-
<AResponsivePopover v-model:open="open">
|
|
172
|
-
<AResponsivePopoverTrigger as-child>
|
|
173
|
-
<button>Open</button>
|
|
174
|
-
</AResponsivePopoverTrigger>
|
|
175
|
-
<AResponsivePopoverContent>
|
|
176
|
-
<p>Content</p>
|
|
177
|
-
</AResponsivePopoverContent>
|
|
178
|
-
</AResponsivePopover>
|
|
179
|
-
```
|
|
180
|
-
|
|
181
|
-
## Full customization
|
|
182
|
-
|
|
183
|
-
`ATellInput` exposes a deep customization surface across three vectors. Every override is opt-in — defaults are sensible, so a vanilla `<ATellInput />` works out of the box.
|
|
184
|
-
|
|
185
|
-
**Slots (replace any rendered region):**
|
|
186
|
-
|
|
187
|
-
```
|
|
188
|
-
prefix · suffix · trigger · chevron · flag · search · search-icon ·
|
|
189
|
-
loading · empty · group-header · item · item-check · valid-icon ·
|
|
190
|
-
error-icon · hint · error
|
|
191
|
-
```
|
|
192
|
-
|
|
193
|
-
**Data-override props:**
|
|
194
|
-
|
|
195
|
-
```ts
|
|
196
|
-
flagUrl?: (iso2, width) => string // swap flagcdn.com for any source
|
|
197
|
-
countries?: CountryOption[] // bypass REST Countries; ship your own list
|
|
198
|
-
searcher?: (query, country) => boolean // custom search (fuzzy/starts-with/locale-aware)
|
|
199
|
-
detector?: (opts) => Promise<string | null> // custom country detection (e.g. server-driven)
|
|
200
|
-
errorMessages?: Partial<Record<PhoneValidationReason, string>> // i18n
|
|
201
|
-
kbdOpen?: string | null // override the '⌘K' hint
|
|
202
|
-
kbdClose?: string | null // override the 'Esc' hint
|
|
203
|
-
```
|
|
204
|
-
|
|
205
|
-
**Class-override props (every region):** `class`, `fieldClass`, `inputClass`, `contentClass`, `popoverClass`, `drawerClass`, `hintClass`, `errorClass`. All merged via `tailwind-merge`, so you only specify the bits you want to change.
|
|
206
|
-
|
|
207
|
-
**Example — fully bespoke trigger, custom country list, custom searcher, custom detector:**
|
|
208
|
-
|
|
209
|
-
```vue
|
|
210
|
-
<script setup lang="ts">
|
|
211
|
-
import { ATellInput, defaultFlagUrl, type CountryOption } from '@alikhalilll/ui';
|
|
212
|
-
|
|
213
|
-
const countries: CountryOption[] = [
|
|
214
|
-
/* … your curated list … */
|
|
215
|
-
];
|
|
216
|
-
|
|
217
|
-
const flagUrl = (iso: string) => `/flags/${iso.toLowerCase()}.svg`;
|
|
218
|
-
const searcher = (q: string, c: CountryOption) =>
|
|
219
|
-
c.raw_data.name.toLowerCase().startsWith(q.toLowerCase());
|
|
220
|
-
|
|
221
|
-
async function detector() {
|
|
222
|
-
// Pretend your backend tells you the user's country from the request
|
|
223
|
-
const { country } = await $fetch('/api/locale');
|
|
224
|
-
return country;
|
|
225
|
-
}
|
|
226
|
-
</script>
|
|
227
|
-
|
|
228
|
-
<template>
|
|
229
|
-
<ATellInput
|
|
230
|
-
v-model:phone="phone"
|
|
231
|
-
v-model:country="country"
|
|
232
|
-
:countries="countries"
|
|
233
|
-
:flag-url="flagUrl"
|
|
234
|
-
:searcher="searcher"
|
|
235
|
-
:detector="detector"
|
|
236
|
-
>
|
|
237
|
-
<template #trigger="{ selectedCountry, open }">
|
|
238
|
-
<button :data-open="open">
|
|
239
|
-
{{ selectedCountry?.raw_data.iso2 ?? '??' }}
|
|
240
|
-
</button>
|
|
241
|
-
</template>
|
|
242
|
-
</ATellInput>
|
|
243
|
-
</template>
|
|
244
|
-
```
|
|
245
|
-
|
|
246
|
-
`AInput` also exposes `#prefix` and `#suffix` slots — when either is filled the component switches to a wrapped layout so the bordered field carries the focus ring while the slot content sits inside the border. See the [docs site](https://alikhalilll.github.io/ali-nuxt-toolkit/ui/input) for the full prop tables and a live demo gallery.
|
|
247
|
-
|
|
248
226
|
## Exported types
|
|
249
227
|
|
|
250
228
|
```ts
|
|
@@ -265,21 +243,11 @@ import type {
|
|
|
265
243
|
} from '@alikhalilll/ui';
|
|
266
244
|
```
|
|
267
245
|
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
```ts
|
|
271
|
-
import { defaultFlagUrl } from '@alikhalilll/ui';
|
|
272
|
-
const hiRes = (iso: string) => defaultFlagUrl(iso, 80);
|
|
273
|
-
```
|
|
274
|
-
|
|
275
|
-
## Country detection chain
|
|
276
|
-
|
|
277
|
-
1. **IP geolocation** — fetch `ipEndpoint` (default `https://ipapi.co/json/`), aborted after `timeoutMs` (default 2 s). Result cached in `sessionStorage` so re-mounts skip the network call.
|
|
278
|
-
2. **Timezone** — `Intl.DateTimeFormat().resolvedOptions().timeZone` against a built-in IANA-zone-to-ISO2 map (~70 zones, covers most populated cities).
|
|
279
|
-
3. **`navigator.language`** — extracts the region from tags like `en-US`, `ar-EG`, `pt-BR`.
|
|
280
|
-
4. **`defaultCountry`** — final fallback (`'US'` if you don't set one).
|
|
246
|
+
## Notes
|
|
281
247
|
|
|
282
|
-
|
|
248
|
+
- **Country detection** runs only in `onMounted` — the input renders immediately with `defaultCountry` (or empty); the detected ISO2 patches in on hydration.
|
|
249
|
+
- The default tel-input behaviour is **picker hidden until detected** (`detect-from-input`). Pass `:detect-from-input="false"` to opt out, or `default-country="20"` / `default-country="EG"` to pre-fill the picker at mount.
|
|
250
|
+
- Import `@alikhalilll/ui/styles.css` **before** your overrides so your overrides win the cascade.
|
|
283
251
|
|
|
284
252
|
## License
|
|
285
253
|
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { defineComponent as d, openBlock as c, createBlock as p, unref as e, mergeProps as i, withCtx as l, renderSlot as m, createVNode as y, createElementVNode as b } from "vue";
|
|
2
|
+
import { DrawerRoot as h, DrawerTrigger as x, DrawerOverlay as O, DrawerPortal as D, DrawerContent as v } from "vaul-vue";
|
|
3
|
+
import { useForwardPropsEmits as B, useForwardProps as w } from "reka-ui";
|
|
4
|
+
import { reactiveOmit as _ } from "@vueuse/core";
|
|
5
|
+
import { c as g } from "./cn-B6yFEsav.mjs";
|
|
6
|
+
const F = /* @__PURE__ */ d({
|
|
7
|
+
__name: "ADrawer",
|
|
8
|
+
props: {
|
|
9
|
+
activeSnapPoint: {},
|
|
10
|
+
closeThreshold: {},
|
|
11
|
+
shouldScaleBackground: { type: Boolean, default: !0 },
|
|
12
|
+
setBackgroundColorOnScale: { type: Boolean },
|
|
13
|
+
scrollLockTimeout: {},
|
|
14
|
+
fixed: { type: Boolean },
|
|
15
|
+
dismissible: { type: Boolean },
|
|
16
|
+
modal: { type: Boolean },
|
|
17
|
+
open: { type: Boolean },
|
|
18
|
+
defaultOpen: { type: Boolean },
|
|
19
|
+
nested: { type: Boolean },
|
|
20
|
+
direction: {},
|
|
21
|
+
noBodyStyles: { type: Boolean },
|
|
22
|
+
handleOnly: { type: Boolean },
|
|
23
|
+
preventScrollRestoration: { type: Boolean },
|
|
24
|
+
snapPoints: {},
|
|
25
|
+
fadeFromIndex: {}
|
|
26
|
+
},
|
|
27
|
+
emits: ["drag", "release", "close", "update:open", "update:activeSnapPoint", "animationEnd"],
|
|
28
|
+
setup(t, { emit: o }) {
|
|
29
|
+
const s = B(t, o);
|
|
30
|
+
return (n, u) => (c(), p(e(h), i({ "data-slot": "drawer" }, e(s)), {
|
|
31
|
+
default: l(() => [
|
|
32
|
+
m(n.$slots, "default")
|
|
33
|
+
]),
|
|
34
|
+
_: 3
|
|
35
|
+
}, 16));
|
|
36
|
+
}
|
|
37
|
+
}), E = /* @__PURE__ */ d({
|
|
38
|
+
__name: "ADrawerTrigger",
|
|
39
|
+
props: {
|
|
40
|
+
asChild: { type: Boolean },
|
|
41
|
+
as: {}
|
|
42
|
+
},
|
|
43
|
+
setup(t) {
|
|
44
|
+
const a = w(t);
|
|
45
|
+
return (r, s) => (c(), p(e(x), i({ "data-slot": "drawer-trigger" }, e(a)), {
|
|
46
|
+
default: l(() => [
|
|
47
|
+
m(r.$slots, "default")
|
|
48
|
+
]),
|
|
49
|
+
_: 3
|
|
50
|
+
}, 16));
|
|
51
|
+
}
|
|
52
|
+
}), A = /* @__PURE__ */ d({
|
|
53
|
+
__name: "ADrawerOverlay",
|
|
54
|
+
props: {
|
|
55
|
+
forceMount: { type: Boolean },
|
|
56
|
+
asChild: { type: Boolean },
|
|
57
|
+
as: {},
|
|
58
|
+
class: { type: [Boolean, null, String, Object, Array] }
|
|
59
|
+
},
|
|
60
|
+
setup(t) {
|
|
61
|
+
const o = t, a = _(o, "class"), r = w(a);
|
|
62
|
+
return (s, n) => (c(), p(e(O), i({ "data-slot": "drawer-overlay" }, e(r), {
|
|
63
|
+
class: e(g)(
|
|
64
|
+
"data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-40 bg-black/60 backdrop-blur-sm",
|
|
65
|
+
o.class
|
|
66
|
+
)
|
|
67
|
+
}), null, 16, ["class"]));
|
|
68
|
+
}
|
|
69
|
+
}), T = /* @__PURE__ */ d({
|
|
70
|
+
inheritAttrs: !1,
|
|
71
|
+
__name: "ADrawerContent",
|
|
72
|
+
props: {
|
|
73
|
+
forceMount: { type: Boolean },
|
|
74
|
+
disableOutsidePointerEvents: { type: Boolean },
|
|
75
|
+
asChild: { type: Boolean },
|
|
76
|
+
as: {},
|
|
77
|
+
class: { type: [Boolean, null, String, Object, Array] }
|
|
78
|
+
},
|
|
79
|
+
emits: ["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus"],
|
|
80
|
+
setup(t, { emit: o }) {
|
|
81
|
+
const a = t, r = o, s = _(a, "class"), n = B(s, r);
|
|
82
|
+
return (u, f) => (c(), p(e(D), null, {
|
|
83
|
+
default: l(() => [
|
|
84
|
+
y(A),
|
|
85
|
+
y(e(v), i({ "data-slot": "drawer-content" }, { ...u.$attrs, ...e(n) }, {
|
|
86
|
+
class: e(g)(
|
|
87
|
+
"bg-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border outline-none",
|
|
88
|
+
a.class
|
|
89
|
+
)
|
|
90
|
+
}), {
|
|
91
|
+
default: l(() => [
|
|
92
|
+
f[0] || (f[0] = b("div", { class: "bg-muted mx-auto mt-4 h-2 w-[100px] rounded-full" }, null, -1)),
|
|
93
|
+
m(u.$slots, "default")
|
|
94
|
+
]),
|
|
95
|
+
_: 3
|
|
96
|
+
}, 16, ["class"])
|
|
97
|
+
]),
|
|
98
|
+
_: 3
|
|
99
|
+
}));
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
export {
|
|
103
|
+
F as _,
|
|
104
|
+
T as a,
|
|
105
|
+
A as b,
|
|
106
|
+
E as c
|
|
107
|
+
};
|
|
108
|
+
//# sourceMappingURL=ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ADrawerContent.vue_vue_type_script_setup_true_lang-BivIZvV1.mjs","sources":["../../entries/drawer/components/ADrawer.vue","../../entries/drawer/components/ADrawerTrigger.vue","../../entries/drawer/components/ADrawerOverlay.vue","../../entries/drawer/components/ADrawerContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { DrawerRoot, type DrawerRootEmits, type DrawerRootProps } from 'vaul-vue';\nimport { useForwardPropsEmits } from 'reka-ui';\n\nconst props = withDefaults(defineProps<DrawerRootProps>(), {\n shouldScaleBackground: true,\n});\nconst emits = defineEmits<DrawerRootEmits>();\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <DrawerRoot data-slot=\"drawer\" v-bind=\"forwarded\">\n <slot />\n </DrawerRoot>\n</template>\n","<script setup lang=\"ts\">\nimport { DrawerTrigger, type DrawerTriggerProps } from 'vaul-vue';\nimport { useForwardProps } from 'reka-ui';\n\nconst props = defineProps<DrawerTriggerProps>();\nconst forwarded = useForwardProps(props);\n</script>\n\n<template>\n <DrawerTrigger data-slot=\"drawer-trigger\" v-bind=\"forwarded\">\n <slot />\n </DrawerTrigger>\n</template>\n","<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { DrawerOverlay } from 'vaul-vue';\nimport type { DialogOverlayProps } from 'reka-ui';\nimport { reactiveOmit } from '@vueuse/core';\nimport { useForwardProps } from 'reka-ui';\nimport { cn } from '@/utils';\n\nconst props = defineProps<DialogOverlayProps & { class?: HTMLAttributes['class'] }>();\nconst delegated = reactiveOmit(props, 'class');\nconst forwarded = useForwardProps(delegated);\n</script>\n\n<template>\n <DrawerOverlay\n data-slot=\"drawer-overlay\"\n v-bind=\"forwarded\"\n :class=\"\n cn(\n 'data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 fixed inset-0 z-40 bg-black/60 backdrop-blur-sm',\n props.class\n )\n \"\n />\n</template>\n","<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { DrawerContent, DrawerPortal } from 'vaul-vue';\nimport type { DialogContentEmits, DialogContentProps } from 'reka-ui';\nimport { reactiveOmit } from '@vueuse/core';\nimport { useForwardPropsEmits } from 'reka-ui';\nimport { cn } from '@/utils';\nimport ADrawerOverlay from './ADrawerOverlay.vue';\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = defineProps<DialogContentProps & { class?: HTMLAttributes['class'] }>();\nconst emits = defineEmits<DialogContentEmits>();\nconst delegated = reactiveOmit(props, 'class');\nconst forwarded = useForwardPropsEmits(delegated, emits);\n</script>\n\n<template>\n <DrawerPortal>\n <ADrawerOverlay />\n <DrawerContent\n data-slot=\"drawer-content\"\n v-bind=\"{ ...$attrs, ...forwarded }\"\n :class=\"\n cn(\n 'bg-background fixed inset-x-0 bottom-0 z-50 mt-24 flex h-auto flex-col rounded-t-[10px] border outline-none',\n props.class\n )\n \"\n >\n <div class=\"bg-muted mx-auto mt-4 h-2 w-[100px] rounded-full\" />\n <slot />\n </DrawerContent>\n </DrawerPortal>\n</template>\n"],"names":["forwarded","useForwardPropsEmits","__props","__emit","_openBlock","_createBlock","_unref","_mergeProps","_renderSlot","_ctx","useForwardProps","props","delegated","reactiveOmit","cn","emits","DrawerPortal","_createVNode","ADrawerOverlay","DrawerContent","$attrs","_createElementVNode"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;AAQA,UAAMA,IAAYC,EAJJC,GAGAC,CACqC;sBAIjDC,EAAA,GAAAC,EAEaC,MAFbC,EAEa,EAFD,aAAU,SAAA,GAAiBD,EAAAN,CAAA,CAAS,GAAA;AAAA,iBAC9C,MAAQ;AAAA,QAARQ,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;;;;;;;ACRZ,UAAMT,IAAYU,EADJR,CACyB;sBAIrCE,EAAA,GAAAC,EAEgBC,MAFhBC,EAEgB,EAFD,aAAU,iBAAA,GAAyBD,EAAAN,CAAA,CAAS,GAAA;AAAA,iBACzD,MAAQ;AAAA,QAARQ,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;;;;;;;;;ACFZ,UAAME,IAAQT,GACRU,IAAYC,EAAaF,GAAO,OAAO,GACvCX,IAAYU,EAAgBE,CAAS;sBAIzCR,EAAA,GAAAC,EASEC,MATFC,EASE,EARA,aAAU,iBAAA,GACFD,EAAAN,CAAA,GAAS;AAAA,MAChB,OAAcM,EAAAQ,CAAA;AAAA;QAA+LH,EAAM;AAAA,MAAA;AAAA;;;;;;;;;;;;;;ACNxN,UAAMA,IAAQT,GACRa,IAAQZ,GACRS,IAAYC,EAAaF,GAAO,OAAO,GACvCX,IAAYC,EAAqBW,GAAWG,CAAK;2BAIrDV,EAeeC,EAAAU,CAAA,GAAA,MAAA;AAAA,iBAdb,MAAkB;AAAA,QAAlBC,EAAkBC,CAAA;AAAA,QAClBD,EAYgBX,EAAAa,CAAA,GAZhBZ,EAYgB,EAXd,aAAU,iBAAA,GAAgB,EAAA,GACba,EAAAA,QAAM,GAAKd,EAAAN,CAAA,KAAS;AAAA,UAChC,OAAgBM,EAAAQ,CAAA;AAAA;YAAuIH,EAAM;AAAA,UAAA;AAAA;qBAO9J,MAAgE;AAAA,4BAAhEU,EAAgE,OAAA,EAA3D,OAAM,mDAAA,GAAkD,MAAA,EAAA;AAAA,YAC7Db,EAAQC,EAAA,QAAA,SAAA;AAAA,UAAA;;;;;;;;"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { defineComponent as S, useSlots as A, computed as l, openBlock as i, createElementBlock as r, normalizeClass as o, unref as t, renderSlot as x, createCommentVNode as v, withDirectives as y, createElementVNode as B, isRef as z, vModelText as h } from "vue";
|
|
2
|
+
import { useVModel as _ } from "@vueuse/core";
|
|
3
|
+
import { c as n } from "./cn-B6yFEsav.mjs";
|
|
4
|
+
import { D as j, c as E, b as O, d as T } from "./sizes-B_9MfLkz.mjs";
|
|
5
|
+
const D = ["data-size"], P = ["data-size"], N = /* @__PURE__ */ S({
|
|
6
|
+
__name: "AInput",
|
|
7
|
+
props: {
|
|
8
|
+
defaultValue: {},
|
|
9
|
+
modelValue: {},
|
|
10
|
+
class: { type: [Boolean, null, String, Object, Array] },
|
|
11
|
+
inputClass: { type: [Boolean, null, String, Object, Array] },
|
|
12
|
+
prefixClass: { type: [Boolean, null, String, Object, Array] },
|
|
13
|
+
suffixClass: { type: [Boolean, null, String, Object, Array] },
|
|
14
|
+
size: { default: j }
|
|
15
|
+
},
|
|
16
|
+
emits: ["update:modelValue"],
|
|
17
|
+
setup(k, { emit: V }) {
|
|
18
|
+
const e = k, w = V, d = A(), f = l(() => !!d.prefix), c = l(() => !!d.suffix), C = l(() => f.value || c.value), s = _(e, "modelValue", w, {
|
|
19
|
+
passive: !0,
|
|
20
|
+
defaultValue: e.defaultValue
|
|
21
|
+
}), p = l(() => E[e.size]), m = l(() => O[e.size]), g = l(() => T[e.size]);
|
|
22
|
+
return (b, a) => C.value ? (i(), r("div", {
|
|
23
|
+
key: 0,
|
|
24
|
+
"data-size": e.size,
|
|
25
|
+
class: o(
|
|
26
|
+
t(n)(
|
|
27
|
+
"border-input bg-background ring-offset-background focus-within:ring-ring inline-flex w-full items-center rounded-md border shadow-sm transition-colors focus-within:ring-1",
|
|
28
|
+
p.value,
|
|
29
|
+
m.value,
|
|
30
|
+
g.value,
|
|
31
|
+
e.class
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
}, [
|
|
35
|
+
f.value ? (i(), r("span", {
|
|
36
|
+
key: 0,
|
|
37
|
+
class: o(t(n)("text-muted-foreground flex shrink-0 items-center pr-2", e.prefixClass))
|
|
38
|
+
}, [
|
|
39
|
+
x(b.$slots, "prefix")
|
|
40
|
+
], 2)) : v("", !0),
|
|
41
|
+
y(B("input", {
|
|
42
|
+
"onUpdate:modelValue": a[0] || (a[0] = (u) => z(s) ? s.value = u : null),
|
|
43
|
+
"data-slot": "input",
|
|
44
|
+
class: o(
|
|
45
|
+
t(n)(
|
|
46
|
+
"placeholder:text-muted-foreground h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
47
|
+
e.inputClass
|
|
48
|
+
)
|
|
49
|
+
)
|
|
50
|
+
}, null, 2), [
|
|
51
|
+
[h, t(s)]
|
|
52
|
+
]),
|
|
53
|
+
c.value ? (i(), r("span", {
|
|
54
|
+
key: 1,
|
|
55
|
+
class: o(t(n)("text-muted-foreground flex shrink-0 items-center pl-2", e.suffixClass))
|
|
56
|
+
}, [
|
|
57
|
+
x(b.$slots, "suffix")
|
|
58
|
+
], 2)) : v("", !0)
|
|
59
|
+
], 10, D)) : y((i(), r("input", {
|
|
60
|
+
key: 1,
|
|
61
|
+
"onUpdate:modelValue": a[1] || (a[1] = (u) => z(s) ? s.value = u : null),
|
|
62
|
+
"data-slot": "input",
|
|
63
|
+
"data-size": e.size,
|
|
64
|
+
class: o(
|
|
65
|
+
t(n)(
|
|
66
|
+
"border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex w-full rounded-md border py-1 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50",
|
|
67
|
+
p.value,
|
|
68
|
+
m.value,
|
|
69
|
+
g.value,
|
|
70
|
+
e.class
|
|
71
|
+
)
|
|
72
|
+
)
|
|
73
|
+
}, null, 10, P)), [
|
|
74
|
+
[h, t(s)]
|
|
75
|
+
]);
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
export {
|
|
79
|
+
N as _
|
|
80
|
+
};
|
|
81
|
+
//# sourceMappingURL=AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AInput.vue_vue_type_script_setup_true_lang-BJUP7ePq.mjs","sources":["../../entries/input/components/AInput.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { computed, useSlots } from 'vue';\nimport { useVModel } from '@vueuse/core';\nimport { cn } from '@/utils';\nimport { controlHeight, controlPaddingX, controlTextSize, DEFAULT_SIZE, type Size } from '@/utils';\n\nconst props = withDefaults(\n defineProps<{\n defaultValue?: string | number;\n modelValue?: string | number;\n class?: HTMLAttributes['class'];\n /** Classes for the inner <input> element (useful when prefix/suffix are present). */\n inputClass?: HTMLAttributes['class'];\n /** Classes for the prefix wrapper. */\n prefixClass?: HTMLAttributes['class'];\n /** Classes for the suffix wrapper. */\n suffixClass?: HTMLAttributes['class'];\n size?: Size;\n }>(),\n { size: DEFAULT_SIZE }\n);\n\nconst emits = defineEmits<{\n (e: 'update:modelValue', payload: string | number): void;\n}>();\n\ndefineSlots<{\n /** Content rendered inside the input's border, left of the field. */\n prefix?: () => unknown;\n /** Content rendered inside the input's border, right of the field. */\n suffix?: () => unknown;\n}>();\n\nconst slots = useSlots();\nconst hasPrefix = computed(() => !!slots.prefix);\nconst hasSuffix = computed(() => !!slots.suffix);\nconst hasAdornment = computed(() => hasPrefix.value || hasSuffix.value);\n\nconst modelValue = useVModel(props, 'modelValue', emits, {\n passive: true,\n defaultValue: props.defaultValue,\n});\n\nconst sizeHeight = computed(() => controlHeight[props.size]);\nconst sizePaddingX = computed(() => controlPaddingX[props.size]);\nconst sizeText = computed(() => controlTextSize[props.size]);\n</script>\n\n<template>\n <!--\n When prefix or suffix slots are filled we render a wrapper that owns the border,\n background and focus ring — so the visible \"input\" is the whole bar, not just the\n native element. Otherwise we render the plain native input directly so consumers\n can use AInput as a drop-in for <input>.\n -->\n <div\n v-if=\"hasAdornment\"\n :data-size=\"props.size\"\n :class=\"\n cn(\n 'border-input bg-background ring-offset-background focus-within:ring-ring inline-flex w-full items-center rounded-md border shadow-sm transition-colors focus-within:ring-1',\n sizeHeight,\n sizePaddingX,\n sizeText,\n props.class\n )\n \"\n >\n <span\n v-if=\"hasPrefix\"\n :class=\"cn('text-muted-foreground flex shrink-0 items-center pr-2', props.prefixClass)\"\n >\n <slot name=\"prefix\" />\n </span>\n\n <input\n v-model=\"modelValue\"\n data-slot=\"input\"\n :class=\"\n cn(\n 'placeholder:text-muted-foreground h-full min-w-0 flex-1 bg-transparent outline-none disabled:cursor-not-allowed disabled:opacity-50',\n props.inputClass\n )\n \"\n />\n\n <span\n v-if=\"hasSuffix\"\n :class=\"cn('text-muted-foreground flex shrink-0 items-center pl-2', props.suffixClass)\"\n >\n <slot name=\"suffix\" />\n </span>\n </div>\n\n <input\n v-else\n v-model=\"modelValue\"\n data-slot=\"input\"\n :data-size=\"props.size\"\n :class=\"\n cn(\n 'border-input bg-background ring-offset-background placeholder:text-muted-foreground focus-visible:ring-ring flex w-full rounded-md border py-1 shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium focus-visible:ring-1 focus-visible:outline-none disabled:cursor-not-allowed disabled:opacity-50',\n sizeHeight,\n sizePaddingX,\n sizeText,\n props.class\n )\n \"\n />\n</template>\n"],"names":["props","__props","emits","__emit","slots","useSlots","hasPrefix","computed","hasSuffix","hasAdornment","modelValue","useVModel","sizeHeight","controlHeight","sizePaddingX","controlPaddingX","sizeText","controlTextSize","_createElementBlock","_normalizeClass","_unref","cn","_renderSlot","_ctx","_createElementVNode","$event"],"mappings":";;;;;;;;;;;;;;;;;AAOA,UAAMA,IAAQC,GAgBRC,IAAQC,GAWRC,IAAQC,EAAA,GACRC,IAAYC,EAAS,MAAM,CAAC,CAACH,EAAM,MAAM,GACzCI,IAAYD,EAAS,MAAM,CAAC,CAACH,EAAM,MAAM,GACzCK,IAAeF,EAAS,MAAMD,EAAU,SAASE,EAAU,KAAK,GAEhEE,IAAaC,EAAUX,GAAO,cAAcE,GAAO;AAAA,MACvD,SAAS;AAAA,MACT,cAAcF,EAAM;AAAA,IAAA,CACrB,GAEKY,IAAaL,EAAS,MAAMM,EAAcb,EAAM,IAAI,CAAC,GACrDc,IAAeP,EAAS,MAAMQ,EAAgBf,EAAM,IAAI,CAAC,GACzDgB,IAAWT,EAAS,MAAMU,EAAgBjB,EAAM,IAAI,CAAC;qBAWjDS,EAAA,cADRS,EAqCM,OAAA;AAAA;MAnCH,aAAWlB,EAAM;AAAA,MACjB,OAAKmB;AAAAA,QAASC,EAAAC,CAAA;AAAA;UAAkMT,EAAA;AAAA,UAAoBE,EAAA;AAAA,UAAsBE,EAAA;AAAA,UAAkBhB,EAAM;AAAA,QAAA;AAAA;;MAW3QM,EAAA,cADRY,EAKO,QAAA;AAAA;QAHJ,OAAKC,EAAEC,EAAAC,CAAA,EAAE,yDAA0DrB,EAAM,WAAW,CAAA;AAAA,MAAA;QAErFsB,EAAsBC,EAAA,QAAA,QAAA;AAAA,MAAA;QAGxBC,EASE,SAAA;AAAA,6DARSd,EAAU,QAAAe,IAAA;AAAA,QACnB,aAAU;AAAA,QACT,OAAKN;AAAAA,UAAWC,EAAAC,CAAA;AAAA;YAA+JrB,EAAM;AAAA,UAAA;AAAA;;YAF7KoB,EAAAV,CAAA,CAAU;AAAA,MAAA;MAWbF,EAAA,cADRU,EAKO,QAAA;AAAA;QAHJ,OAAKC,EAAEC,EAAAC,CAAA,EAAE,yDAA0DrB,EAAM,WAAW,CAAA;AAAA,MAAA;QAErFsB,EAAsBC,EAAA,QAAA,QAAA;AAAA,MAAA;yBAI1BL,EAcE,SAAA;AAAA;2DAZSR,EAAU,QAAAe,IAAA;AAAA,MACnB,aAAU;AAAA,MACT,aAAWzB,EAAM;AAAA,MACjB,OAAKmB;AAAAA,QAASC,EAAAC,CAAA;AAAA;UAAkWT,EAAA;AAAA,UAAoBE,EAAA;AAAA,UAAsBE,EAAA;AAAA,UAAkBhB,EAAM;AAAA,QAAA;AAAA;;UAH1aoB,EAAAV,CAAA,CAAU;AAAA,IAAA;;;"}
|