@entry-ui/qwik 0.7.0 → 0.9.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.
Files changed (126) hide show
  1. package/lib/_internal/components/collapsible-panel/collapsible-panel.d.ts +13 -0
  2. package/lib/_internal/components/collapsible-panel/collapsible-panel.qwik.mjs +195 -0
  3. package/lib/_internal/components/collapsible-panel/collapsible-panel.types.d.ts +62 -0
  4. package/lib/_internal/components/collapsible-panel/index.d.ts +2 -0
  5. package/lib/_internal/components/index.d.ts +2 -0
  6. package/lib/_internal/components/indicator/index.d.ts +2 -0
  7. package/lib/_internal/components/indicator/indicator.d.ts +11 -0
  8. package/lib/_internal/components/indicator/indicator.qwik.mjs +27 -0
  9. package/lib/_internal/components/indicator/indicator.types.d.ts +15 -0
  10. package/lib/components/accordion/parts/accordion-item-indicator/accordion-item-indicator.qwik.mjs +4 -12
  11. package/lib/components/accordion/parts/accordion-item-panel/accordion-item-panel.qwik.mjs +10 -169
  12. package/lib/components/accordion/parts/accordion-root/accordion-root.qwik.mjs +6 -19
  13. package/lib/components/collapsible/parts/collapsible-indicator/collapsible-indicator.qwik.mjs +4 -12
  14. package/lib/components/collapsible/parts/collapsible-panel/collapsible-panel.qwik.mjs +10 -164
  15. package/lib/components/collapsible/parts/collapsible-root/collapsible-root.qwik.mjs +1 -18
  16. package/lib/components/copy-button/contexts/copy-button-root-context/copy-button-root-context.d.ts +11 -0
  17. package/lib/components/copy-button/contexts/copy-button-root-context/copy-button-root-context.qwik.mjs +10 -0
  18. package/lib/components/copy-button/contexts/copy-button-root-context/copy-button-root-context.types.d.ts +24 -0
  19. package/lib/components/copy-button/contexts/copy-button-root-context/index.d.ts +2 -0
  20. package/lib/components/copy-button/contexts/index.d.ts +1 -0
  21. package/lib/components/copy-button/hooks/index.d.ts +1 -0
  22. package/lib/components/copy-button/hooks/use-copy-button-root-context/index.d.ts +2 -0
  23. package/lib/components/copy-button/hooks/use-copy-button-root-context/use-copy-button-root-context.d.ts +7 -0
  24. package/lib/components/copy-button/hooks/use-copy-button-root-context/use-copy-button-root-context.qwik.mjs +13 -0
  25. package/lib/components/copy-button/hooks/use-copy-button-root-context/use-copy-button-root-context.types.d.ts +24 -0
  26. package/lib/components/copy-button/index.d.ts +2 -0
  27. package/lib/components/copy-button/index.qwik.mjs +6 -0
  28. package/lib/components/copy-button/parts/copy-button-indicator/copy-button-indicator.d.ts +9 -0
  29. package/lib/components/copy-button/parts/copy-button-indicator/copy-button-indicator.qwik.mjs +20 -0
  30. package/lib/components/copy-button/parts/copy-button-indicator/copy-button-indicator.types.d.ts +15 -0
  31. package/lib/components/copy-button/parts/copy-button-indicator/index.d.ts +2 -0
  32. package/lib/components/copy-button/parts/copy-button-root/copy-button-root.d.ts +7 -0
  33. package/lib/components/copy-button/parts/copy-button-root/copy-button-root.qwik.mjs +47 -0
  34. package/lib/components/copy-button/parts/copy-button-root/copy-button-root.types.d.ts +52 -0
  35. package/lib/components/copy-button/parts/copy-button-root/index.d.ts +2 -0
  36. package/lib/components/copy-button/parts/index.d.ts +4 -0
  37. package/lib/components/copy-button/parts/index.qwik.mjs +6 -0
  38. package/lib/components/index.d.ts +3 -0
  39. package/lib/components/roving-focus-group/contexts/index.d.ts +2 -0
  40. package/lib/components/roving-focus-group/contexts/roving-focus-group-item-context/index.d.ts +2 -0
  41. package/lib/components/roving-focus-group/contexts/roving-focus-group-item-context/roving-focus-group-item-context.d.ts +6 -0
  42. package/lib/components/roving-focus-group/contexts/roving-focus-group-item-context/roving-focus-group-item-context.qwik.mjs +5 -0
  43. package/lib/components/roving-focus-group/contexts/roving-focus-group-item-context/roving-focus-group-item-context.types.d.ts +22 -0
  44. package/lib/components/roving-focus-group/contexts/roving-focus-group-root-context/index.d.ts +2 -0
  45. package/lib/components/roving-focus-group/contexts/roving-focus-group-root-context/roving-focus-group-root-context.d.ts +11 -0
  46. package/lib/components/roving-focus-group/contexts/roving-focus-group-root-context/roving-focus-group-root-context.qwik.mjs +10 -0
  47. package/lib/components/roving-focus-group/contexts/roving-focus-group-root-context/roving-focus-group-root-context.types.d.ts +37 -0
  48. package/lib/components/roving-focus-group/hooks/index.d.ts +2 -0
  49. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-item-context/index.d.ts +2 -0
  50. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-item-context/use-roving-focus-group-item-context.d.ts +7 -0
  51. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-item-context/use-roving-focus-group-item-context.qwik.mjs +13 -0
  52. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-item-context/use-roving-focus-group-item-context.types.d.ts +22 -0
  53. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-root-context/index.d.ts +2 -0
  54. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-root-context/use-roving-focus-group-root-context.d.ts +8 -0
  55. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-root-context/use-roving-focus-group-root-context.qwik.mjs +13 -0
  56. package/lib/components/roving-focus-group/hooks/use-roving-focus-group-root-context/use-roving-focus-group-root-context.types.d.ts +22 -0
  57. package/lib/components/roving-focus-group/index.d.ts +2 -0
  58. package/lib/components/roving-focus-group/index.qwik.mjs +8 -0
  59. package/lib/components/roving-focus-group/parts/index.d.ts +4 -0
  60. package/lib/components/roving-focus-group/parts/index.qwik.mjs +6 -0
  61. package/lib/components/roving-focus-group/parts/roving-focus-group-item/index.d.ts +2 -0
  62. package/lib/components/roving-focus-group/parts/roving-focus-group-item/roving-focus-group-item.d.ts +7 -0
  63. package/lib/components/roving-focus-group/parts/roving-focus-group-item/roving-focus-group-item.qwik.mjs +160 -0
  64. package/lib/components/roving-focus-group/parts/roving-focus-group-item/roving-focus-group-item.types.d.ts +29 -0
  65. package/lib/components/roving-focus-group/parts/roving-focus-group-root/index.d.ts +2 -0
  66. package/lib/components/roving-focus-group/parts/roving-focus-group-root/roving-focus-group-root.d.ts +7 -0
  67. package/lib/components/roving-focus-group/parts/roving-focus-group-root/roving-focus-group-root.qwik.mjs +49 -0
  68. package/lib/components/roving-focus-group/parts/roving-focus-group-root/roving-focus-group-root.types.d.ts +59 -0
  69. package/lib/components/tabs/contexts/index.d.ts +4 -0
  70. package/lib/components/tabs/contexts/tabs-list-context/index.d.ts +2 -0
  71. package/lib/components/tabs/contexts/tabs-list-context/tabs-list-context.d.ts +11 -0
  72. package/lib/components/tabs/contexts/tabs-list-context/tabs-list-context.qwik.mjs +10 -0
  73. package/lib/components/tabs/contexts/tabs-list-context/tabs-list-context.types.d.ts +12 -0
  74. package/lib/components/tabs/contexts/tabs-panel-context/index.d.ts +2 -0
  75. package/lib/components/tabs/contexts/tabs-panel-context/tabs-panel-context.d.ts +6 -0
  76. package/lib/components/tabs/contexts/tabs-panel-context/tabs-panel-context.qwik.mjs +5 -0
  77. package/lib/components/tabs/contexts/tabs-panel-context/tabs-panel-context.types.d.ts +12 -0
  78. package/lib/components/tabs/contexts/tabs-root-context/index.d.ts +2 -0
  79. package/lib/components/tabs/contexts/tabs-root-context/tabs-root-context.d.ts +11 -0
  80. package/lib/components/tabs/contexts/tabs-root-context/tabs-root-context.qwik.mjs +10 -0
  81. package/lib/components/tabs/contexts/tabs-root-context/tabs-root-context.types.d.ts +33 -0
  82. package/lib/components/tabs/contexts/tabs-tab-context/index.d.ts +2 -0
  83. package/lib/components/tabs/contexts/tabs-tab-context/tabs-tab-context.d.ts +6 -0
  84. package/lib/components/tabs/contexts/tabs-tab-context/tabs-tab-context.qwik.mjs +5 -0
  85. package/lib/components/tabs/contexts/tabs-tab-context/tabs-tab-context.types.d.ts +22 -0
  86. package/lib/components/tabs/hooks/index.d.ts +3 -0
  87. package/lib/components/tabs/hooks/use-tabs-panel-context/index.d.ts +2 -0
  88. package/lib/components/tabs/hooks/use-tabs-panel-context/use-tabs-panel-context.d.ts +8 -0
  89. package/lib/components/tabs/hooks/use-tabs-panel-context/use-tabs-panel-context.qwik.mjs +11 -0
  90. package/lib/components/tabs/hooks/use-tabs-panel-context/use-tabs-panel-context.types.d.ts +12 -0
  91. package/lib/components/tabs/hooks/use-tabs-root-context/index.d.ts +2 -0
  92. package/lib/components/tabs/hooks/use-tabs-root-context/use-tabs-root-context.d.ts +8 -0
  93. package/lib/components/tabs/hooks/use-tabs-root-context/use-tabs-root-context.qwik.mjs +13 -0
  94. package/lib/components/tabs/hooks/use-tabs-root-context/use-tabs-root-context.types.d.ts +22 -0
  95. package/lib/components/tabs/hooks/use-tabs-tab-context/index.d.ts +2 -0
  96. package/lib/components/tabs/hooks/use-tabs-tab-context/use-tabs-tab-context.d.ts +7 -0
  97. package/lib/components/tabs/hooks/use-tabs-tab-context/use-tabs-tab-context.qwik.mjs +13 -0
  98. package/lib/components/tabs/hooks/use-tabs-tab-context/use-tabs-tab-context.types.d.ts +22 -0
  99. package/lib/components/tabs/index.d.ts +2 -0
  100. package/lib/components/tabs/index.qwik.mjs +10 -0
  101. package/lib/components/tabs/parts/index.d.ts +8 -0
  102. package/lib/components/tabs/parts/index.qwik.mjs +10 -0
  103. package/lib/components/tabs/parts/tabs-list/index.d.ts +2 -0
  104. package/lib/components/tabs/parts/tabs-list/tabs-list.d.ts +7 -0
  105. package/lib/components/tabs/parts/tabs-list/tabs-list.qwik.mjs +37 -0
  106. package/lib/components/tabs/parts/tabs-list/tabs-list.types.d.ts +30 -0
  107. package/lib/components/tabs/parts/tabs-panel/index.d.ts +2 -0
  108. package/lib/components/tabs/parts/tabs-panel/tabs-panel.d.ts +7 -0
  109. package/lib/components/tabs/parts/tabs-panel/tabs-panel.qwik.mjs +39 -0
  110. package/lib/components/tabs/parts/tabs-panel/tabs-panel.types.d.ts +27 -0
  111. package/lib/components/tabs/parts/tabs-root/index.d.ts +2 -0
  112. package/lib/components/tabs/parts/tabs-root/tabs-root.d.ts +7 -0
  113. package/lib/components/tabs/parts/tabs-root/tabs-root.qwik.mjs +34 -0
  114. package/lib/components/tabs/parts/tabs-root/tabs-root.types.d.ts +50 -0
  115. package/lib/components/tabs/parts/tabs-tab/index.d.ts +2 -0
  116. package/lib/components/tabs/parts/tabs-tab/tabs-tab.d.ts +7 -0
  117. package/lib/components/tabs/parts/tabs-tab/tabs-tab.qwik.mjs +87 -0
  118. package/lib/components/tabs/parts/tabs-tab/tabs-tab.types.d.ts +25 -0
  119. package/lib/hooks/index.d.ts +1 -0
  120. package/lib/hooks/use-clipboard/index.d.ts +2 -0
  121. package/lib/hooks/use-clipboard/index.qwik.mjs +4 -0
  122. package/lib/hooks/use-clipboard/use-clipboard.d.ts +19 -0
  123. package/lib/hooks/use-clipboard/use-clipboard.qwik.mjs +93 -0
  124. package/lib/hooks/use-clipboard/use-clipboard.types.d.ts +58 -0
  125. package/lib/index.qwik.mjs +24 -4
  126. package/package.json +18 -2
