@svelte-atoms/core 1.0.0-alpha.31 → 1.0.0-alpha.33

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.
Files changed (136) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +289 -853
  3. package/dist/attachments/index.d.ts +1 -0
  4. package/dist/attachments/index.js +1 -0
  5. package/dist/components/accordion/accordion-root.svelte +65 -65
  6. package/dist/components/accordion/accordion.stories.svelte +70 -70
  7. package/dist/components/accordion/item/accordion-item-body.svelte +44 -44
  8. package/dist/components/accordion/item/accordion-item-header.svelte +51 -51
  9. package/dist/components/accordion/item/accordion-item-indicator.svelte +51 -51
  10. package/dist/components/accordion/item/accordion-item-root.svelte +66 -66
  11. package/dist/components/alert/alert-close-button.svelte +66 -66
  12. package/dist/components/alert/alert-description.svelte +42 -42
  13. package/dist/components/alert/alert-root.svelte +68 -68
  14. package/dist/components/atom/html-atom.svelte +26 -194
  15. package/dist/components/atom/types.d.ts +3 -2
  16. package/dist/components/atom/utils.d.ts +37 -0
  17. package/dist/components/atom/utils.js +208 -0
  18. package/dist/components/breadcrumb/breadcrumb-item.svelte +1 -1
  19. package/dist/components/breadcrumb/breadcrumb-separator.svelte +5 -1
  20. package/dist/components/breadcrumb/breadcrumb.stories.svelte +16 -16
  21. package/dist/components/calendar/calendar-day.svelte +101 -101
  22. package/dist/components/checkbox/checkbox.svelte +159 -159
  23. package/dist/components/collapsible/bond.svelte.js +2 -1
  24. package/dist/components/collapsible/collapsible-body.svelte +3 -2
  25. package/dist/components/collapsible/motion.svelte.d.ts +6 -0
  26. package/dist/components/collapsible/motion.svelte.js +15 -0
  27. package/dist/components/combobox/atoms.d.ts +3 -3
  28. package/dist/components/combobox/atoms.js +3 -3
  29. package/dist/components/combobox/bond.svelte.d.ts +6 -6
  30. package/dist/components/combobox/bond.svelte.js +3 -26
  31. package/dist/components/combobox/combobox-control.svelte +52 -52
  32. package/dist/components/combobox/{compobox-item.svelte → combobox-item.svelte} +62 -68
  33. package/dist/components/combobox/combobox-item.svelte.d.ts +12 -0
  34. package/dist/components/combobox/combobox.stories.svelte +50 -0
  35. package/dist/components/combobox/combobox.stories.svelte.d.ts +3 -0
  36. package/dist/components/datagrid/tr/datagrid-tr.svelte +90 -90
  37. package/dist/components/date-picker/bond.svelte.d.ts +15 -5
  38. package/dist/components/date-picker/bond.svelte.js +6 -11
  39. package/dist/components/date-picker/date-picker-calendar.svelte +1 -8
  40. package/dist/components/dialog/bond.svelte.js +5 -20
  41. package/dist/components/dialog/dialog-content.svelte +44 -44
  42. package/dist/components/dialog/dialog-root.svelte +91 -91
  43. package/dist/components/drawer/bond.svelte.d.ts +18 -16
  44. package/dist/components/drawer/bond.svelte.js +8 -18
  45. package/dist/components/drawer/drawer-content.svelte +49 -49
  46. package/dist/components/drawer/drawer-root.svelte +5 -4
  47. package/dist/components/drawer/drawer.stories.svelte +141 -144
  48. package/dist/components/drawer/motion.js +1 -1
  49. package/dist/components/dropdown/atoms.d.ts +1 -1
  50. package/dist/components/dropdown/atoms.js +1 -1
  51. package/dist/components/dropdown/bond.svelte.d.ts +21 -22
  52. package/dist/components/dropdown/bond.svelte.js +29 -53
  53. package/dist/components/dropdown/dropdown-root.svelte +65 -59
  54. package/dist/components/dropdown/dropdown-values.svelte +17 -17
  55. package/dist/components/dropdown/dropdown-values.svelte.d.ts +1 -2
  56. package/dist/components/dropdown/dropdown.stories.svelte +83 -80
  57. package/dist/components/dropdown/index.d.ts +1 -0
  58. package/dist/components/dropdown/index.js +1 -0
  59. package/dist/components/dropdown/item/attachments.svelte.d.ts +2 -2
  60. package/dist/components/dropdown/item/attachments.svelte.js +2 -2
  61. package/dist/components/dropdown/item/controller.svelte.d.ts +34 -0
  62. package/dist/components/dropdown/item/controller.svelte.js +82 -0
  63. package/dist/components/dropdown/item/dropdown-item.svelte +109 -102
  64. package/dist/components/dropdown/item/dropdown-item.svelte.d.ts +13 -28
  65. package/dist/components/dropdown/item/index.d.ts +3 -0
  66. package/dist/components/dropdown/item/index.js +3 -0
  67. package/dist/components/dropdown/item/types.d.ts +29 -0
  68. package/dist/components/dropdown/item/types.js +1 -0
  69. package/dist/components/list/list-item.svelte +20 -20
  70. package/dist/components/menu/atoms.d.ts +8 -3
  71. package/dist/components/menu/atoms.js +8 -3
  72. package/dist/components/menu/bond.svelte.d.ts +54 -0
  73. package/dist/components/menu/bond.svelte.js +132 -0
  74. package/dist/components/menu/index.d.ts +1 -0
  75. package/dist/components/menu/index.js +1 -0
  76. package/dist/components/menu/item/controller.svelte.d.ts +26 -0
  77. package/dist/components/menu/item/controller.svelte.js +69 -0
  78. package/dist/components/menu/item/index.d.ts +2 -0
  79. package/dist/components/menu/item/index.js +2 -0
  80. package/dist/components/menu/item/menu-item.svelte +103 -0
  81. package/dist/components/menu/item/menu-item.svelte.d.ts +31 -0
  82. package/dist/components/menu/item/types.d.ts +62 -0
  83. package/dist/components/menu/item/types.js +1 -0
  84. package/dist/components/menu/{menu-list.svelte → menu-content.svelte} +40 -40
  85. package/dist/components/menu/{menu-list.svelte.d.ts → menu-content.svelte.d.ts} +3 -3
  86. package/dist/components/menu/menu-root.svelte +15 -0
  87. package/dist/components/menu/menu-root.svelte.d.ts +8 -0
  88. package/dist/components/menu/menu.stories.svelte +33 -33
  89. package/dist/components/menu/types.d.ts +0 -7
  90. package/dist/components/popover/bond.svelte.d.ts +11 -14
  91. package/dist/components/popover/bond.svelte.js +27 -44
  92. package/dist/components/popover/popover-content.svelte +137 -137
  93. package/dist/components/popover/popover.stories.svelte +37 -49
  94. package/dist/components/portal/active-portal.svelte +29 -29
  95. package/dist/components/portal/portal-root.svelte +76 -76
  96. package/dist/components/portal/teleport.svelte +49 -49
  97. package/dist/components/radio/radio.svelte +109 -109
  98. package/dist/components/root/index.d.ts +1 -0
  99. package/dist/components/root/index.js +1 -0
  100. package/dist/components/root/l0-portal.svelte +8 -0
  101. package/dist/components/root/l0-portal.svelte.d.ts +26 -0
  102. package/dist/components/root/l1-portal.svelte +7 -0
  103. package/dist/components/root/l1-portal.svelte.d.ts +26 -0
  104. package/dist/components/root/root.css +119 -119
  105. package/dist/components/root/root.svelte +17 -18
  106. package/dist/components/root/root.svelte.d.ts +2 -6
  107. package/dist/components/root/toasts-portal.svelte +7 -0
  108. package/dist/components/root/toasts-portal.svelte.d.ts +26 -0
  109. package/dist/components/root/types.d.ts +17 -0
  110. package/dist/components/sidebar/motion.svelte.js +3 -3
  111. package/dist/components/sidebar/sidebar-content.svelte +40 -40
  112. package/dist/components/textarea/textarea-input.svelte +9 -9
  113. package/dist/components/textarea/textarea-root.svelte +9 -9
  114. package/dist/components/tooltip/tooltip-trigger.svelte +39 -39
  115. package/dist/components/tree/index.d.ts +1 -0
  116. package/dist/components/tree/index.js +1 -0
  117. package/dist/components/tree/motion.svelte.d.ts +6 -0
  118. package/dist/components/tree/motion.svelte.js +14 -0
  119. package/dist/components/tree/tree-body.svelte +4 -3
  120. package/dist/context/preset.svelte.d.ts +3 -1
  121. package/dist/icons/icon-copy.svelte +6 -6
  122. package/dist/utils/dom.svelte.d.ts +2 -0
  123. package/dist/utils/dom.svelte.js +21 -0
  124. package/dist/utils/function.d.ts +1 -1
  125. package/dist/utils/promise.svelte.d.ts +5 -0
  126. package/dist/utils/promise.svelte.js +20 -0
  127. package/package.json +4 -2
  128. package/dist/components/combobox/compobox-item.svelte.d.ts +0 -34
  129. package/dist/components/combobox/compobox.stories.svelte +0 -51
  130. package/dist/components/combobox/compobox.stories.svelte.d.ts +0 -3
  131. package/dist/components/dropdown/item/bond.svelte.d.ts +0 -42
  132. package/dist/components/dropdown/item/bond.svelte.js +0 -99
  133. package/dist/components/menu/menu-item.svelte +0 -69
  134. package/dist/components/menu/menu-item.svelte.d.ts +0 -37
  135. package/dist/utils/markdown-to-llm.d.ts +0 -28
  136. package/dist/utils/markdown-to-llm.js +0 -76
