@evixcard/evx-ui-kit 1.5.0 → 1.7.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,3 +1,4 @@
1
+ import { EvFieldSize } from '../EvSelectBase/fieldSize';
1
2
  import { EvComboboxOption } from './types';
2
3
  type __VLS_Props = {
3
4
  options: EvComboboxOption[];
@@ -9,6 +10,8 @@ type __VLS_Props = {
9
10
  label?: string;
10
11
  /** Title rendered in the menu header. Omit to hide the header. */
11
12
  headerTitle?: string;
13
+ /** Trigger height — sm ≈40 / md ≈42 (default) / lg ≈56. */
14
+ size?: EvFieldSize;
12
15
  /** Show a "Clear" action in the menu header that resets the selection. */
13
16
  clearable?: boolean;
14
17
  /** Text shown when the search yields no matches. */
@@ -42,6 +45,7 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_PublicProps,
42
45
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
43
46
  "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
44
47
  }>, {
48
+ size: EvFieldSize;
45
49
  disabled: boolean;
46
50
  placeholder: string;
47
51
  error: boolean;
@@ -10,5 +10,14 @@ export declare const FlagEUR: Component;
10
10
  export declare const FlagUSD: Component;
11
11
  export declare const FlagGBP: Component;
12
12
  export declare const FlagJPY: Component;
13
+ export declare const FlagMXN: Component;
14
+ /**
15
+ * Neutral globe used for any currency without a dedicated flag illustration, so
16
+ * the toggle never renders an icon-less, ragged option. Grey (not national
17
+ * colours) — it reads as "other / international".
18
+ */
19
+ export declare const FlagFallback: Component;
13
20
  /** Returns the flag component for a currency code, or undefined if unknown. */
14
21
  export declare function flagFor(code: string): Component | undefined;
22
+ /** Always returns a renderable flag — the dedicated illustration or a neutral fallback. */
23
+ export declare function currencyFlag(code: string): Component;
@@ -11,8 +11,18 @@ declare const _default: <T extends Record<string, unknown> = Record<string, unkn
11
11
  slots: Partial<Record<`cell-${string}`, (_: {
12
12
  row: T;
13
13
  value: unknown;
14
+ }) => any>> & Partial<Record<`cell-${string}`, (_: {
15
+ row: T;
16
+ value: unknown;
17
+ }) => any>> & Partial<Record<`cell-${string}`, (_: {
18
+ row: T;
19
+ value: unknown;
20
+ }) => any>> & Partial<Record<`cell-${string}`, (_: {
21
+ row: T;
22
+ value: unknown;
14
23
  }) => any>> & {
15
24
  empty?(_: {}): any;
25
+ empty?(_: {}): any;
16
26
  };
17
27
  emit: ((evt: "sort", field: string, direction: "desc" | "asc") => void) & ((evt: "update:page", page: number) => void) & ((evt: "row-click", row: T) => void) & ((evt: "update:selectedKeys", keys: (string | number)[]) => void);
18
28
  }>) => import('vue').VNode & {
@@ -14,4 +14,19 @@ export interface EvDataTableProps<T extends Record<string, unknown> = Record<str
14
14
  selectable?: boolean;
15
15
  selectedKeys?: (string | number)[];
16
16
  rowKey?: string;
17
+ /**
18
+ * How the table renders on narrow (< lg) viewports.
19
+ * - 'auto' (default): show a Card/Table segmented toggle; default to cards.
20
+ * - 'cards': always cards under lg (no toggle).
21
+ * - 'table': keep the horizontally-scrolling table (legacy behaviour).
22
+ * Desktop (lg+) always renders the table.
23
+ */
24
+ mobileLayout?: 'auto' | 'cards' | 'table';
25
+ /** Column key used as the card title in card layout. Defaults to the first column. */
26
+ cardTitleKey?: string;
27
+ /**
28
+ * Accessible-name builder for the per-row selection checkbox (card + table).
29
+ * Defaults to `Select <rowKey value>`. The header select-all is always "Select all".
30
+ */
31
+ selectionLabel?: (row: T) => string;
17
32
  }