@@ -0,0 +1,13 @@
1
+ import type { CollapsiblePanelProps } from './collapsible-panel.types';
2
+ /**
3
+ * Internal component used as a base for expandable panels, such as `Collapsible` or `Accordion`.
4
+ * It provides advanced height synchronization, CSS transition support, and seamless
5
+ * integration with the browser's native search-and-reveal (`hidden="until-found"`) functionality.
6
+ *
7
+ * This component is designed for internal library use to ensure consistent animation
8
+ * behaviors, state management (open/closed), and accessibility across different
9
+ * disclosure-pattern implementations.
10
+ *
11
+ * Renders a `<div>` element.
12
+ */
13
+ export declare const CollapsiblePanel: import("@qwik.dev/core").Component<CollapsiblePanelProps>;
@@ -0,0 +1,195 @@
1
+ import { jsx } from "@qwik.dev/core/jsx-runtime";
2
+ import { component$, useSignal, useComputed$, useTask$, isBrowser, isDev, sync$, $, Slot } from "@qwik.dev/core";
3
+ import { getComputedStyle } from "@entry-ui/utilities/get-computed-style";
4
+ import { getHiddenElementHeight } from "@entry-ui/utilities/get-hidden-element-height";
5
+ import { getWindow } from "@entry-ui/utilities/get-window";
6
+ import { addEventListenerOnce } from "@entry-ui/utilities/add-event-listener-once";
7
+ import { mergeStyles } from "../../../utilities/merge-styles/merge-styles.qwik.mjs";
8
+ import { mergeRefs } from "../../../utilities/merge-refs/merge-refs.qwik.mjs";
9
+ import { warn } from "../../utilities/warn/warn.qwik.mjs";
10
+ import { Primitive } from "../primitive/primitive.qwik.mjs";
11
+ const CollapsiblePanel = component$((props) => {
12
+ const { as = "div", ref: _ref, componentName, heightVariableName, open = false, setOpen$, hiddenUntilFound: _hiddenUntilFound = false, disabled = false, onOpenChangeComplete$, onBeforematch$, style, ...others } = props;
13
+ const ref = useSignal(void 0);
14
+ const hidden = useSignal(!open);
15
+ const state = useSignal(open ? "open" : "closed");
16
+ const height = useSignal(open ? "auto" : _hiddenUntilFound ? disabled ? "0px" : "none" : "0px");
17
+ const isBeforeMatch = useSignal(false);
18
+ const preventInitialAnimation = useSignal(true);
19
+ const hiddenUntilFound = useComputed$(() => disabled ? false : _hiddenUntilFound);
20
+ const mergedStyles = useComputed$(() => mergeStyles([
21
+ {
22
+ // When the panel is hidden, we use "none !important" to ensure it's removed
23
+ // from the visual flow unless hidden="until-found" is active.
24
+ // In the latter case, we set display to undefined to allow the browser's
25
+ // internal search engine to manage visibility and reveal the content.
26
+ display: hidden.value ? hiddenUntilFound.value ? void 0 : "none !important" : void 0,
27
+ transitionDuration: preventInitialAnimation.value ? "0s" : void 0,
28
+ animationDuration: preventInitialAnimation.value ? "0s" : void 0,
29
+ [heightVariableName]: height.value
30
+ },
31
+ style
32
+ ]));
33
+ useTask$(({ track }) => {
34
+ const isHiddenUntilFound = track(() => hiddenUntilFound.value);
35
+ const panelRef = ref.value;
36
+ if (isBrowser && panelRef) {
37
+ const panelHeight = open ? "auto" : isHiddenUntilFound ? "none" : "0px";
38
+ height.value = panelHeight;
39
+ panelRef.style.setProperty(heightVariableName, panelHeight);
40
+ }
41
+ });
42
+ useTask$(({ track, cleanup }) => {
43
+ const isOpen = track(() => open);
44
+ const panelRef = ref.value;
45
+ if (isBrowser && panelRef) {
46
+ if (preventInitialAnimation.value && !isBeforeMatch.value) {
47
+ preventInitialAnimation.value = false;
48
+ panelRef.style.removeProperty("transition-duration");
49
+ panelRef.style.removeProperty("animation-duration");
50
+ }
51
+ if (isOpen) {
52
+ hidden.value = false;
53
+ panelRef.removeAttribute("hidden");
54
+ if (hiddenUntilFound.value) {
55
+ isBeforeMatch.value = false;
56
+ } else {
57
+ panelRef.style.removeProperty("display");
58
+ }
59
+ state.value = "open";
60
+ panelRef.setAttribute("data-state", "open");
61
+ const { animationDuration: animationDuration2, transitionDuration: transitionDuration2 } = getComputedStyle(panelRef);
62
+ const panelHeight = getHiddenElementHeight(panelRef);
63
+ const win = getWindow(panelRef);
64
+ if (transitionDuration2 === "0s" && animationDuration2 === "0s") {
65
+ height.value = `${panelHeight}px`;
66
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
67
+ } else if (transitionDuration2 !== "0s") {
68
+ if (height.value === "none") {
69
+ height.value = "0px";
70
+ panelRef.style.setProperty(heightVariableName, "0px");
71
+ win.setTimeout(() => {
72
+ height.value = `${panelHeight}px`;
73
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
74
+ }, 0);
75
+ } else {
76
+ height.value = `${panelHeight}px`;
77
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
78
+ }
79
+ } else if (animationDuration2 !== "0s") {
80
+ height.value = `${panelHeight}px`;
81
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
82
+ }
83
+ } else {
84
+ state.value = "closed";
85
+ panelRef.setAttribute("data-state", "closed");
86
+ const { animationDuration: animationDuration2, transitionDuration: transitionDuration2 } = getComputedStyle(panelRef);
87
+ const panelHeight = getHiddenElementHeight(panelRef);
88
+ const win = getWindow(panelRef);
89
+ if (transitionDuration2 === "0s" && animationDuration2 === "0s") {
90
+ height.value = "0px";
91
+ panelRef.style.setProperty(heightVariableName, "0px");
92
+ } else if (transitionDuration2 !== "0s") {
93
+ if (height.value === "auto") {
94
+ height.value = `${panelHeight}px`;
95
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
96
+ win.setTimeout(() => {
97
+ height.value = "0px";
98
+ panelRef.style.setProperty(heightVariableName, "0px");
99
+ }, 0);
100
+ } else {
101
+ height.value = "0px";
102
+ panelRef.style.setProperty(heightVariableName, "0px");
103
+ }
104
+ } else if (animationDuration2 !== "0s") {
105
+ height.value = `${panelHeight}px`;
106
+ panelRef.style.setProperty(heightVariableName, `${panelHeight}px`);
107
+ }
108
+ }
109
+ const applyFinalState = () => {
110
+ if (isOpen) {
111
+ height.value = "auto";
112
+ panelRef.style.setProperty(heightVariableName, "auto");
113
+ } else {
114
+ hidden.value = true;
115
+ if (hiddenUntilFound.value) {
116
+ height.value = "none";
117
+ panelRef.style.setProperty(heightVariableName, "none");
118
+ } else {
119
+ height.value = "0px";
120
+ panelRef.style.setProperty(heightVariableName, "0px");
121
+ }
122
+ }
123
+ if (onOpenChangeComplete$) {
124
+ onOpenChangeComplete$(isOpen);
125
+ }
126
+ };
127
+ const { transitionDuration, animationDuration } = getComputedStyle(panelRef);
128
+ if (isDev && transitionDuration !== "0s" && animationDuration !== "0s") {
129
+ warn([
130
+ `Both CSS transitions and CSS animations are detected on ${componentName} component.`,
131
+ `Using both at the same time may cause unpredictable behavior.`,
132
+ `Please use only one animation method.`
133
+ ]);
134
+ applyFinalState();
135
+ } else if (transitionDuration !== "0s") {
136
+ const removeTransitionEndListener = addEventListenerOnce({
137
+ target: panelRef,
138
+ type: "transitionend",
139
+ listener: applyFinalState
140
+ });
141
+ cleanup(() => {
142
+ removeTransitionEndListener();
143
+ });
144
+ } else if (animationDuration !== "0s") {
145
+ const removeAnimationEndListener = addEventListenerOnce({
146
+ target: panelRef,
147
+ type: "animationend",
148
+ listener: applyFinalState
149
+ });
150
+ cleanup(() => {
151
+ removeAnimationEndListener();
152
+ });
153
+ } else {
154
+ applyFinalState();
155
+ }
156
+ }
157
+ });
158
+ const handleBeforeMatchSync$ = sync$((event) => {
159
+ const entryUIQwikEvent = event;
160
+ if (!entryUIQwikEvent.entryUIQwikHandlerPrevented) {
161
+ event.preventDefault();
162
+ }
163
+ });
164
+ const handleBeforeMatch$ = $((event) => {
165
+ const entryUIQwikEvent = event;
166
+ if (!entryUIQwikEvent.entryUIQwikHandlerPrevented) {
167
+ isBeforeMatch.value = true;
168
+ preventInitialAnimation.value = true;
169
+ if (setOpen$) {
170
+ setOpen$(true);
171
+ }
172
+ }
173
+ });
174
+ return /* @__PURE__ */ jsx(Primitive.div, {
175
+ as,
176
+ ref: mergeRefs([
177
+ _ref,
178
+ ref
179
+ ]),
180
+ hidden: hidden.value ? hiddenUntilFound.value ? "until-found" : "hidden" : void 0,
181
+ "data-state": state.value,
182
+ "data-disabled": disabled ? "" : void 0,
183
+ onBeforematch$: [
184
+ onBeforematch$,
185
+ handleBeforeMatchSync$,
186
+ handleBeforeMatch$
187
+ ],
188
+ style: mergedStyles.value,
189
+ ...others,
190
+ children: /* @__PURE__ */ jsx(Slot, {})
191
+ });
192
+ });
193
+ export {
194
+ CollapsiblePanel
195
+ };
@@ -0,0 +1,62 @@
1
+ import { PropsOf, Component, QRL } from '@qwik.dev/core';
2
+ /**
3
+ * Props for the internal `CollapsiblePanel` component.
4
+ * Extends the standard HTML attributes for a `<div>` element.
5
+ */
6
+ export interface CollapsiblePanelProps extends PropsOf<'div'> {
7
+ /**
8
+ * The element or component this component should render as.
9
+ *
10
+ * @see {@link https://github.com/ZAHON/entry-ui/tree/main/packages/qwik/docs/guides/composition.md Composition} guide for more details.
11
+ *
12
+ * @default "div"
13
+ */
14
+ as?: string | Component;
15
+ /**
16
+ * The name of the parent component using this panel (e.g., "Accordion.ItemPanel").
17
+ * Used primarily for developer warnings and debugging.
18
+ */
19
+ componentName: string;
20
+ /**
21
+ * The name of the CSS custom property (variable) used to synchronize the panel's height.
22
+ */
23
+ heightVariableName: `--${string}`;
24
+ /**
25
+ * The controlled open state of the panel.
26
+ * When `true`, the panel expands to reveal its content.
27
+ *
28
+ * @default false
29
+ */
30
+ open?: boolean;
31
+ /**
32
+ * A `QRL` callback that updates the `open` state.
33
+ * Triggered automatically by internal logic, such as the browser's "beforematch" event.
34
+ *
35
+ * @default undefined
36
+ */
37
+ setOpen$?: QRL<(open: boolean) => void>;
38
+ /**
39
+ * When `true`, the panel utilizes the browser's native `hidden="until-found"` attribute.
40
+ * This enables "find-in-page" support, allowing the browser to automatically reveal
41
+ * the panel when a match is found inside its content.
42
+ *
43
+ * @default false
44
+ */
45
+ hiddenUntilFound?: boolean;
46
+ /**
47
+ * If `true`, the panel is considered inactive.
48
+ * This prevents the `hiddenUntilFound` behavior and ensures the panel remains
49
+ * closed and non-interactable.
50
+ *
51
+ * @default false
52
+ */
53
+ disabled?: boolean;
54
+ /**
55
+ * A `QRL` callback invoked once the expansion or collapse transition has fully completed.
56
+ * It fires after the CSS `transitionend` or `animationend` events, or immediately
57
+ * if no animations are defined.
58
+ *
59
+ * @default undefined
60
+ */
61
+ onOpenChangeComplete$?: QRL<(open: boolean) => void>;
62
+ }
@@ -0,0 +1,2 @@
1
+ export type { CollapsiblePanelProps } from './collapsible-panel.types';
2
+ export { CollapsiblePanel } from './collapsible-panel';
@@ -1 +1,3 @@
1
+ export * from './collapsible-panel';
2
+ export * from './indicator';
1
3
  export * from './primitive';