@@ -1,40 +1,40 @@
1
- <script lang="ts" generics="T extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
- import { List } from '../list';
3
- import { Content } from '../popover/atoms';
4
- import type { Base } from '../atom';
5
- import { PopoverBond } from '../popover';
6
-
7
- const bond = PopoverBond.get();
8
-
9
- let {
10
- class: klass = '',
11
- as = 'ul' as T,
12
- base = List.Root as B,
13
- preset = 'menu.list',
14
- children = undefined,
15
- onmount = undefined,
16
- ondestroy = undefined,
17
- animate = undefined,
18
- enter = undefined,
19
- exit = undefined,
20
- initial = undefined,
21
- ...restProps
22
- } = $props();
23
- </script>
24
-
25
- <Content
26
- {as}
27
- {base}
28
- {bond}
29
- {preset}
30
- class={['bg-background border-border overflow-hidden p-0', '$preset', klass]}
31
- onmount={onmount?.bind(bond.state)}
32
- ondestroy={ondestroy?.bind(bond.state)}
33
- enter={enter?.bind(bond.state)}
34
- exit={exit?.bind(bond.state)}
35
- initial={initial?.bind(bond.state)}
36
- animate={animate?.bind(bond.state)}
37
- {...restProps}
38
- >
39
- {@render children?.()}
40
- </Content>
1
+ <script lang="ts" generics="T extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base">
2
+ import { Content } from '../popover/atoms';
3
+ import type { Base } from '../atom';
4
+ import { MenuBond } from './bond.svelte';
5
+ import { Root } from '../list/atoms';
6
+
7
+ const bond = MenuBond.get();
8
+
9
+ let {
10
+ class: klass = '',
11
+ as = 'ul' as T,
12
+ base = Root as B,
13
+ preset = 'menu.content',
14
+ children = undefined,
15
+ onmount = undefined,
16
+ ondestroy = undefined,
17
+ animate = undefined,
18
+ enter = undefined,
19
+ exit = undefined,
20
+ initial = undefined,
21
+ ...restProps
22
+ } = $props();
23
+ </script>
24
+
25
+ <Content
26
+ {as}
27
+ {base}
28
+ {bond}
29
+ {preset}
30
+ class={['border-border overflow-hidden p-0', '$preset', klass]}
31
+ onmount={onmount?.bind(bond.state)}
32
+ ondestroy={ondestroy?.bind(bond.state)}
33
+ enter={enter?.bind(bond.state)}
34
+ exit={exit?.bind(bond.state)}
35
+ initial={initial?.bind(bond.state)}
36
+ animate={animate?.bind(bond.state)}
37
+ {...restProps}
38
+ >
39
+ {@render children?.()}
40
+ </Content>
@@ -32,6 +32,6 @@ interface $$IsomorphicComponent {
32
32
  <T extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base>(internal: unknown, props: ReturnType<__sveltets_Render<T, B>['props']> & {}): ReturnType<__sveltets_Render<T, B>['exports']>;
33
33
  z_$$bindings?: ReturnType<__sveltets_Render<any, any>['bindings']>;
34
34
  }
