@alikhalilll/ui 1.1.0 → 1.2.0

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.
@@ -1,13 +1,18 @@
1
- import { _ as e, a as s, b as l, D as n, c as u, d as o, e as r, u as A, f as c } from "./chunks/ATellInput.vue_vue_type_script_setup_true_lang-B4lyNu_f.mjs";
1
+ import { _ as e, a as t, b as l, D as n, c as o, L as r, d as u, e as i, f as A, l as E, n as S, r as C, u as D, g as _ } from "./chunks/ATellInput.vue_vue_type_script_setup_true_lang-Bv_lLV_l.mjs";
2
2
  export {
3
3
  e as ACountryFlag,
4
- s as ACountrySelect,
4
+ t as ACountrySelect,
5
5
  l as ATellInput,
6
6
  n as DEFAULT_ERROR_MESSAGES,
7
+ o as DEFAULT_MESSAGES,
8
+ r as LOCALE_DIGIT_RANGES,
7
9
  u as aTellInputVariants,
8
- o as defaultFlagUrl,
9
- r as detectCountry,
10
- A as useCountryDetection,
11
- c as usePhoneValidation
10
+ i as defaultFlagUrl,
11
+ A as detectCountry,
12
+ E as localizeCountries,
13
+ S as normalizeDigits,
14
+ C as resolveMessages,
15
+ D as useCountryDetection,
16
+ _ as usePhoneValidation
12
17
  };
13
18
  //# sourceMappingURL=tell-input.mjs.map
@@ -1,6 +1,6 @@
1
1
  # `@alikhalilll/ui/tell-input`
2
2
 
3
- Vue 3 phone-number input with smart country detection (libphonenumber-js + IP/timezone/locale hint), a responsive popover/drawer country picker, and a structured `PhoneValidationResult` exposed via template ref.
3
+ Vue 3 phone-number input with smart country detection (libphonenumber-js + IP/timezone/locale hint), a responsive popover/drawer country picker, and a structured `PhoneValidationResult` exposed via template ref. RTL-aware, localisable, and accepts alternative numeral systems.
4
4
 
5
5
  ## Install
6
6
 
@@ -31,7 +31,22 @@ const country = ref<number | null>(null);
31
31
  </template>