@@ -0,0 +1,2 @@
1
+ export type { IndicatorProps } from './indicator.types';
2
+ export { Indicator } from './indicator';
@@ -0,0 +1,11 @@
1
+ import type { IndicatorProps } from './indicator.types';
2
+ /**
3
+ * Internal component used as a base for various state indicators.
4
+ * It provides common accessibility attributes, styling resets, and composition support.
5
+ *
6
+ * This component is intended for internal library use to ensure consistent
7
+ * behavior across different indicator implementations.
8
+ *
9
+ * Renders a `<span>` element.
10
+ */
11
+ export declare const Indicator: import("@qwik.dev/core").Component<IndicatorProps>;
@@ -0,0 +1,27 @@
1
+ import { jsx } from "@qwik.dev/core/jsx-runtime";
2
+ import { component$, useComputed$, Slot } from "@qwik.dev/core";
3
+ import { mergeStyles } from "../../../utilities/merge-styles/merge-styles.qwik.mjs";
4
+ import { Primitive } from "../primitive/primitive.qwik.mjs";
5
+ const Indicator = component$((props) => {
6
+ const { as = "span", style, ...others } = props;
7
+ const mergedStyles = useComputed$(() => mergeStyles([
8
+ {
9
+ pointerEvents: "none",
10
+ userSelect: "none",
11
+ // Ensures text selection is disabled on older versions of Safari
12
+ // and iOS browsers using the WebKit engine.
13
+ WebkitUserSelect: "none"
14
+ },
15
+ style
16
+ ]));
17
+ return /* @__PURE__ */ jsx(Primitive.span, {
18
+ as,
19
+ "aria-hidden": "true",
20
+ style: mergedStyles.value,
21
+ ...others,
22
+ children: /* @__PURE__ */ jsx(Slot, {})
23
+ });
24
+ });
25
+ export {
26
+ Indicator
27
+ };
@@ -0,0 +1,15 @@
1
+ import { PropsOf, Component } from '@qwik.dev/core';
2
+ /**
3
+ * Props for the internal `Indicator` component.
4
+ * Extends the standard HTML attributes for a `<span>` element.
5
+ */
6
+ export interface IndicatorProps extends PropsOf<'span'> {
7
+ /**
8
+ * The element or component this component should render as.
9
+ *
10
+ * @see {@link https://github.com/ZAHON/entry-ui/tree/main/packages/qwik/docs/guides/composition.md Composition} guide for more details.
11
+ *
12
+ * @default "span"
13
+ */
14
+ as?: string | Component;
15
+ }
@@ -1,23 +1,15 @@
1
1
  import { jsx } from "@qwik.dev/core/jsx-runtime";