35
- declare const MenuList: $$IsomorphicComponent;
36
- type MenuList<T extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base> = InstanceType<typeof MenuList<T, B>>;
37
- export default MenuList;
35
+ declare const MenuContent: $$IsomorphicComponent;
36
+ type MenuContent<T extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base> = InstanceType<typeof MenuContent<T, B>>;
37
+ export default MenuContent;
@@ -0,0 +1,15 @@
1
+ <script lang="ts">
2
+ import { MenuBond, MenuBondState, type MenuBondProps } from './bond.svelte';
3
+ import { Root } from '../popover/atoms';
4
+
5
+ let { open = $bindable(false), factory = _factory, children, ...restProps } = $props();
6
+
7
+ function _factory(props: MenuBondProps) {
8
+ const menuBondState = new MenuBondState(() => props);
9
+ return new MenuBond(menuBondState);
10
+ }
11
+ </script>
12
+
13
+ <Root bind:open {factory} {...restProps}>
14
+ {@render children?.()}
15
+ </Root>
@@ -0,0 +1,8 @@
1
+ import { MenuBond, MenuBondState, type MenuBondProps } from './bond.svelte';
2
+ declare const MenuRoot: import("svelte").Component<{
3
+ open?: boolean;
4
+ factory?: (props: MenuBondProps) => MenuBond<MenuBondProps, MenuBondState<MenuBondProps>, import(".").PopoverDomElements>;
5
+ children: any;
6
+ } & Record<string, any>, {}, "open">;
7
+ type MenuRoot = ReturnType<typeof MenuRoot>;
8
+ export default MenuRoot;
@@ -1,33 +1,33 @@
1
- <script module>
2
- import { defineMeta } from '@storybook/addon-svelte-csf';
3
- import { Menu as AMenu } from '.';
4
- import { Button } from '../button';
5
-
6
- // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
- const { Story } = defineMeta({
8
- title: 'Atoms/Menu',
9
- // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
10
-
11
- parameters: {
12
- // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
13
- layout: 'fullscreen'
14
- },
15
- args: {}
16
- });
17
- </script>
18
-
19
- <script lang="ts">
20
- let open = $state(false);
21
- </script>
22
-
23
- <Story name="Menu" args={{}}>
24
- <AMenu.Root bind:open offset={4}>
25
- <AMenu.Trigger base={Button}>Select a language</AMenu.Trigger>
26
- <AMenu.List>
27
- <AMenu.Item>Arabic</AMenu.Item>
28
- <AMenu.Item>English</AMenu.Item>
29
- <AMenu.Item>Spanish</AMenu.Item>
30
- <AMenu.Item>Italian</AMenu.Item>
31
- </AMenu.List>
32
- </AMenu.Root>
33
- </Story>
1
+ <script module>
2
+ import { defineMeta } from '@storybook/addon-svelte-csf';
3
+ import { Menu as AMenu } from '.';
4
+ import { Button } from '../button';
5
+
6
+ // More on how to set up stories at: https://storybook.js.org/docs/writing-stories
7
+ const { Story } = defineMeta({
8
+ title: 'Atoms/Menu',
9
+ // This component will have an automatically generated Autodocs entry: https://storybook.js.org/docs/writing-docs/autodocs
10
+
11
+ parameters: {
12
+ // More on how to position stories at: https://storybook.js.org/docs/configure/story-layout
13
+ layout: 'fullscreen'
14
+ },
15
+ args: {}
16
+ });
17
+ </script>
18
+
19
+ <script lang="ts">
20
+ let open = $state(false);
21
+ </script>
22
+
23
+ <Story name="Menu" args={{}}>
24
+ <AMenu.Root bind:open>
25
+ <AMenu.Trigger base={Button}>Select a language</AMenu.Trigger>
26
+ <AMenu.List>
27
+ <AMenu.Item onclick={() => console.log('Arabic')}>Arabic</AMenu.Item>
28
+ <AMenu.Item onclick={() => console.log('English')}>English</AMenu.Item>
29
+ <AMenu.Item onclick={() => console.log('Spanish')}>Spanish</AMenu.Item>
30
+ <AMenu.Item onclick={() => console.log('Italian')}>Italian</AMenu.Item>
31
+ </AMenu.List>
32
+ </AMenu.Root>
33
+ </Story>
@@ -1,15 +1,8 @@
1
1
  import type { HtmlAtomProps, Base } from '../atom';
