@entry-ui/qwik 0.4.0 → 0.6.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.
- package/lib/_internal/hooks/index.d.ts +1 -0
- package/lib/_internal/hooks/use-id-manager/index.d.ts +2 -0
- package/lib/_internal/hooks/use-id-manager/use-id-manager.d.ts +21 -0
- package/lib/_internal/hooks/use-id-manager/use-id-manager.qwik.mjs +25 -0
- package/lib/_internal/hooks/use-id-manager/use-id-manager.types.d.ts +56 -0
- package/lib/_internal/index.d.ts +1 -0
- package/lib/_internal/utilities/error/error.qwik.mjs +10 -0
- package/lib/_internal/utilities/warn/warn.qwik.mjs +10 -0
- package/lib/components/collapsible/contexts/collapsible-root-context/collapsible-root-context.d.ts +11 -0
- package/lib/components/collapsible/contexts/collapsible-root-context/collapsible-root-context.qwik.mjs +10 -0
- package/lib/components/collapsible/contexts/collapsible-root-context/collapsible-root-context.types.d.ts +58 -0
- package/lib/components/collapsible/contexts/collapsible-root-context/index.d.ts +2 -0
- package/lib/components/collapsible/contexts/collapsible-trigger-context/collapsible-trigger-context.d.ts +6 -0
- package/lib/components/collapsible/contexts/collapsible-trigger-context/collapsible-trigger-context.qwik.mjs +5 -0
- package/lib/components/collapsible/contexts/collapsible-trigger-context/collapsible-trigger-context.types.d.ts +13 -0
- package/lib/components/collapsible/contexts/collapsible-trigger-context/index.d.ts +2 -0
- package/lib/components/collapsible/contexts/index.d.ts +2 -0
- package/lib/components/collapsible/hooks/index.d.ts +2 -0
- package/lib/components/collapsible/hooks/use-collapsible-root-context/index.d.ts +2 -0
- package/lib/components/collapsible/hooks/use-collapsible-root-context/use-collapsible-root-context.d.ts +7 -0
- package/lib/components/collapsible/hooks/use-collapsible-root-context/use-collapsible-root-context.qwik.mjs +13 -0
- package/lib/components/collapsible/hooks/use-collapsible-root-context/use-collapsible-root-context.types.d.ts +22 -0
- package/lib/components/collapsible/hooks/use-collapsible-trigger-context/index.d.ts +2 -0
- package/lib/components/collapsible/hooks/use-collapsible-trigger-context/use-collapsible-trigger-context.d.ts +7 -0
- package/lib/components/collapsible/hooks/use-collapsible-trigger-context/use-collapsible-trigger-context.qwik.mjs +11 -0
- package/lib/components/collapsible/hooks/use-collapsible-trigger-context/use-collapsible-trigger-context.types.d.ts +13 -0
- package/lib/components/collapsible/index.d.ts +2 -0
- package/lib/components/collapsible/index.qwik.mjs +8 -0
- package/lib/components/collapsible/parts/collapsible-indicator/collapsible-indicator.d.ts +8 -0
- package/lib/components/collapsible/parts/collapsible-indicator/collapsible-indicator.qwik.mjs +27 -0
- package/lib/components/collapsible/parts/collapsible-indicator/collapsible-indicator.types.d.ts +15 -0
- package/lib/components/collapsible/parts/collapsible-indicator/index.d.ts +2 -0
- package/lib/components/collapsible/parts/collapsible-panel/collapsible-panel.d.ts +7 -0
- package/lib/components/collapsible/parts/collapsible-panel/collapsible-panel.qwik.mjs +169 -0
- package/lib/components/collapsible/parts/collapsible-panel/collapsible-panel.types.d.ts +31 -0
- package/lib/components/collapsible/parts/collapsible-panel/index.d.ts +2 -0
- package/lib/components/collapsible/parts/collapsible-root/collapsible-root.d.ts +7 -0
- package/lib/components/collapsible/parts/collapsible-root/collapsible-root.qwik.mjs +56 -0
- package/lib/components/collapsible/parts/collapsible-root/collapsible-root.types.d.ts +41 -0
- package/lib/components/collapsible/parts/collapsible-root/index.d.ts +2 -0
- package/lib/components/collapsible/parts/collapsible-trigger/collapsible-trigger.d.ts +7 -0
- package/lib/components/collapsible/parts/collapsible-trigger/collapsible-trigger.qwik.mjs +52 -0
- package/lib/components/collapsible/parts/collapsible-trigger/collapsible-trigger.types.d.ts +23 -0
- package/lib/components/collapsible/parts/collapsible-trigger/index.d.ts +2 -0
- package/lib/components/collapsible/parts/index.d.ts +8 -0
- package/lib/components/collapsible/parts/index.qwik.mjs +10 -0
- package/lib/components/index.d.ts +2 -0
- package/lib/components/toggle/contexts/index.d.ts +1 -0
- package/lib/components/toggle/contexts/toggle-root-context/index.d.ts +2 -0
- package/lib/components/toggle/contexts/toggle-root-context/toggle-root-context.d.ts +6 -0
- package/lib/components/toggle/contexts/toggle-root-context/toggle-root-context.qwik.mjs +5 -0
- package/lib/components/toggle/contexts/toggle-root-context/toggle-root-context.types.d.ts +22 -0
- package/lib/components/toggle/hooks/index.d.ts +1 -0
- package/lib/components/toggle/hooks/use-toggle-root-context/index.d.ts +2 -0
- package/lib/components/toggle/hooks/use-toggle-root-context/use-toggle-root-context.d.ts +7 -0
- package/lib/components/toggle/hooks/use-toggle-root-context/use-toggle-root-context.qwik.mjs +13 -0
- package/lib/components/toggle/hooks/use-toggle-root-context/use-toggle-root-context.types.d.ts +22 -0
- package/lib/components/toggle/index.d.ts +2 -0
- package/lib/components/toggle/index.qwik.mjs +6 -0
- package/lib/components/toggle/parts/index.d.ts +2 -0
- package/lib/components/toggle/parts/index.qwik.mjs +4 -0
- package/lib/components/toggle/parts/toggle-root/index.d.ts +2 -0
- package/lib/components/toggle/parts/toggle-root/toggle-root.d.ts +7 -0
- package/lib/components/toggle/parts/toggle-root/toggle-root.qwik.mjs +43 -0
- package/lib/components/toggle/parts/toggle-root/toggle-root.types.d.ts +41 -0
- package/lib/hooks/index.d.ts +2 -0
- package/lib/hooks/use-counter/index.d.ts +2 -0
- package/lib/hooks/use-counter/index.qwik.mjs +4 -0
- package/lib/hooks/use-counter/use-counter.d.ts +15 -0
- package/lib/hooks/use-counter/use-counter.qwik.mjs +113 -0
- package/lib/hooks/use-counter/use-counter.types.d.ts +73 -0
- package/lib/hooks/use-lifecycle/index.d.ts +2 -0
- package/lib/hooks/use-lifecycle/index.qwik.mjs +4 -0
- package/lib/hooks/use-lifecycle/use-lifecycle.d.ts +21 -0
- package/lib/hooks/use-lifecycle/use-lifecycle.qwik.mjs +59 -0
- package/lib/hooks/use-lifecycle/use-lifecycle.types.d.ts +33 -0
- package/lib/hooks/use-lifecycle/utilities/create-global-unmount-observer/create-global-unmount-observer.d.ts +13 -0
- package/lib/hooks/use-lifecycle/utilities/create-global-unmount-observer/create-global-unmount-observer.qwik.mjs +91 -0
- package/lib/hooks/use-lifecycle/utilities/create-global-unmount-observer/create-global-unmount-observer.types.d.ts +26 -0
- package/lib/hooks/use-lifecycle/utilities/create-global-unmount-observer/index.d.ts +2 -0
- package/lib/hooks/use-lifecycle/utilities/index.d.ts +1 -0
- package/lib/index.d.ts +1 -0
- package/lib/index.qwik.mjs +19 -3
- package/lib/types/entry-ui-qwik-event/entry-ui-qwik-event.types.d.ts +22 -0
- package/lib/types/entry-ui-qwik-event/index.d.ts +1 -0
- package/lib/types/entry-ui-qwik-event-state/entry-ui-qwik-event-state.types.d.ts +17 -0
- package/lib/types/entry-ui-qwik-event-state/index.d.ts +1 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/signal-or-readonly-signal/index.d.ts +1 -0
- package/lib/types/signal-or-readonly-signal/signal-or-readonly-signal.types.d.ts +12 -0
- package/lib/utilities/index.d.ts +1 -0
- package/lib/utilities/make-event-preventable/index.d.ts +1 -0
- package/lib/utilities/make-event-preventable/index.qwik.mjs +4 -0
- package/lib/utilities/make-event-preventable/make-event-preventable.d.ts +20 -0
- package/lib/utilities/make-event-preventable/make-event-preventable.qwik.mjs +10 -0
- package/lib/utilities/merge-styles/merge-styles.types.d.ts +1 -1
- package/package.json +26 -2
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
import { jsx } from "@qwik.dev/core/jsx-runtime";
|
|
2
|
+
import { component$, useComputed$, useContextProvider, Slot } from "@qwik.dev/core";
|
|
3
|
+
import { useControllable } from "../../../../hooks/use-controllable/use-controllable.qwik.mjs";
|
|
4
|
+
import { useIdManager } from "../../../../_internal/hooks/use-id-manager/use-id-manager.qwik.mjs";
|
|
5
|
+
import { mergeStyles } from "../../../../utilities/merge-styles/merge-styles.qwik.mjs";
|
|
6
|
+
import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
|
|
7
|
+
import { CollapsibleRootContext } from "../../contexts/collapsible-root-context/collapsible-root-context.qwik.mjs";
|
|
8
|
+
const CollapsibleRoot = component$((props) => {
|
|
9
|
+
const { as = "div", defaultOpen, open: _open, onOpenChange$, disabled: _disabled = false, style, ...others } = props;
|
|
10
|
+
const { state: open, setState$: setOpen$ } = useControllable({
|
|
11
|
+
defaultValue: defaultOpen ?? false,
|
|
12
|
+
controlledSignal: _open,
|
|
13
|
+
onChange$: onOpenChange$
|
|
14
|
+
});
|
|
15
|
+
const disabled = useComputed$(() => _disabled);
|
|
16
|
+
const triggerId = useIdManager({
|
|
17
|
+
prefix: "entry-ui-qwik-collapsible-trigger-"
|
|
18
|
+
});
|
|
19
|
+
const panelId = useIdManager({
|
|
20
|
+
prefix: "entry-ui-qwik-collapsible-panel-"
|
|
21
|
+
});
|
|
22
|
+
useContextProvider(CollapsibleRootContext, {
|
|
23
|
+
open,
|
|
24
|
+
setOpen$,
|
|
25
|
+
disabled,
|
|
26
|
+
triggerId,
|
|
27
|
+
panelId
|
|
28
|
+
});
|
|
29
|
+
return /* @__PURE__ */ jsx(Primitive.div, {
|
|
30
|
+
as,
|
|
31
|
+
"data-entry-ui-qwik-collapsible-root": "",
|
|
32
|
+
"data-state": open.value ? "open" : "closed",
|
|
33
|
+
"data-disabled": disabled.value ? "" : void 0,
|
|
34
|
+
style: mergeStyles([
|
|
35
|
+
{
|
|
36
|
+
// Performance optimization
|
|
37
|
+
// The `contain: layout style;` CSS property is used here to improve rendering performance.
|
|
38
|
+
// `contain: layout;` tells the browser that the internal layout of this component
|
|
39
|
+
// is self-contained and does not affect the layout of elements outside of it. This prevents
|
|
40
|
+
// costly re-calculations of the entire page layout when the collapsible panel expands or collapses,
|
|
41
|
+
// which is especially beneficial during animations.
|
|
42
|
+
// `contain: style;` ensures that CSS properties that can affect the rest of the page,
|
|
43
|
+
// like counters, are isolated to this element.
|
|
44
|
+
// Together, these properties create a performance "bubble," allowing the browser to optimize
|
|
45
|
+
// rendering by treating the collapsible component as an independent unit.
|
|
46
|
+
contain: "layout style"
|
|
47
|
+
},
|
|
48
|
+
style
|
|
49
|
+
]),
|
|
50
|
+
...others,
|
|
51
|
+
children: /* @__PURE__ */ jsx(Slot, {})
|
|
52
|
+
});
|
|
53
|
+
});
|
|
54
|
+
export {
|
|
55
|
+
CollapsibleRoot
|
|
56
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { PropsOf, Component, Signal, QRL } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the `Collapsible.Root` component.
|
|
4
|
+
* Extends the standard HTML attributes for a `<div>` element.
|
|
5
|
+
*/
|
|
6
|
+
export interface CollapsibleRootProps 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 open state of the collapsible when it is initially rendered.
|
|
17
|
+
* Use when you do not need to control its open state.
|
|
18
|
+
*
|
|
19
|
+
* @default undefined
|
|
20
|
+
*/
|
|
21
|
+
defaultOpen?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The controlled open state of the collapsible.
|
|
24
|
+
* Must be used in conjunction with `onOpenChange$`.
|
|
25
|
+
*
|
|
26
|
+
* @default undefined
|
|
27
|
+
*/
|
|
28
|
+
open?: Signal<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* A `QRL` callback function that is called when the open state of the collapsible changes.
|
|
31
|
+
*
|
|
32
|
+
* @default undefined
|
|
33
|
+
*/
|
|
34
|
+
onOpenChange$?: QRL<(open: boolean) => void>;
|
|
35
|
+
/**
|
|
36
|
+
* When `true`, prevents the user from interacting with the collapsible.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { CollapsibleTriggerProps } from './collapsible-trigger.types';
|
|
2
|
+
/**
|
|
3
|
+
* A button that opens and closes the collapsible panel.
|
|
4
|
+
*
|
|
5
|
+
* Renders a `<button>` element.
|
|
6
|
+
*/
|
|
7
|
+
export declare const CollapsibleTrigger: import("@qwik.dev/core").Component<CollapsibleTriggerProps>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { jsx } from "@qwik.dev/core/jsx-runtime";
|
|
2
|
+
import { component$, useSignal, useComputed$, $, useContextProvider, Slot } from "@qwik.dev/core";
|
|
3
|
+
import { useLifecycle } from "../../../../hooks/use-lifecycle/use-lifecycle.qwik.mjs";
|
|
4
|
+
import { mergeRefs } from "../../../../utilities/merge-refs/merge-refs.qwik.mjs";
|
|
5
|
+
import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
|
|
6
|
+
import { useCollapsibleRootContext } from "../../contexts/collapsible-root-context/collapsible-root-context.qwik.mjs";
|
|
7
|
+
import { CollapsibleTriggerContext } from "../../contexts/collapsible-trigger-context/collapsible-trigger-context.qwik.mjs";
|
|
8
|
+
const CollapsibleTrigger = component$((props) => {
|
|
9
|
+
const { as = "button", ref: _ref, id, disabled: _disabled, onClick$, ...others } = props;
|
|
10
|
+
const { open, setOpen$, disabled: rootDisabled, triggerId, panelId } = useCollapsibleRootContext();
|
|
11
|
+
const ref = useSignal(void 0);
|
|
12
|
+
const disabled = useComputed$(() => _disabled ?? rootDisabled.value);
|
|
13
|
+
useLifecycle({
|
|
14
|
+
element: ref,
|
|
15
|
+
onMount$: $(() => triggerId.set$(id)),
|
|
16
|
+
onUnmount$: $(() => triggerId.delete$())
|
|
17
|
+
});
|
|
18
|
+
const handleClick$ = $((event) => {
|
|
19
|
+
const entryUIQwikEvent = event;
|
|
20
|
+
if (!entryUIQwikEvent.entryUIQwikHandlerPrevented && !disabled.value) {
|
|
21
|
+
setOpen$(!open.value);
|
|
22
|
+
}
|
|
23
|
+
});
|
|
24
|
+
useContextProvider(CollapsibleTriggerContext, {
|
|
25
|
+
disabled
|
|
26
|
+
});
|
|
27
|
+
return /* @__PURE__ */ jsx(Primitive.button, {
|
|
28
|
+
as,
|
|
29
|
+
ref: mergeRefs([
|
|
30
|
+
_ref,
|
|
31
|
+
ref
|
|
32
|
+
]),
|
|
33
|
+
type: "button",
|
|
34
|
+
id: triggerId.id.value,
|
|
35
|
+
disabled: disabled.value,
|
|
36
|
+
"aria-controls": panelId.id.value && open.value ? panelId.id.value : void 0,
|
|
37
|
+
"aria-expanded": panelId.id.value ? open.value : void 0,
|
|
38
|
+
"data-entry-ui-qwik-collapsible-trigger": "",
|
|
39
|
+
"data-state": open.value ? "open" : "closed",
|
|
40
|
+
// Present when the entire collapsible component is in a disabled state.
|
|
41
|
+
"data-disabled": rootDisabled.value ? "" : void 0,
|
|
42
|
+
onClick$: [
|
|
43
|
+
onClick$,
|
|
44
|
+
handleClick$
|
|
45
|
+
],
|
|
46
|
+
...others,
|
|
47
|
+
children: /* @__PURE__ */ jsx(Slot, {})
|
|
48
|
+
});
|
|
49
|
+
});
|
|
50
|
+
export {
|
|
51
|
+
CollapsibleTrigger
|
|
52
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { PropsOf, Component } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the `Collapsible.Trigger` component.
|
|
4
|
+
* Extends the standard HTML attributes for a `<button>` element.
|
|
5
|
+
*/
|
|
6
|
+
export interface CollapsibleTriggerProps extends PropsOf<'button'> {
|
|
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 "button"
|
|
13
|
+
*/
|
|
14
|
+
as?: string | Component;
|
|
15
|
+
/**
|
|
16
|
+
* When `true`, prevents the user from interacting with the trigger.
|
|
17
|
+
* If left `undefined`, this state will be inherited from the `disabled`
|
|
18
|
+
* prop of the `Collapsible.Root` component.
|
|
19
|
+
*
|
|
20
|
+
* @default undefined
|
|
21
|
+
*/
|
|
22
|
+
disabled?: boolean;
|
|
23
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export type { CollapsibleRootProps as RootProps } from './collapsible-root';
|
|
2
|
+
export type { CollapsibleTriggerProps as TriggerProps } from './collapsible-trigger';
|
|
3
|
+
export type { CollapsiblePanelProps as PanelProps } from './collapsible-panel';
|
|
4
|
+
export type { CollapsibleIndicatorProps as IndicatorProps } from './collapsible-indicator';
|
|
5
|
+
export { CollapsibleRoot as Root } from './collapsible-root';
|
|
6
|
+
export { CollapsibleTrigger as Trigger } from './collapsible-trigger';
|
|
7
|
+
export { CollapsiblePanel as Panel } from './collapsible-panel';
|
|
8
|
+
export { CollapsibleIndicator as Indicator } from './collapsible-indicator';
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { CollapsibleRoot } from "./collapsible-root/collapsible-root.qwik.mjs";
|
|
2
|
+
import { CollapsibleTrigger } from "./collapsible-trigger/collapsible-trigger.qwik.mjs";
|
|
3
|
+
import { CollapsiblePanel } from "./collapsible-panel/collapsible-panel.qwik.mjs";
|
|
4
|
+
import { CollapsibleIndicator } from "./collapsible-indicator/collapsible-indicator.qwik.mjs";
|
|
5
|
+
export {
|
|
6
|
+
CollapsibleIndicator as Indicator,
|
|
7
|
+
CollapsiblePanel as Panel,
|
|
8
|
+
CollapsibleRoot as Root,
|
|
9
|
+
CollapsibleTrigger as Trigger
|
|
10
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toggle-root-context';
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import type { ToggleRootContextValue } from './toggle-root-context.types';
|
|
2
|
+
/**
|
|
3
|
+
* Provides the context for the `Toggle.Root` component, allowing descendant
|
|
4
|
+
* components to access readonly signals and `QRL` functions without prop drilling.
|
|
5
|
+
*/
|
|
6
|
+
export declare const ToggleRootContext: import("@qwik.dev/core").ContextId<ToggleRootContextValue>;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReadonlySignal, QRL } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* The value provided by the `Toggle.Root` context.
|
|
4
|
+
* Contains the readonly signals and `QRL` functions shared with descendant components.
|
|
5
|
+
*/
|
|
6
|
+
export interface ToggleRootContextValue {
|
|
7
|
+
/**
|
|
8
|
+
* A readonly signal whose value indicates the toggle's current pressed state.
|
|
9
|
+
* It is `true` when the toggle is on, and `false` when off.
|
|
10
|
+
*/
|
|
11
|
+
pressed: ReadonlySignal<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* A `QRL` function used to programmatically set the pressed state of the toggle.
|
|
14
|
+
* When invoked with `true`, the toggle will be on; with `false`, it will be off.
|
|
15
|
+
*/
|
|
16
|
+
setPressed$: QRL<(pressed: boolean) => void>;
|
|
17
|
+
/**
|
|
18
|
+
* A readonly signal that indicates whether the toggle is disabled.
|
|
19
|
+
* Its value is `true` if the toggle is disabled, preventing user interaction.
|
|
20
|
+
*/
|
|
21
|
+
disabled: ReadonlySignal<boolean>;
|
|
22
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './use-toggle-root-context';
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { UseToggleRootContextReturnValue } from './use-toggle-root-context.types';
|
|
2
|
+
/**
|
|
3
|
+
* A hook that provides access to the `Toggle.Root` component's internal state.
|
|
4
|
+
* It exposes readonly signals and `QRL` functions to interact with the toggle's state,
|
|
5
|
+
* allowing descendant components to control or react to its pressed/unpressed state.
|
|
6
|
+
*/
|
|
7
|
+
export declare const useToggleRootContext: () => UseToggleRootContextReturnValue;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { useContext } from "@qwik.dev/core";
|
|
2
|
+
import { ToggleRootContext } from "../../contexts/toggle-root-context/toggle-root-context.qwik.mjs";
|
|
3
|
+
const useToggleRootContext = () => {
|
|
4
|
+
const { pressed, setPressed$, disabled } = useContext(ToggleRootContext);
|
|
5
|
+
return {
|
|
6
|
+
pressed,
|
|
7
|
+
setPressed$,
|
|
8
|
+
disabled
|
|
9
|
+
};
|
|
10
|
+
};
|
|
11
|
+
export {
|
|
12
|
+
useToggleRootContext
|
|
13
|
+
};
|
package/lib/components/toggle/hooks/use-toggle-root-context/use-toggle-root-context.types.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { ReadonlySignal, QRL } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* The value returned by the `useToggleRootContext` hook.
|
|
4
|
+
* Provides access to the toggle's readonly signals and `QRL` functions for descendant components.
|
|
5
|
+
*/
|
|
6
|
+
export interface UseToggleRootContextReturnValue {
|
|
7
|
+
/**
|
|
8
|
+
* A readonly signal whose value indicates the toggle's current pressed state.
|
|
9
|
+
* It is `true` when the toggle is on, and `false` when off.
|
|
10
|
+
*/
|
|
11
|
+
pressed: ReadonlySignal<boolean>;
|
|
12
|
+
/**
|
|
13
|
+
* A `QRL` function used to programmatically set the pressed state of the toggle.
|
|
14
|
+
* When invoked with `true`, the toggle will be on; with `false`, it will be off.
|
|
15
|
+
*/
|
|
16
|
+
setPressed$: QRL<(pressed: boolean) => void>;
|
|
17
|
+
/**
|
|
18
|
+
* A readonly signal that indicates whether the toggle is disabled.
|
|
19
|
+
* Its value is `true` if the toggle is disabled, preventing user interaction.
|
|
20
|
+
*/
|
|
21
|
+
disabled: ReadonlySignal<boolean>;
|
|
22
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { jsx } from "@qwik.dev/core/jsx-runtime";
|
|
2
|
+
import { component$, useComputed$, $, useContextProvider, Slot } from "@qwik.dev/core";
|
|
3
|
+
import { useControllable } from "../../../../hooks/use-controllable/use-controllable.qwik.mjs";
|
|
4
|
+
import { Primitive } from "../../../../_internal/components/primitive/primitive.qwik.mjs";
|
|
5
|
+
import { ToggleRootContext } from "../../contexts/toggle-root-context/toggle-root-context.qwik.mjs";
|
|
6
|
+
const ToggleRoot = component$((props) => {
|
|
7
|
+
const { as = "button", defaultPressed, pressed: _pressed, onPressedChange$, disabled: _disabled = false, onClick$, ...others } = props;
|
|
8
|
+
const { state: pressed, setState$: setPressed$ } = useControllable({
|
|
9
|
+
defaultValue: defaultPressed ?? false,
|
|
10
|
+
controlledSignal: _pressed,
|
|
11
|
+
onChange$: onPressedChange$
|
|
12
|
+
});
|
|
13
|
+
const disabled = useComputed$(() => _disabled);
|
|
14
|
+
const handleClick$ = $((event) => {
|
|
15
|
+
const entryUIQwikEvent = event;
|
|
16
|
+
if (!entryUIQwikEvent.entryUIQwikHandlerPrevented && !disabled.value) {
|
|
17
|
+
setPressed$(!pressed.value);
|
|
18
|
+
}
|
|
19
|
+
});
|
|
20
|
+
useContextProvider(ToggleRootContext, {
|
|
21
|
+
pressed,
|
|
22
|
+
setPressed$,
|
|
23
|
+
disabled
|
|
24
|
+
});
|
|
25
|
+
return /* @__PURE__ */ jsx(Primitive.button, {
|
|
26
|
+
as,
|
|
27
|
+
type: "button",
|
|
28
|
+
disabled: disabled.value,
|
|
29
|
+
"aria-pressed": pressed.value,
|
|
30
|
+
"data-entry-ui-qwik-toggle-root": "",
|
|
31
|
+
"data-state": pressed.value ? "on" : "off",
|
|
32
|
+
"data-disabled": disabled.value ? "" : void 0,
|
|
33
|
+
onClick$: [
|
|
34
|
+
onClick$,
|
|
35
|
+
handleClick$
|
|
36
|
+
],
|
|
37
|
+
...others,
|
|
38
|
+
children: /* @__PURE__ */ jsx(Slot, {})
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
export {
|
|
42
|
+
ToggleRoot
|
|
43
|
+
};
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { PropsOf, Component, Signal, QRL } from '@qwik.dev/core';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the `Toggle.Root` component.
|
|
4
|
+
* Extends the standard HTML attributes for a `button` element.
|
|
5
|
+
*/
|
|
6
|
+
export interface ToggleRootProps extends PropsOf<'button'> {
|
|
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 "button"
|
|
13
|
+
*/
|
|
14
|
+
as?: string | Component;
|
|
15
|
+
/**
|
|
16
|
+
* The pressed state of the toggle when it is initially rendered.
|
|
17
|
+
* Use when you do not need to control its pressed state.
|
|
18
|
+
*
|
|
19
|
+
* @default undefined
|
|
20
|
+
*/
|
|
21
|
+
defaultPressed?: boolean;
|
|
22
|
+
/**
|
|
23
|
+
* The controlled pressed state of the toggle.
|
|
24
|
+
* Must be used in conjunction with `onPressedChange$`.
|
|
25
|
+
*
|
|
26
|
+
* @default undefined
|
|
27
|
+
*/
|
|
28
|
+
pressed?: Signal<boolean>;
|
|
29
|
+
/**
|
|
30
|
+
* A `QRL` callback function that is called when the pressed state of the toggle changes.
|
|
31
|
+
*
|
|
32
|
+
* @default undefined
|
|
33
|
+
*/
|
|
34
|
+
onPressedChange$?: QRL<(pressed: boolean) => void>;
|
|
35
|
+
/**
|
|
36
|
+
* When `true`, prevents the user from interacting with the toggle.
|
|
37
|
+
*
|
|
38
|
+
* @default false
|
|
39
|
+
*/
|
|
40
|
+
disabled?: boolean;
|
|
41
|
+
}
|
package/lib/hooks/index.d.ts
CHANGED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { UseCounterParams, UseCounterReturnValue } from './use-counter.types';
|
|
2
|
+
/**
|
|
3
|
+
* A hook that manages a numeric state with built-in clamping and validation logic.
|
|
4
|
+
*
|
|
5
|
+
* This hook provides a secure way to handle counter states by ensuring the value
|
|
6
|
+
* always remains within defined boundaries. It encapsulates a numeric signal and
|
|
7
|
+
* exposes it as a readonly signal, enforcing predictable state transitions through
|
|
8
|
+
* dedicated `QRL` functions.
|
|
9
|
+
*
|
|
10
|
+
* It features strict validation during development to ensure all parameters
|
|
11
|
+
* and operations result in finite numbers, preventing common pitfalls such as
|
|
12
|
+
* `NaN` or `Infinity` from polluting the state. It is ideal for quantity selectors,
|
|
13
|
+
* pagination, volume controls, or any UI element requiring bounded numeric input.
|
|
14
|
+
*/
|
|
15
|
+
export declare const useCounter: (params?: UseCounterParams) => UseCounterReturnValue;
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { useSignal, $ } from "@qwik.dev/core";
|
|
2
|
+
import { isDev } from "@qwik.dev/core/build";
|
|
3
|
+
import { isValidNumber } from "@entry-ui/utilities/is-valid-number";
|
|
4
|
+
import { clamp } from "@entry-ui/utilities/clamp";
|
|
5
|
+
import { fail } from "../../_internal/utilities/fail/fail.qwik.mjs";
|
|
6
|
+
import { warn } from "../../_internal/utilities/warn/warn.qwik.mjs";
|
|
7
|
+
const useCounter = (params = {}) => {
|
|
8
|
+
const { initialCount = 0, step = 1, min = -Number.MAX_VALUE, max = Number.MAX_VALUE } = params;
|
|
9
|
+
if (isDev) {
|
|
10
|
+
if (!isValidNumber(initialCount)) {
|
|
11
|
+
fail([
|
|
12
|
+
`Invalid 'initialCount' parameter in 'useCounter' hook.`,
|
|
13
|
+
`Expected a finite number, but received: ${initialCount}`
|
|
14
|
+
]);
|
|
15
|
+
}
|
|
16
|
+
if (!isValidNumber(step)) {
|
|
17
|
+
fail([
|
|
18
|
+
`Invalid 'step' parameter in 'useCounter' hook.`,
|
|
19
|
+
`Expected a finite number, but received: ${step}`
|
|
20
|
+
]);
|
|
21
|
+
}
|
|
22
|
+
if (!isValidNumber(min)) {
|
|
23
|
+
fail([
|
|
24
|
+
`Invalid 'min' parameter in 'useCounter' hook.`,
|
|
25
|
+
`Expected a finite number, but received: ${min}`
|
|
26
|
+
]);
|
|
27
|
+
}
|
|
28
|
+
if (!isValidNumber(max)) {
|
|
29
|
+
fail([
|
|
30
|
+
`Invalid 'max' parameter in 'useCounter' hook.`,
|
|
31
|
+
`Expected a finite number, but received: ${max}`
|
|
32
|
+
]);
|
|
33
|
+
}
|
|
34
|
+
if (min > max) {
|
|
35
|
+
fail([
|
|
36
|
+
`Invalid range for 'useCounter' hook.`,
|
|
37
|
+
`The 'min' parameter (${min}) must be less than or equal to the 'max' parameter (${max}).`
|
|
38
|
+
]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
const count = useSignal(clamp({
|
|
42
|
+
value: initialCount,
|
|
43
|
+
min,
|
|
44
|
+
max
|
|
45
|
+
}));
|
|
46
|
+
const increment$ = $(() => {
|
|
47
|
+
const nextCount = count.value + step;
|
|
48
|
+
if (!isValidNumber(nextCount)) {
|
|
49
|
+
if (isDev) {
|
|
50
|
+
warn([
|
|
51
|
+
`The 'increment$' QRL function from the 'useCounter' hook resulted in an invalid, non-finite number: ${nextCount}.`,
|
|
52
|
+
`The 'count' was not updated to prevent application instability.`
|
|
53
|
+
]);
|
|
54
|
+
}
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
count.value = clamp({
|
|
58
|
+
value: nextCount,
|
|
59
|
+
min,
|
|
60
|
+
max
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
const decrement$ = $(() => {
|
|
64
|
+
const nextCount = count.value - step;
|
|
65
|
+
if (!isValidNumber(nextCount)) {
|
|
66
|
+
if (isDev) {
|
|
67
|
+
warn([
|
|
68
|
+
`The 'decrement$' QRL function from the 'useCounter' hook resulted in an invalid, non-finite number: ${nextCount}.`,
|
|
69
|
+
`The 'count' was not updated to prevent application instability.`
|
|
70
|
+
]);
|
|
71
|
+
}
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
count.value = clamp({
|
|
75
|
+
value: nextCount,
|
|
76
|
+
min,
|
|
77
|
+
max
|
|
78
|
+
});
|
|
79
|
+
});
|
|
80
|
+
const set$ = $((value) => {
|
|
81
|
+
if (!isValidNumber(value)) {
|
|
82
|
+
if (isDev) {
|
|
83
|
+
warn([
|
|
84
|
+
`The 'set$' QRL function from the 'useCounter' hook was called with an invalid, non-finite number: ${value}.`,
|
|
85
|
+
`The 'count' was not updated to prevent application instability.`
|
|
86
|
+
]);
|
|
87
|
+
}
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
count.value = clamp({
|
|
91
|
+
value,
|
|
92
|
+
min,
|
|
93
|
+
max
|
|
94
|
+
});
|
|
95
|
+
});
|
|
96
|
+
const reset$ = $(() => {
|
|
97
|
+
count.value = clamp({
|
|
98
|
+
value: initialCount,
|
|
99
|
+
min,
|
|
100
|
+
max
|
|
101
|
+
});
|
|
102
|
+
});
|
|
103
|
+
return {
|
|
104
|
+
count,
|
|
105
|
+
increment$,
|
|
106
|
+
decrement$,
|
|
107
|
+
reset$,
|
|
108
|
+
set$
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
export {
|
|
112
|
+
useCounter
|
|
113
|
+
};
|