@@ -1,8 +1,11 @@
1
+ import { EvFieldSize } from '../EvSelectBase/fieldSize';
1
2
  type __VLS_Props = {
2
3
  placeholder?: string;
3
4
  disabled?: boolean;
4
5
  error?: boolean;
5
6
  label?: string;
7
+ /** Trigger height — sm ≈40 / md ≈42 (default) / lg ≈56. */
8
+ size?: EvFieldSize;
6
9
  class?: string;
7
10
  /** Lower bound, inclusive — ISO 'YYYY-MM-DD'. */
8
11
  min?: string | null;
@@ -17,6 +20,7 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
17
20
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
18
21
  "onUpdate:modelValue"?: ((value: string | null) => any) | undefined;
19
22
  }>, {
23
+ size: EvFieldSize;
20
24
  disabled: boolean;
21
25
  placeholder: string;
22
26
  error: boolean;
@@ -36,14 +36,14 @@ declare const __VLS_component: import('vue').DefineComponent<__VLS_Props, {
36
36
  input: (value: Event) => any;
37
37
  "update:modelValue": (value: string | number | null) => any;
38
38
  change: (value: Event) => any;
39
- focus: (value: FocusEvent) => any;
40
39
  blur: (value: FocusEvent) => any;
40
+ focus: (value: FocusEvent) => any;
41
41
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
42
42
  onInput?: ((value: Event) => any) | undefined;
43
43
  "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
44
44
  onChange?: ((value: Event) => any) | undefined;
45
- onFocus?: ((value: FocusEvent) => any) | undefined;
46
45
  onBlur?: ((value: FocusEvent) => any) | undefined;
46
+ onFocus?: ((value: FocusEvent) => any) | undefined;
47
47
  }>, {
48
48
  size: EvInputSize;
49
49
  type: InputType;
@@ -1,6 +1,7 @@
1
1
  export declare const variants: {
2
- md: string;
3
2
  sm: string;
3
+ md: string;
4
+ lg: string;
4
5
  };
5
- export declare const containerBaseClasses = "\n w-full cursor-text\n flex items-center\n gap-4\n bg-white text-black\n border border-[#F1F1F1]\n outline-none\n transition-colors\n focus-within:border-[#888A8D]\n";
6
- export declare const inputBaseClasses = "\n flex-1\n bg-transparent\n border-0 outline-none\n placeholder:text-[#8C8C8C]\n !leading-[12px]\n text-[14px]\n disabled:cursor-not-allowed\n";
6
+ export declare const containerBaseClasses = "\n w-full cursor-text\n flex items-center\n gap-4\n bg-white text-black\n border border-[color:var(--ev-input-border,#F1F1F1)]\n outline-none\n transition-colors\n focus-within:border-[color:var(--ev-input-focus,#888A8D)]\n";
7
+ export declare const inputBaseClasses = "\n flex-1\n bg-transparent\n border-0 outline-none\n placeholder:text-[#8C8C8C]\n text-[16px]\n disabled:cursor-not-allowed\n";
@@ -23,11 +23,11 @@ declare function __VLS_template(): {
23
23
  };
24
24
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
25
25
  declare const __VLS_component: import('vue').DefineComponent<Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
26
- open: () => any;
27
26
  close: () => any;
27
+ open: () => any;
28
28
  }, string, import('vue').PublicProps, Readonly<Props> & Readonly<{
29
- onOpen?: (() => any) | undefined;
30
29
  onClose?: (() => any) | undefined;
30
+ onOpen?: (() => any) | undefined;
31
31
  }>, {
32
32
  align: EvMenuAlign;
33
33
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
@@ -4,6 +4,14 @@ export interface EvModalProps {
4
4
  title: string;
5
5
  size?: EvModalSize;
6
6
  closable?: boolean;
7
+ /**
8
+ * Where to move focus when the modal opens.
9
+ * - 'first' (default): the first focusable element in the panel.
10
+ * - 'none': leave focus on the panel container (no autofocus of a control).
11
+ * - any other string: treated as a CSS selector queried within the panel
12
+ * (e.g. '[data-autofocus]'); falls back to 'first' if nothing matches.
13
+ */
14
+ initialFocus?: 'first' | 'none' | string;
7
15
  }
8
16
  declare function __VLS_template(): {
9
17
  attrs: Partial<{}>;
@@ -24,6 +32,7 @@ declare const __VLS_component: import('vue').DefineComponent<EvModalProps, {}, {
24
32
  onClose?: (() => any) | undefined;
25
33
  }>, {
26
34
  size: EvModalSize;
35
+ initialFocus: "first" | "none" | string;
27
36
  closable: boolean;
28
37
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
29
38
  containerRef: HTMLDivElement;
@@ -1,3 +1,4 @@
1
+ import { EvFieldSize } from '../EvSelectBase/fieldSize';
1
2
  import { EvMultiSelectOption, EvMultiSelectValue } from './types';
2
3
  type __VLS_Props = {
3
4
  options: EvMultiSelectOption[];
@@ -6,6 +7,8 @@ type __VLS_Props = {
6
7
  disabled?: boolean;
7
8
  error?: boolean;
8
9
  label?: string;
10
+ /** Control min-height — sm ≈40 / md ≈42 (default) / lg ≈56. Grows with chips. */
11
+ size?: EvFieldSize;
9
12
  class?: string;
10
13
  };
11
14
  type __VLS_PublicProps = {
@@ -16,11 +19,13 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
16
19
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
17
20
  "onUpdate:modelValue"?: ((value: EvMultiSelectValue[]) => any) | undefined;
18
21
  }>, {
22
+ size: EvFieldSize;
19
23
  disabled: boolean;
20
24
  placeholder: string;
21
25
  error: boolean;
22
26
  searchable: boolean;
23
27
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
24
28
  root: HTMLDivElement;
29
+ panelRef: HTMLDivElement;
25
30
  }, any>;
26
31
  export default _default;
@@ -42,8 +42,8 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
42
42
  readonly onInput?: ((value: Event) => any) | undefined;
43
43
  readonly "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
44
44
  readonly onChange?: ((value: Event) => any) | undefined;
45
- readonly onFocus?: ((value: FocusEvent) => any) | undefined;
46
45
  readonly onBlur?: ((value: FocusEvent) => any) | undefined;
46
+ readonly onFocus?: ((value: FocusEvent) => any) | undefined;
47
47
  } & import('vue').VNodeProps & import('vue').AllowedComponentProps & import('vue').ComponentCustomProps;
48
48
  $attrs: {
49
49
  [x: string]: unknown;
@@ -59,7 +59,7 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
59
59
  $root: import('vue').ComponentPublicInstance | null;
60
60
  $parent: import('vue').ComponentPublicInstance | null;
61
61
  $host: Element | null;
62
- $emit: ((event: "input", value: Event) => void) & ((event: "update:modelValue", value: string | number | null) => void) & ((event: "change", value: Event) => void) & ((event: "focus", value: FocusEvent) => void) & ((event: "blur", value: FocusEvent) => void);
62
+ $emit: ((event: "input", value: Event) => void) & ((event: "update:modelValue", value: string | number | null) => void) & ((event: "change", value: Event) => void) & ((event: "blur", value: FocusEvent) => void) & ((event: "focus", value: FocusEvent) => void);
63
63
  $el: any;
64
64
  $options: import('vue').ComponentOptionsBase<Readonly<{
65
65
  modelValue?: string | number | null;
@@ -81,8 +81,8 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
81
81
  onInput?: ((value: Event) => any) | undefined;
82
82
  "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
83
83
  onChange?: ((value: Event) => any) | undefined;
84
- onFocus?: ((value: FocusEvent) => any) | undefined;
85
84
  onBlur?: ((value: FocusEvent) => any) | undefined;
85
+ onFocus?: ((value: FocusEvent) => any) | undefined;
86
86
  }>, {
87
87
  focus: () => void;
88
88
  blur: () => void | undefined;
@@ -91,8 +91,8 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
91
91
  input: (value: Event) => any;
92
92
  "update:modelValue": (value: string | number | null) => any;
93
93
  change: (value: Event) => any;
94
- focus: (value: FocusEvent) => any;
95
94
  blur: (value: FocusEvent) => any;
95
+ focus: (value: FocusEvent) => any;
96
96
  }, string, {
97
97
  size: EvInputSize;
98
98
  type: import('../EvInput').InputType;
@@ -143,9 +143,9 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
143
143
  onInput?: ((value: Event) => any) | undefined;
144
144
  "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
145
145
  onChange?: ((value: Event) => any) | undefined;
146
- onFocus?: ((value: FocusEvent) => any) | undefined;
147
146
  onBlur?: ((value: FocusEvent) => any) | undefined;
148
- }>, "select" | "focus" | "blur" | ("size" | "type" | "disabled" | "required")> & import('vue').ShallowUnwrapRef<{
147
+ onFocus?: ((value: FocusEvent) => any) | undefined;
148
+ }>, "select" | "blur" | "focus" | ("size" | "type" | "disabled" | "required")> & import('vue').ShallowUnwrapRef<{
149
149
  focus: () => void;
150
150
  blur: () => void | undefined;
151
151
  select: () => void | undefined;
@@ -14,9 +14,12 @@ type __VLS_Props = {
14
14
  class?: string;
15
15
  selectClass?: string;
16
16
  /**
17
- * Opt-in custom dropdown with a filterable text input. When `false`
18
- * (default) the component renders the native `<select>` exactly as before.
17
+ * Escape hatch: render the platform-native `<select>` instead of the kit's
18
+ * custom dropdown. Default `false` — the custom styled dropdown is the default
19
+ * (its open list can be themed, unlike the OS-rendered native one).
19
20
  */
21
+ native?: boolean;
22
+ /** Show a filterable text input inside the custom dropdown. */
20
23
  searchable?: boolean;
21
24
  /** Placeholder for the filter input shown in `searchable` mode. */
22
25
  searchPlaceholder?: string;
@@ -26,17 +29,18 @@ type __VLS_Props = {
26
29
  declare const _default: import('vue').DefineComponent<__VLS_Props, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {} & {
27
30
  "update:modelValue": (value: string | number | null) => any;
28
31
  change: (value: Event) => any;
29
- focus: (value: FocusEvent) => any;
30
32
  blur: (value: FocusEvent) => any;
33
+ focus: (value: FocusEvent) => any;
31
34
  }, string, import('vue').PublicProps, Readonly<__VLS_Props> & Readonly<{
32
35
  "onUpdate:modelValue"?: ((value: string | number | null) => any) | undefined;
33
36
  onChange?: ((value: Event) => any) | undefined;
34
- onFocus?: ((value: FocusEvent) => any) | undefined;
35
37
  onBlur?: ((value: FocusEvent) => any) | undefined;
38
+ onFocus?: ((value: FocusEvent) => any) | undefined;
36
39
  }>, {
37
40
  size: EvSelectSize;
38
41
  disabled: boolean;
39
42
  required: boolean;
43
+ native: boolean;
40
44
  searchable: boolean;
41
45
  searchPlaceholder: string;
42
46
  noResultsText: string;
@@ -1,4 +1,4 @@
1
- export type EvSelectSize = 'sm' | 'md';
1
+ export type { EvFieldSize as EvSelectSize } from '../EvSelectBase/fieldSize';
2
2
  export interface EvSelectOption {
3
3
  value: string | number;
4
4
  label: string;
@@ -0,0 +1,5 @@
1
+ export type EvFieldSize = 'sm' | 'md' | 'lg';
2
+ /** Fixed-height triggers — single-line value (EvSelect, EvDatePicker). */
3
+ export declare const FIELD_HEIGHT: Record<EvFieldSize, string>;
4
+ /** Minimum-height controls that grow with content (EvMultiSelect, EvTagInput, EvComboboxSelect). */
5
+ export declare const FIELD_MIN_HEIGHT: Record<EvFieldSize, string>;
@@ -0,0 +1,67 @@
1
+ import { MaybeRefOrGetter, Ref } from 'vue';
2
+ /**
3
+ * Shared dropdown engine for the kit's select family (EvSelect / EvMultiSelect /
4
+ * EvComboboxSelect). It owns the behaviour the three components used to duplicate:
5
+ * open/close, substring filtering, roving keyboard navigation, outside-click
6
+ * dismissal, focus management, scroll-active-into-view and value matching.
7
+ *
8
+ * Each component keeps its OWN template (chips / checkbox rows / title+meta rows,
9
+ * teleport vs inline panel) and just wires it to the state + handlers returned here.
10
+ *
11
+ * a11y baseline (DEV-604): roving Arrow navigation + Space/Enter selection + an
12
+ * `activeIndex` for aria-activedescendant are provided here, so EvSelect and
13
+ * EvMultiSelect gain the keyboard navigation they previously lacked (only
14
+ * EvComboboxSelect had it). The search semantics stay the kit's own substring
15
+ * `includes()` (or a per-component `filterPredicate`) — NOT headlessui's startsWith
16
+ * type-ahead — to preserve the multi-field (title+meta) search contract.
17
+ */
18
+ export type SelectPrimitive = string | number;
19
+ export interface UseSelectFieldConfig<T> {
20
+ /** Reactive source list of option objects. */
21
+ options: Ref<T[]>;
22
+ /** Stable primitive value of an option (used for selection + keys). */
23
+ getValue: (option: T) => SelectPrimitive;
24
+ /** Text matched against the query in searchable mode (e.g. label, or title+meta). */
25
+ getFilterText: (option: T) => string;
26
+ /** Custom match predicate; overrides getFilterText. Receives the lowercased query. */
27
+ filterPredicate?: (option: T, query: string) => boolean;
28
+ /** Whether an option is non-selectable. Defaults to never-disabled. */
29
+ isDisabled?: (option: T) => boolean;
30
+ /** Field-level disabled — blocks opening. */
31
+ disabled: Ref<boolean>;
32
+ /** Current selection for highlight/aria: a single value, an array, or null. */
33
+ selected: Ref<SelectPrimitive | SelectPrimitive[] | null | undefined>;
34
+ /** Called when a non-disabled option is chosen; the component updates its model. */
35
+ onPick: (option: T) => void;
36
+ /** Multi-select: selection toggles and the menu stays open. Default false. */
37
+ multiple?: boolean;
38
+ /** A filter input lives in the panel and drives `query`/`filtered`. Reactive; default false. */
39
+ searchable?: MaybeRefOrGetter<boolean>;
40
+ /** Close after a pick. Defaults to `!multiple` (single closes, multi stays open). */
41
+ closeOnSelect?: boolean;
42
+ /** Return focus to the trigger on close (EvSelect contract). Default false. */
43
+ returnFocusOnClose?: boolean;
44
+ /** Move focus into the panel search input on open. Defaults to `searchable`. */
45
+ focusSearchOnOpen?: boolean;
46
+ /** Value equality. Defaults to String()-coercion (matches EvSelect's behaviour). */
47
+ by?: (a: SelectPrimitive, b: SelectPrimitive) => boolean;
48
+ }
49
+ export declare function useSelectField<T>(cfg: UseSelectFieldConfig<T>): {
50
+ open: Ref<boolean, boolean>;
51
+ query: Ref<string, string>;
52
+ activeIndex: Ref<number, number>;
53
+ filtered: import('vue').ComputedRef<T[]>;
54
+ rootRef: Ref<HTMLElement | null, HTMLElement | null>;
55
+ triggerRef: Ref<HTMLElement | null, HTMLElement | null>;
56
+ panelRef: Ref<HTMLElement | null, HTMLElement | null>;
57
+ searchRef: Ref<HTMLInputElement | null, HTMLInputElement | null>;
58
+ isSelected: (option: T) => boolean;
59
+ optionDisabled: (o: T) => boolean;
60
+ openMenu: () => void;
61
+ closeMenu: (returnFocus?: boolean) => void;
62
+ toggle: () => void;
63
+ pick: (option: T) => void;
64
+ moveActive: (delta: number) => void;
65
+ onTriggerKeydown: (e: KeyboardEvent) => void;
66
+ onListKeydown: (e: KeyboardEvent) => void;
67
+ };
@@ -15,6 +15,12 @@ export interface EvTabsProps {
15
15
  modelValue?: number;
16
16
  /** Initial active tab index when uncontrolled (no `modelValue`). Defaults to 0. */
17
17
  defaultTab?: number;
18
+ /**
19
+ * Pill variant only: render the default white plate (`bg-white p-3`) around the
20
+ * panel content. Off by default — most consumers fill the panel themselves and
21
+ * the extra backing reads as a stray box.
22
+ */
23
+ panelBacking?: boolean;
18
24
  }
19
25
  declare function __VLS_template(): {
20
26
  attrs: Partial<{}>;
@@ -23,7 +29,9 @@ declare function __VLS_template(): {
23
29
  }) => any>> & Partial<Record<`tab-${number}`, (_: {
24
30
  tab: TabItem;
25
31
  }) => any>>;
26
- refs: {};
32
+ refs: {
33
+ tabListRef: HTMLDivElement;
34
+ };
27
35
  rootEl: any;
28
36
  };
29
37
  type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
@@ -35,7 +43,10 @@ declare const __VLS_component: import('vue').DefineComponent<EvTabsProps, {}, {}
35
43
  size: "sm" | "md" | "lg";
36
44
  variant: "pill" | "underline";
37
45
  defaultTab: number;
38
- }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;
46
+ panelBacking: boolean;
47
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
48
+ tabListRef: HTMLDivElement;
49
+ }, any>;
39
50
  declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
40
51
  export default _default;
41
52
  type __VLS_WithTemplateSlots<T, S> = T & {
@@ -1,6 +1,9 @@
1
+ import { EvFieldSize } from '../EvSelectBase/fieldSize';
1
2
  type __VLS_Props = {
2
3
  suggestions?: string[];
3
4
  placeholder?: string;
5
+ /** Box min-height — sm ≈40 / md ≈42 (default) / lg ≈56. Grows with chips. */
6
+ size?: EvFieldSize;
4
7
  class?: string;
5
8
  };
6
9
  type __VLS_PublicProps = {
@@ -13,6 +16,7 @@ declare const _default: import('vue').DefineComponent<__VLS_PublicProps, {}, {},
13
16
  }, string, import('vue').PublicProps, Readonly<__VLS_PublicProps> & Readonly<{
14
17
  "onUpdate:modelValue"?: ((value: string[]) => any) | undefined;
15
18
  }>, {
19
+ size: EvFieldSize;
16
20
  placeholder: string;
17
21
  suggestions: string[];
18
22
  }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, any>;