2
2
  import { component$, Slot } from "@qwik.dev/core";
3
- import { mergeStyles } from "../../../../utilities/merge-styles/merge-styles.qwik.mjs";
4
- import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
3
+ import { Indicator } from "../../../../_internal/components/indicator/indicator.qwik.mjs";
5
4
  import { useAccordionItemContext } from "../../contexts/accordion-item-context/accordion-item-context.qwik.mjs";
6
5
  const AccordionItemIndicator = component$((props) => {
7
- const { style, ...others } = props;
6
+ const { as = "span", ...others } = props;
8
7
  const { open, disabled } = useAccordionItemContext();
9
- return /* @__PURE__ */ jsx(Primitive.span, {
10
- "aria-hidden": "true",
8
+ return /* @__PURE__ */ jsx(Indicator, {
9
+ as,
11
10
  "data-entry-ui-qwik-accordion-item-indicator": "",
12
11
  "data-state": open.value ? "open" : "closed",
13
12
  "data-disabled": disabled.value ? "" : void 0,
14
- style: mergeStyles([
15
- {
16
- pointerEvents: "none",
17
- userSelect: "none"
18
- },
19
- style
20
- ]),
21
13
  ...others,
22
14
  children: /* @__PURE__ */ jsx(Slot, {})
23
15
  });
@@ -1,195 +1,36 @@
1
1
  import { jsx } from "@qwik.dev/core/jsx-runtime";
2
- import { component$, useSignal, useComputed$, $, useTask$, isBrowser, isDev, sync$, Slot } from "@qwik.dev/core";
3
- import { getComputedStyle } from "@entry-ui/utilities/get-computed-style";
4
- import { getHiddenElementHeight } from "@entry-ui/utilities/get-hidden-element-height";
5
- import { addEventListenerOnce } from "@entry-ui/utilities/add-event-listener-once";
2
+ import { component$, useSignal, $, Slot } from "@qwik.dev/core";
6
3
  import { useLifecycle } from "../../../../hooks/use-lifecycle/use-lifecycle.qwik.mjs";
7
- import { mergeStyles } from "../../../../utilities/merge-styles/merge-styles.qwik.mjs";
8
4
  import { mergeRefs } from "../../../../utilities/merge-refs/merge-refs.qwik.mjs";
9
- import { warn } from "../../../../_internal/utilities/warn/warn.qwik.mjs";
10
- import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
5
+ import { CollapsiblePanel } from "../../../../_internal/components/collapsible-panel/collapsible-panel.qwik.mjs";
11
6
  import { useAccordionRootContext } from "../../contexts/accordion-root-context/accordion-root-context.qwik.mjs";
12
7
  import { useAccordionItemContext } from "../../contexts/accordion-item-context/accordion-item-context.qwik.mjs";
13
8
  const AccordionItemPanel = component$((props) => {
14
- const { as = "div", ref: _ref, id, hiddenUntilFound: _hiddenUntilFound = false, onOpenChangeComplete$, onBeforematch$, style, ...others } = props;
9
+ const { as = "div", ref: _ref, id, hiddenUntilFound = false, ...others } = props;
15
10
  const { hiddenUntilFound: rootHiddenUntilFound } = useAccordionRootContext();
16
11
  const { open, setOpen$, disabled, panelId, triggerId } = useAccordionItemContext();
17
12
  const ref = useSignal(void 0);
18
- const hidden = useSignal(!open.value);
19
- const state = useSignal(open.value ? "open" : "closed");
20
- const height = useSignal(() => {
21
- if (open.value) {
22
- return "auto";
23
- }
24
- return _hiddenUntilFound || rootHiddenUntilFound.value ? disabled.value ? "0px" : "none" : "0px";
25
- });
26
- const isBeforeMatch = useSignal(false);
27
- const preventInitialAnimation = useSignal(true);
28
- const hiddenUntilFound = useComputed$(() => disabled.value ? false : _hiddenUntilFound || rootHiddenUntilFound.value);
29
- const mergedStyles = useComputed$(() => mergeStyles([
30
- {
31
- display: hidden.value ? hiddenUntilFound.value ? void 0 : "none !important" : void 0,
32
- transitionDuration: preventInitialAnimation.value ? "0s" : void 0,
33
- animationDuration: preventInitialAnimation.value ? "0s" : void 0,
34
- "--entry-ui-qwik-accordion-item-panel-height": height.value
35
- },
36
- style
37
- ]));
38
13
  useLifecycle({
39
14
  element: ref,
40
15
  onMount$: $(() => panelId.set$(id)),
41
16
  onUnmount$: $(() => panelId.delete$())
42
17
  });
43
- useTask$(({ track }) => {
44
- const isHiddenUntilFound = track(() => hiddenUntilFound.value);
45
- const panelRef = ref.value;
46
- if (isBrowser && panelRef) {
47
- const panelHeight = open.value ? "auto" : isHiddenUntilFound ? "none" : "0px";
48
- height.value = panelHeight;
49
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", panelHeight);
50
- }
51
- });
52
- useTask$(({ track, cleanup }) => {
53
- const isOpen = track(() => open.value);
54
- const panelRef = ref.value;
55
- if (isBrowser && panelRef) {
56
- if (preventInitialAnimation.value && !isBeforeMatch.value) {
57
- preventInitialAnimation.value = false;
58
- panelRef.style.removeProperty("transition-duration");
59
- panelRef.style.removeProperty("animation-duration");
60
- }
61
- if (isOpen) {
62
- hidden.value = false;
63
- panelRef.removeAttribute("hidden");
64
- if (hiddenUntilFound.value) {
65
- isBeforeMatch.value = false;
66
- } else {
67
- panelRef.style.removeProperty("display");
68
- }
69
- state.value = "open";
70
- panelRef.setAttribute("data-state", "open");
71
- const { animationDuration: animationDuration2, transitionDuration: transitionDuration2 } = getComputedStyle(panelRef);
72
- const panelHeight = getHiddenElementHeight(panelRef);
73
- if (animationDuration2 === "0s" && transitionDuration2 !== "0s") {
74
- if (height.value === "none") {
75
- height.value = "0px";
76
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "0px");
77
- setTimeout(() => {
78
- height.value = `${panelHeight}px`;
79
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", `${panelHeight}px`);
80
- }, 0);
81
- } else {
82
- height.value = `${panelHeight}px`;
83
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", `${panelHeight}px`);
84
- }
85
- } else {
86
- height.value = `${panelHeight}px`;
87
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", `${panelHeight}px`);
88
- }
89
- } else {
90
- state.value = "closed";
91
- panelRef.setAttribute("data-state", "closed");
92
- const { animationDuration: animationDuration2, transitionDuration: transitionDuration2 } = getComputedStyle(panelRef);
93
- const panelHeight = getHiddenElementHeight(panelRef);
94
- if (animationDuration2 === "0s" && transitionDuration2 !== "0s") {
95
- if (height.value === "auto") {
96
- height.value = `${panelHeight}px`;
97
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", `${panelHeight}px`);
98
- setTimeout(() => {
99
- height.value = "0px";
100
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "0px");
101
- }, 0);
102
- } else {
103
- height.value = "0px";
104
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "0px");
105
- }
106
- } else {
107
- height.value = `${panelHeight}px`;
108
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", `${panelHeight}px`);
109
- }
110
- }
111
- const applyFinalState = () => {
112
- if (isOpen) {
113
- height.value = "auto";
114
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "auto");
115
- } else {
116
- hidden.value = true;
117
- if (hiddenUntilFound.value) {
118
- height.value = "none";
119
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "none");
120
- } else {
121
- height.value = "0px";
122
- panelRef.style.setProperty("--entry-ui-qwik-accordion-item-panel-height", "0px");
123
- }
124
- }
125
- if (onOpenChangeComplete$) {
126
- onOpenChangeComplete$(isOpen);
127
- }
128
- };
129
- const { transitionDuration, animationDuration } = getComputedStyle(panelRef);
130
- if (isDev && transitionDuration !== "0s" && animationDuration !== "0s") {
131
- warn([
132
- `Both CSS transitions and CSS animations are detected on 'Accordion.ItemPanel' component.`,
133
- `Using both at the same time may cause unpredictable behavior.`,
134
- `Please use only one animation method.`
135
- ]);
136
- applyFinalState();
137
- } else if (transitionDuration !== "0s") {
138
- const removeTransitionEndListener = addEventListenerOnce({
139
- target: panelRef,
140
- type: "transitionend",
141
- listener: applyFinalState
142
- });
143
- cleanup(() => {
144
- removeTransitionEndListener();
145
- });
146
- } else if (animationDuration !== "0s") {
147
- const removeAnimationEndListener = addEventListenerOnce({
148
- target: panelRef,
149
- type: "animationend",
150
- listener: applyFinalState
151
- });
152
- cleanup(() => {
153
- removeAnimationEndListener();
154
- });
155
- } else {
156
- applyFinalState();
157
- }
158
- }
159
- });
160
- const handleBeforeMatchSync$ = sync$((event) => {
161
- const entryUIQwikEvent = event;
162
- if (!entryUIQwikEvent.entryUIQwikHandlerPrevented) {
163
- event.preventDefault();
164
- }
165
- });
166
- const handleBeforeMatch$ = $((event) => {
167
- const entryUIQwikEvent = event;
168
- if (!entryUIQwikEvent.entryUIQwikHandlerPrevented) {
169
- isBeforeMatch.value = true;
170
- preventInitialAnimation.value = true;
171
- setOpen$(true);
172
- }
173
- });
174
- return /* @__PURE__ */ jsx(Primitive.div, {
18
+ return /* @__PURE__ */ jsx(CollapsiblePanel, {
175
19
  as,
20
+ componentName: "Accordion.ItemPanel",
21
+ heightVariableName: "--entry-ui-qwik-accordion-item-panel-height",
22
+ open: open.value,
23
+ setOpen$,
24
+ hiddenUntilFound: hiddenUntilFound || rootHiddenUntilFound.value,
25
+ disabled: disabled.value,
176
26
  ref: mergeRefs([
177
27
  _ref,
178
28
  ref
179
29
  ]),
180
30
  id: panelId.id.value,
181
31
  role: triggerId.id.value ? "region" : void 0,
182
- hidden: hidden.value ? hiddenUntilFound.value ? "until-found" : "hidden" : void 0,
183
32
  "aria-labelledby": triggerId.id.value,
184
33
  "data-entry-ui-qwik-accordion-item-panel": "",
185
- "data-state": state.value,
186
- "data-disabled": disabled.value ? "" : void 0,
187
- onBeforematch$: [
188
- onBeforematch$,
189
- handleBeforeMatchSync$,
190
- handleBeforeMatch$
191
- ],
192
- style: mergedStyles.value,
193
34
  ...others,
194
35
  children: /* @__PURE__ */ jsx(Slot, {})
195
36
  });
@@ -1,13 +1,13 @@
1
1
  import { jsx } from "@qwik.dev/core/jsx-runtime";
2
2
  import { component$, useComputed$, $, sync$, useContextProvider, Slot } from "@qwik.dev/core";
3
3
  import { isDev } from "@qwik.dev/core/build";
4
+ import { focusElement } from "@entry-ui/utilities/focus-element";
4
5
  import { useControllable } from "../../../../hooks/use-controllable/use-controllable.qwik.mjs";
5
- import { mergeStyles } from "../../../../utilities/merge-styles/merge-styles.qwik.mjs";
6
6
  import { warn } from "../../../../_internal/utilities/warn/warn.qwik.mjs";
7
7
  import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
8
8
  import { AccordionRootContext } from "../../contexts/accordion-root-context/accordion-root-context.qwik.mjs";
9
9
  const AccordionRoot = component$((props) => {
10
- const { as = "div", defaultValue, value: _value, onValueChange$, multiple = false, loopFocus = true, hiddenUntilFound: _hiddenUntilFound = false, disabled: _disabled = false, onKeyDown$, style, ...others } = props;
10
+ const { as = "div", defaultValue, value: _value, onValueChange$, multiple = false, loopFocus = true, hiddenUntilFound: _hiddenUntilFound = false, disabled: _disabled = false, onKeyDown$, ...others } = props;
11
11
  const { state: value, setState$: setValue$ } = useControllable({
12
12
  defaultValue: defaultValue ?? [],
13
13
  controlledSignal: _value,
@@ -91,7 +91,10 @@ const AccordionRoot = component$((props) => {
91
91
  break;
92
92
  }
93
93
  if (nextIndex > -1) {
94
- enabledTriggers[nextIndex]?.focus();
94
+ focusElement({
95
+ element: enabledTriggers[nextIndex],
96
+ focusVisible: true
97
+ });
95
98
  }
96
99
  }
97
100
  });
@@ -112,22 +115,6 @@ const AccordionRoot = component$((props) => {
112
115
  handleKeyDownSync$,
113
116
  handleKeyDown$
114
117
  ],
115
- style: mergeStyles([
116
- {
117
- // Performance optimization
118
- // The `contain: layout style;` CSS property is used here to improve rendering performance.
119
- // `contain: layout;` tells the browser that the internal layout of this accordion
120
- // is self-contained and does not affect the layout of elements outside of it. This prevents
121
- // costly re-calculations of the entire page layout when an accordion item expands or collapses,
122
- // which is especially beneficial during animations.
123
- // `contain: style;` ensures that CSS properties that can affect the rest of the page,
124
- // like counters, are isolated to this element.
125
- // Together, these properties create a performance "bubble", allowing the browser to optimize
126
- // rendering by treating the accordion component as an independent unit.
127
- contain: "layout style"
128
- },
129
- style
130
- ]),
131
118
  ...others,
132
119
  children: /* @__PURE__ */ jsx(Slot, {})
133
120
  });
@@ -1,23 +1,15 @@
1
1
  import { jsx } from "@qwik.dev/core/jsx-runtime";
2
2
  import { component$, Slot } from "@qwik.dev/core";
3
- import { mergeStyles } from "../../../../utilities/merge-styles/merge-styles.qwik.mjs";
4
- import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
3
+ import { Indicator } from "../../../../_internal/components/indicator/indicator.qwik.mjs";
5
4
  import { useCollapsibleRootContext } from "../../contexts/collapsible-root-context/collapsible-root-context.qwik.mjs";
6
5
  const CollapsibleIndicator = component$((props) => {
7
- const { style, ...others } = props;
6
+ const { as = "span", ...others } = props;
8
7
  const { open, disabled } = useCollapsibleRootContext();
9
- return /* @__PURE__ */ jsx(Primitive.span, {
10
- "aria-hidden": "true",
8
+ return /* @__PURE__ */ jsx(Indicator, {
9
+ as,
11
10
  "data-entry-ui-qwik-collapsible-indicator": "",
12
11
  "data-state": open.value ? "open" : "closed",
13
12
  "data-disabled": disabled.value ? "" : void 0,
14
- style: mergeStyles([
15
- {
16
- pointerEvents: "none",
17
- userSelect: "none"
18
- },
19
- style
20
- ]),
21
13
  ...others,
22
14
  children: /* @__PURE__ */ jsx(Slot, {})
23
15
  });