32
32
  ```
33
33
 
34
- The default shape is a plain phone input with the country picker hidden. As the user types or pastes, detection runs (debounced) against known dial codes; on first match the picker slides in pre-filled and `phone` is normalised to the national significant number — `01066105963` becomes `1066105963`, `+447911123456` becomes `7911123456`.
34
+ The default shape is a plain phone input with the country picker hidden. As the user types or pastes, detection runs (debounced) against known dial codes; on first match a flag-only trigger reveals at the **end** of the field, the dial code shows as a static prefix inside the input, and `phone` is normalised to the national significant number — `01066105963` becomes `1066105963`, `+447911123456` becomes `7911123456`.
35
+
36
+ ## Internationalization
37
+
38
+ - **RTL** — direction inherits from the page (`<div dir="rtl">` / `<html dir="rtl">`), or force it with `dir="ltr"` / `dir="rtl"`. The phone field row stays LTR (dial prefix → digits → flag); only the helper/error text and the country popover follow the page direction.
39
+ - **`locale`** — localises country names (`Intl.DisplayNames`) and the format-hint numerals.
40
+ - **`messages`** — one bag for every UI string (picker labels, validation errors, a11y labels).
41
+ - **Alternative numerals** — digits typed as Arabic-Indic (`٠-٩`), Persian (`۰-۹`), Devanagari, or Bengali are normalised to ASCII. `normalizeDigits` is exported for standalone use.
42
+
43
+ ```vue
44
+ <template>
45
+ <div dir="rtl">
46
+ <ATellInput v-model:phone="phone" v-model:country="country" locale="ar" :messages="ar" />
47
+ </div>
48
+ </template>
49
+ ```
35
50
 
36
51
  ## Variants
37
52
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alikhalilll/ui",
3
- "version": "1.1.0",
3
+ "version": "1.2.0",
4
4
  "description": "Headless, shadcn-vue style Vue 3 component library — every component is its own importable subpath (`@alikhalilll/ui/tell-input`, `@alikhalilll/ui/popover`, …) so users pay only for what they actually use.",
5
5
  "license": "MIT",
6
6
  "author": "alikhalilll",
@@ -1,103 +0,0 @@
1
- import { defineComponent as p, openBlock as n, createBlock as c, unref as e, mergeProps as u, withCtx as l, renderSlot as f, normalizeProps as g, guardReactiveProps as B, createElementBlock as _, normalizeClass as P, createCommentVNode as h, createVNode as b } from "vue";
2
- import { useForwardPropsEmits as v, PopoverRoot as w, useForwardProps as C, PopoverTrigger as O, PopoverPortal as A, PopoverContent as k } from "reka-ui";
3
- import { reactiveOmit as z } from "@vueuse/core";
4
- import { c as y } from "./cn-B6yFEsav.mjs";
5
- const D = /* @__PURE__ */ p({
6
- __name: "APopover",
7
- props: {
8
- defaultOpen: { type: Boolean },
9
- open: { type: Boolean },
10
- modal: { type: Boolean, default: !0 }
11
- },
12
- emits: ["update:open"],
13
- setup(t, { emit: a }) {
14
- const r = v(t, a);
15
- return (i, d) => (n(), c(e(w), u({ "data-slot": "popover" }, e(r)), {
16
- default: l((m) => [
17
- f(i.$slots, "default", g(B(m)))
18
- ]),
19
- _: 3
20
- }, 16));
21
- }
22
- }), E = /* @__PURE__ */ p({
23
- __name: "APopoverTrigger",
24
- props: {
25
- asChild: { type: Boolean },
26
- as: {}
27
- },
28
- setup(t) {
29
- const o = C(t);
30
- return (s, r) => (n(), c(e(O), u({ "data-slot": "popover-trigger" }, e(o)), {
31
- default: l(() => [
32
- f(s.$slots, "default")
33
- ]),
34
- _: 3
35
- }, 16));
36
- }
37
- }), j = /* @__PURE__ */ p({
38
- inheritAttrs: !1,
39
- __name: "APopoverContent",
40
- props: {
41
- forceMount: { type: Boolean },
42
- side: {},
43
- sideOffset: { default: 4 },
44
- sideFlip: { type: Boolean },
45
- align: { default: "center" },
46
- alignOffset: {},
47
- alignFlip: { type: Boolean },
48
- avoidCollisions: { type: Boolean },
49
- collisionBoundary: {},
50
- collisionPadding: {},
51
- arrowPadding: {},
52
- hideShiftedArrow: { type: Boolean },
53
- sticky: {},
54
- hideWhenDetached: { type: Boolean },
55
- positionStrategy: {},
56
- updatePositionStrategy: {},
57
- disableUpdateOnLayoutShift: { type: Boolean },
58
- prioritizePosition: { type: Boolean },
59
- reference: {},
60
- asChild: { type: Boolean },
61
- as: {},
62
- disableOutsidePointerEvents: { type: Boolean },
63
- class: { type: [Boolean, null, String, Object, Array] },
64
- overlay: { type: Boolean, default: !1 },
65
- overlayClass: { type: [Boolean, null, String, Object, Array] }
66
- },
67
- emits: ["escapeKeyDown", "pointerDownOutside", "focusOutside", "interactOutside", "openAutoFocus", "closeAutoFocus"],
68
- setup(t, { emit: a }) {
69
- const o = t, s = a, r = z(o, "class", "overlay", "overlayClass"), i = v(r, s);
70
- return (d, m) => (n(), c(e(A), null, {
71
- default: l(() => [
72
- o.overlay ? (n(), _("div", {
73
- key: 0,
74
- "data-slot": "popover-overlay",
75
- class: P(
76
- e(y)(
77
- "fixed inset-0 z-40 bg-black/60 backdrop-blur-sm pointer-events-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
78
- o.overlayClass
79
- )
80
- )
81
- }, null, 2)) : h("", !0),
82
- b(e(k), u({ "data-slot": "popover-content" }, { ...d.$attrs, ...e(i) }, {
83
- class: e(y)(
84
- "bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none",
85
- o.class
86
- )
87
- }), {
88
- default: l(() => [
89
- f(d.$slots, "default")
90
- ]),
91
- _: 3
92
- }, 16, ["class"])
93
- ]),
94
- _: 3
95
- }));
96
- }
97
- });
98
- export {
99
- D as _,
100
- j as a,
101
- E as b
102
- };
103
- //# sourceMappingURL=APopoverContent.vue_vue_type_script_setup_true_lang-BRqULKIg.mjs.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"APopoverContent.vue_vue_type_script_setup_true_lang-BRqULKIg.mjs","sources":["../../entries/popover/components/APopover.vue","../../entries/popover/components/APopoverTrigger.vue","../../entries/popover/components/APopoverContent.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport type { PopoverRootEmits, PopoverRootProps } from 'reka-ui';\nimport { PopoverRoot, useForwardPropsEmits } from 'reka-ui';\n\n/**\n * Defaults `modal` to `true` so the popover locks page scroll, traps focus, and an overlay\n * (rendered by APopoverContent when `overlay` is set) actually dims the page.\n * Pass `:modal=\"false\"` for tooltip-style non-modal popovers.\n */\nconst props = withDefaults(defineProps<PopoverRootProps>(), { modal: true });\nconst emits = defineEmits<PopoverRootEmits>();\nconst forwarded = useForwardPropsEmits(props, emits);\n</script>\n\n<template>\n <PopoverRoot v-slot=\"slotProps\" data-slot=\"popover\" v-bind=\"forwarded\">\n <slot v-bind=\"slotProps\" />\n </PopoverRoot>\n</template>\n","<script setup lang=\"ts\">\nimport type { PopoverTriggerProps } from 'reka-ui';\nimport { PopoverTrigger, useForwardProps } from 'reka-ui';\n\nconst props = defineProps<PopoverTriggerProps>();\nconst forwarded = useForwardProps(props);\n</script>\n\n<template>\n <PopoverTrigger data-slot=\"popover-trigger\" v-bind=\"forwarded\">\n <slot />\n </PopoverTrigger>\n</template>\n","<script setup lang=\"ts\">\nimport type { HTMLAttributes } from 'vue';\nimport { reactiveOmit } from '@vueuse/core';\nimport {\n PopoverContent,\n type PopoverContentEmits,\n type PopoverContentProps,\n PopoverPortal,\n useForwardPropsEmits,\n} from 'reka-ui';\nimport { cn } from '@/utils';\n\ndefineOptions({ inheritAttrs: false });\n\nconst props = withDefaults(\n defineProps<\n PopoverContentProps & {\n class?: HTMLAttributes['class'];\n /** Render a dimmed, clickable backdrop behind the popover. Pair with `<APopover modal>`. */\n overlay?: boolean;\n overlayClass?: HTMLAttributes['class'];\n }\n >(),\n { align: 'center', sideOffset: 4, overlay: false }\n);\nconst emits = defineEmits<PopoverContentEmits>();\nconst delegated = reactiveOmit(props, 'class', 'overlay', 'overlayClass');\nconst forwarded = useForwardPropsEmits(delegated, emits);\n</script>\n\n<template>\n <PopoverPortal>\n <!--\n Overlay is a sibling of PopoverContent inside the same portal. Reka-ui's\n DismissableLayer treats any pointer-down outside the content as a dismiss,\n so clicking the overlay closes the popover for free. We still mark it\n pointer-events:auto explicitly to be safe.\n -->\n <div\n v-if=\"props.overlay\"\n data-slot=\"popover-overlay\"\n :class=\"\n cn(\n 'fixed inset-0 z-40 bg-black/60 backdrop-blur-sm pointer-events-auto data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n props.overlayClass\n )\n \"\n />\n <PopoverContent\n data-slot=\"popover-content\"\n v-bind=\"{ ...$attrs, ...forwarded }\"\n :class=\"\n cn(\n 'bg-popover text-popover-foreground data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 z-50 w-72 rounded-md border p-4 shadow-md outline-none',\n props.class\n )\n \"\n >\n <slot />\n </PopoverContent>\n </PopoverPortal>\n</template>\n"],"names":["forwarded","useForwardPropsEmits","__props","__emit","_openBlock","_createBlock","_unref","_mergeProps","_withCtx","slotProps","_renderSlot","_ctx","useForwardProps","props","emits","delegated","reactiveOmit","PopoverPortal","_createElementBlock","_normalizeClass","cn","_createVNode","PopoverContent","$attrs"],"mappings":";;;;;;;;;;;;;AAWA,UAAMA,IAAYC,EAFJC,GACAC,CACqC;sBAIjDC,EAAA,GAAAC,EAEcC,MAFdC,EAEc,EAFkB,aAAU,UAAA,GAAkBD,EAAAN,CAAA,CAAS,GAAA;AAAA,MACnE,SAAAQ,EAAA,CADmBC,MAAS;AAAA,QAC5BC,EAA2BC,yBAAbF,CAAS,CAAA,CAAA;AAAA,MAAA;;;;;;;;;;;ACX3B,UAAMT,IAAYY,EADJV,CACyB;sBAIrCE,EAAA,GAAAC,EAEiBC,MAFjBC,EAEiB,EAFD,aAAU,kBAAA,GAA0BD,EAAAN,CAAA,CAAS,GAAA;AAAA,iBAC3D,MAAQ;AAAA,QAARU,EAAQC,EAAA,QAAA,SAAA;AAAA,MAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACIZ,UAAME,IAAQX,GAWRY,IAAQX,GACRY,IAAYC,EAAaH,GAAO,SAAS,WAAW,cAAc,GAClEb,IAAYC,EAAqBc,GAAWD,CAAK;2BAIrDT,EA6BgBC,EAAAW,CAAA,GAAA,MAAA;AAAA,iBAtBd,MASE;AAAA,QARMJ,EAAM,gBADdK,EASE,OAAA;AAAA;UAPA,aAAU;AAAA,UACT,OAAKC;AAAAA,YAAWb,EAAAc,CAAA;AAAA;cAAuNP,EAAM;AAAA,YAAA;AAAA;;QAOhPQ,EAWiBf,EAAAgB,CAAA,GAXjBf,EAWiB,EAVf,aAAU,kBAAA,GAAiB,EAAA,GACdgB,EAAAA,QAAM,GAAKjB,EAAAN,CAAA,KAAS;AAAA,UAChC,OAAgBM,EAAAc,CAAA;AAAA;YAAscP,EAAM;AAAA,UAAA;AAAA;qBAO7d,MAAQ;AAAA,YAARH,EAAQC,EAAA,QAAA,SAAA;AAAA,UAAA;;;;;;;;"}