2
- /**
3
- * Extend this interface to add custom menu item properties in your application.
4
- */
5
- export interface MenuItemExtendProps {
6
- }
7
2
  /**
8
3
  * Extend this interface to add custom menu list properties in your application.
9
4
  */
10
5
  export interface MenuListExtendProps {
11
6
  }
12
- export interface MenuItemProps<E extends keyof HTMLElementTagNameMap = 'button', B extends Base = Base> extends HtmlAtomProps<E, B>, MenuItemExtendProps {
13
- }
14
7
  export interface MenuListProps<E extends keyof HTMLElementTagNameMap = 'div', B extends Base = Base> extends HtmlAtomProps<E, B>, MenuListExtendProps {
15
8
  }
@@ -34,12 +34,8 @@ export declare class PopoverBond<Props extends PopoverStateProps = PopoverStateP
34
34
  static CONTEXT_KEY: string;
35
35
  position: ComputePositionReturn | undefined;
36
36
  constructor(state: State);
37
- trigger(props?: Record<string, unknown> & {
38
- onclick?: (ev: PointerEvent) => void;
39
- onkeydown?: (ev: KeyboardEvent) => void;
40
- }): {
41
- onclick: (ev: PointerEvent) => void;
42
- onkeydown: (ev: KeyboardEvent) => void;
37
+ trigger(): {
38
+ [x: symbol]: (node: HTMLElement) => (() => void) | undefined;
43
39
  id: string;
44
40
  role: string;
45
41
  disabled: boolean | undefined;
@@ -49,30 +45,31 @@ export declare class PopoverBond<Props extends PopoverStateProps = PopoverStateP
49
45
  'aria-controls': string;
50
46
  'aria-haspopup': string;
51
47
  'data-kind': string;
48
+ onclick: (ev: PointerEvent) => void;
49
+ onkeydown: (ev: KeyboardEvent) => void;
52
50
  };
53
- content(props?: Record<string, unknown> & {
54
- onchange?: (node: HTMLElement, position: ComputePositionReturn) => void;
55
- }): {
56
- onchange?: (node: HTMLElement, position: ComputePositionReturn) => void;
51
+ content(): {
52
+ [x: symbol]: (node: HTMLElement) => (() => void) | undefined;
57
53
  id: string;
58
54
  role: string;
59
55
  'aria-modal': boolean;
60
56
  'aria-labelledby': string;
61
- 'aria-hidden': boolean;
62
- inert: string | undefined;
57
+ inert: boolean | undefined;
63
58
  tabindex: number;
64
59
  'data-atom': string;
65
60
  'data-kind': string;
66
61
  'data-active': boolean;
67
62
  onkeydown: ((ev: KeyboardEvent) => void) | undefined;
68
63
  };
69
- indicator(props?: Record<string, unknown>): {
64
+ indicator(): {
65
+ [x: symbol]: (node: HTMLElement) => void;
70
66
  id: string;
71
67
  'aria-hidden': boolean;
72
68
  'aria-live': string;
73
69
  'data-kind': string;
74
70
  };
75
- arrow(props?: Record<string, unknown>): {
71
+ arrow(): {
72
+ [x: symbol]: (node: HTMLElement) => void;
76
73
  id: string;
77
74
  role: string;
78
75
  'aria-hidden': boolean;
@@ -1,7 +1,7 @@
1
1
  import { getContext, setContext, untrack } from 'svelte';
2
2
  import { createAttachmentKey } from 'svelte/attachments';
3
3
  import { autoUpdate, computePosition, arrow, flip, offset } from '@floating-ui/dom';
4
- import { getElementId, isBrowser } from '../../utils/dom.svelte.js';
4
+ import { focus, focusTrap, getElementId, isBrowser } from '../../utils/dom.svelte.js';
5
5
  import { Bond, BondState } from '../../shared/bond.svelte.js';
6
6
  const POPOVER_ELEMENTS_KIND = {
7
7
  trigger: 'popover-trigger',
@@ -15,7 +15,7 @@ export class PopoverBond extends Bond {
15
15
  constructor(state) {
16
16
  super(state);
17
17
  }
18
- trigger(props = {}) {
18
+ trigger() {
19
19
  const isButtonElement = isBrowser()
20
20
  ? this.elements.trigger instanceof HTMLButtonElement
21
21
  : false;
@@ -42,32 +42,29 @@ export class PopoverBond extends Bond {
42
42
  return;
43
43
  }
44
44
  this.state.toggle();
45
- props.onclick?.(ev);
46
45
  },
47
46
  onkeydown: (ev) => {
48
47
  if (isDisabled)
49
48
  return;
50
49
  // Toggle on Enter or Space
51
50
  if (ev.key === 'Enter' || ev.key === ' ') {
52
- ev.preventDefault();
53
51
  this.state.toggle();
54
- props.onkeydown?.(ev);
52
+ return;
53
+ }
54
+ if (ev.key === 'Tab') {
55
+ this.elements.content?.focus();
56
+ return;
55
57
  }
56
- // Close on Escape
57
- else if (ev.key === 'Escape' && isOpen) {
58
- ev.preventDefault();
58
+ if (ev.key === 'Escape') {
59
59
  this.state.close();
60
- props.onkeydown?.(ev);
61
60
  }
62
61
  },
63
- ...props,
64
62
  [createAttachmentKey()]: (node) => {
65
63
  this.elements.trigger = node;
66
64
  const position = untrack(() => this.position);
67
65
  if (!position) {
68
66
  const init = async () => {
69
67
  popover(this)({
70
- ...props,
71
68
  onchange: (_node, position) => {
72
69
  this.position = position;
73
70
  }
@@ -86,7 +83,7 @@ export class PopoverBond extends Bond {
86
83
  }
87
84
  };
88
85
  }
89
- content(props = {}) {
86
+ content() {
90
87
  const kind = POPOVER_ELEMENTS_KIND.content;
91
88
  const id = getElementId(this.id, kind);
92
89
  const triggerId = getElementId(this.id, POPOVER_ELEMENTS_KIND.trigger);
@@ -94,59 +91,47 @@ export class PopoverBond extends Bond {
94
91
  const isDisabled = this.state?.props?.disabled ?? false;
95
92
  const isActive = isOpen && !isDisabled;
96
93
  // Focus management
97
- const focusTrap = (ev) => {
98
- const node = ev.currentTarget;
94
+ const focusManager = (ev) => {
99
95
  if (ev.key === 'Escape') {
100
- ev.preventDefault();
101
96
  this.state.close();
102
97
  this.elements.trigger?.focus();
98
+ return;
103
99
  }
104
- // Tab trap - keep focus within popover
105
- else if (ev.key === 'Tab') {
106
- const focusableElements = node.querySelectorAll('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])');
107
- const firstElement = focusableElements[0];
108
- const lastElement = focusableElements[focusableElements.length - 1];
109
- if (ev.shiftKey && document.activeElement === firstElement) {
110
- ev.preventDefault();
111
- lastElement?.focus();
112
- }
113
- else if (!ev.shiftKey && document.activeElement === lastElement) {
114
- ev.preventDefault();
115
- firstElement?.focus();
116
- }
117
- }
100
+ focusTrap(ev);
118
101
  };
119
102
  return {
120
103
  id,
121
104
  role: 'dialog',
122
105
  'aria-modal': false,
123
106
  'aria-labelledby': triggerId,
124
- 'aria-hidden': !isActive,
125
- inert: !isActive ? '' : undefined,
107
+ inert: !isActive ? true : undefined,
126
108
  tabindex: -1,
127
109
  'data-atom': this.id,
128
110
  'data-kind': 'content',
129
111
  'data-active': isActive,
130
- onkeydown: isOpen ? focusTrap : undefined,
131
- ...props,
112
+ onkeydown: isOpen ? focusManager : undefined,
132
113
  [createAttachmentKey()]: (node) => {
133
114
  this.elements.content = node;
134
- if (!this.elements.trigger) {
115
+ const triggerElement = this.elements.trigger;
116
+ if (!triggerElement) {
135
117
  return;
136
118
  }
137
119
  if (!this.state.isOpen) {
138
120
  return;
139
121
  }
122
+ // check if trigger contains a focusable element and the focus is already inside
123
+ // check if the in-focus element is an input, textarea or select to avoid stealing focus
124
+ const activeElement = document.activeElement;
125
+ const triggerContainsFocus = ['input', 'textarea'].includes(activeElement.tagName.toLowerCase()) ||
126
+ triggerElement === activeElement ||
127
+ triggerElement.contains(activeElement);
140
128
  // Move focus to popover when opened
141
- setTimeout(() => {
142
- const firstFocusable = node.querySelector('a[href], button:not([disabled]), textarea:not([disabled]), input:not([disabled]), select:not([disabled]), [tabindex]:not([tabindex="-1"])');
143
- (firstFocusable || node).focus();
144
- }, 0);
129
+ if (!triggerContainsFocus) {
130
+ setTimeout(() => focus(node), 0);
131
+ }
145
132
  const cleanup = popover(this)({
146
- ...props,
147
133
  onchange: (node, position) => {
148
134
  this.position = position;
149
- props.onchange?.(node, position);
150
135
  }
151
136
  }, autoUpdate);
152
137
  return () => {
@@ -155,7 +140,7 @@ export class PopoverBond extends Bond {
155
140
  }
156
141
  };
157
142
  }
158
- indicator(props = {}) {
143
+ indicator() {
159
144
  const kind = POPOVER_ELEMENTS_KIND.indicator;
160
145
  const id = getElementId(this.id, kind);
161
146
  const isOpen = this.state?.props?.open ?? false;
@@ -164,13 +149,12 @@ export class PopoverBond extends Bond {
164
149
  'aria-hidden': true,
165
150
  'aria-live': isOpen ? 'polite' : 'off',
166
151
  'data-kind': kind,
167
- ...props,
168
152
  [createAttachmentKey()]: (node) => {
169
153
  this.elements.indicator = node;
170
154
  }
171
155
  };
172
156
  }
173
- arrow(props = {}) {
157
+ arrow() {
174
158
  const kind = POPOVER_ELEMENTS_KIND.arrow;
175
159
  const id = getElementId(this.id, kind);
176
160
  return {
@@ -178,7 +162,6 @@ export class PopoverBond extends Bond {
178
162
  role: 'presentation',
179
163
  'aria-hidden': true,
180
164
  'data-kind': kind,
181
- ...props,
182
165
  [createAttachmentKey()]: (node) => {
183
166
  this.elements.arrow = node;
184
167
  }