@pg-labs-incubator/cobweb 0.0.0-stage → 0.0.2
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/LICENSE +163 -0
- package/README.md +82 -2
- package/package.json +112 -3
- package/src/action/action.yaml +291 -0
- package/src/action/button-group.yaml +56 -0
- package/src/action/button.yaml +239 -0
- package/src/action/split-button.yaml +87 -0
- package/src/color/color.yaml +181 -0
- package/src/color/palette.yaml +147 -0
- package/src/container/card.yaml +170 -0
- package/src/container/corner-radius.yaml +50 -0
- package/src/container/elevation.yaml +19 -0
- package/src/design.yaml +41 -0
- package/src/feedback/feedback.yaml +225 -0
- package/src/icon/icon-font.yaml +28 -0
- package/src/icon/icon.yaml +31 -0
- package/src/input/date-picker.yaml +144 -0
- package/src/input/date-range-input.yaml +162 -0
- package/src/input/range-slider.yaml +161 -0
- package/src/input/select.yaml +230 -0
- package/src/input/slider.yaml +172 -0
- package/src/input/text-field.yaml +240 -0
- package/src/input/time-picker.yaml +220 -0
- package/src/motion/motion.yaml +371 -0
- package/src/navigation/app-bar.yaml +147 -0
- package/src/navigation/navigation.yaml +339 -0
- package/src/navigation/scroll.yaml +23 -0
- package/src/navigation/search.yaml +112 -0
- package/src/navigation/tabs.yaml +144 -0
- package/src/navigation/toolbar.yaml +130 -0
- package/src/selection/checkbox.yaml +162 -0
- package/src/selection/chip.yaml +219 -0
- package/src/selection/radio.yaml +125 -0
- package/src/selection/segmented-group.yaml +11 -0
- package/src/selection/segmented.yaml +69 -0
- package/src/selection/switch.yaml +209 -0
- package/src/spacing/measurement.yaml +80 -0
- package/src/state/state.yaml +38 -0
- package/src/surface/surface.yaml +483 -0
- package/src/text/line-height.yaml +144 -0
- package/src/text/typeface.yaml +31 -0
- package/src/text/typescale.yaml +726 -0
- package/target/esbuild/action/action.css +1 -0
- package/target/esbuild/action/base.jsx +1 -0
- package/target/esbuild/action/button.jsx +17 -0
- package/target/esbuild/action/fab-menu-context.jsx +1 -0
- package/target/esbuild/action/fab-menu.jsx +15 -0
- package/target/esbuild/action/fab.jsx +7 -0
- package/target/esbuild/action/group.jsx +22 -0
- package/target/esbuild/action/icon-button.jsx +5 -0
- package/target/esbuild/action/index.jsx +1 -0
- package/target/esbuild/action/split-button.jsx +12 -0
- package/target/esbuild/color/contrast.jsx +1 -0
- package/target/esbuild/color/dynamic.jsx +1 -0
- package/target/esbuild/color/hct.jsx +1 -0
- package/target/esbuild/color/index.css +1 -0
- package/target/esbuild/color/index.jsx +1 -0
- package/target/esbuild/color/palette.jsx +1 -0
- package/target/esbuild/color/scheme.jsx +1 -0
- package/target/esbuild/color/temperature.jsx +1 -0
- package/target/esbuild/container/card.css +1 -0
- package/target/esbuild/container/card.jsx +1 -0
- package/target/esbuild/container/elevation-shadow.css +1 -0
- package/target/esbuild/container/elevation-shadow.jsx +1 -0
- package/target/esbuild/container/index.jsx +1 -0
- package/target/esbuild/dom/client.jsx +1 -0
- package/target/esbuild/dom/index.jsx +1 -0
- package/target/esbuild/dom/server.jsx +1 -0
- package/target/esbuild/dom/types.jsx +1 -0
- package/target/esbuild/feedback/badge.jsx +15 -0
- package/target/esbuild/feedback/feedback.css +1 -0
- package/target/esbuild/feedback/focus.jsx +1 -0
- package/target/esbuild/feedback/index.jsx +1 -0
- package/target/esbuild/feedback/loading.jsx +7 -0
- package/target/esbuild/feedback/observe.jsx +1 -0
- package/target/esbuild/feedback/progress.jsx +35 -0
- package/target/esbuild/feedback/snackbar.jsx +23 -0
- package/target/esbuild/feedback/tooltip.jsx +24 -0
- package/target/esbuild/icon/icon.css +1 -0
- package/target/esbuild/icon/icon.jsx +1 -0
- package/target/esbuild/icon/index.jsx +1 -0
- package/target/esbuild/index.css +1 -0
- package/target/esbuild/index.jsx +1 -0
- package/target/esbuild/input/autocomplete.jsx +5 -0
- package/target/esbuild/input/base.jsx +4 -0
- package/target/esbuild/input/date-picker.css +1 -0
- package/target/esbuild/input/date-picker.jsx +104 -0
- package/target/esbuild/input/date-range-input.css +1 -0
- package/target/esbuild/input/date-time.jsx +21 -0
- package/target/esbuild/input/index.css +1 -0
- package/target/esbuild/input/index.jsx +1 -0
- package/target/esbuild/input/paired-input.jsx +1 -0
- package/target/esbuild/input/picker-dialog.css +1 -0
- package/target/esbuild/input/picker-dialog.jsx +14 -0
- package/target/esbuild/input/select.css +1 -0
- package/target/esbuild/input/select.jsx +63 -0
- package/target/esbuild/input/slider.css +1 -0
- package/target/esbuild/input/slider.jsx +51 -0
- package/target/esbuild/input/text-field.css +1 -0
- package/target/esbuild/input/text-field.jsx +67 -0
- package/target/esbuild/input/time-picker.css +1 -0
- package/target/esbuild/input/time-picker.jsx +29 -0
- package/target/esbuild/motion/frame.jsx +1 -0
- package/target/esbuild/motion/index.css +1 -0
- package/target/esbuild/motion/index.jsx +1 -0
- package/target/esbuild/motion/material.jsx +1 -0
- package/target/esbuild/motion/motion.jsx +1 -0
- package/target/esbuild/motion/spring.jsx +1 -0
- package/target/esbuild/motion/transition.css +1 -0
- package/target/esbuild/motion/transition.jsx +1 -0
- package/target/esbuild/motion/velocity.jsx +1 -0
- package/target/esbuild/navigation/app-bar.jsx +51 -0
- package/target/esbuild/navigation/base.jsx +1 -0
- package/target/esbuild/navigation/drawer.jsx +25 -0
- package/target/esbuild/navigation/index.jsx +1 -0
- package/target/esbuild/navigation/navigation.css +1 -0
- package/target/esbuild/navigation/navigation.jsx +29 -0
- package/target/esbuild/navigation/scroll.jsx +1 -0
- package/target/esbuild/navigation/search.jsx +29 -0
- package/target/esbuild/navigation/tabs.jsx +7 -0
- package/target/esbuild/navigation/toolbar.jsx +23 -0
- package/target/esbuild/selection/base.jsx +1 -0
- package/target/esbuild/selection/checkbox.jsx +14 -0
- package/target/esbuild/selection/chip.jsx +23 -0
- package/target/esbuild/selection/index.jsx +1 -0
- package/target/esbuild/selection/radio.jsx +9 -0
- package/target/esbuild/selection/segmented.jsx +15 -0
- package/target/esbuild/selection/selection.css +1 -0
- package/target/esbuild/selection/switch.jsx +14 -0
- package/target/esbuild/shape/corner-rounding.jsx +1 -0
- package/target/esbuild/shape/cubic.jsx +1 -0
- package/target/esbuild/shape/index.jsx +1 -0
- package/target/esbuild/shape/material-shapes.jsx +1 -0
- package/target/esbuild/shape/morph.jsx +1 -0
- package/target/esbuild/shape/path.jsx +1 -0
- package/target/esbuild/shape/point.jsx +1 -0
- package/target/esbuild/shape/rounded-polygon.jsx +1 -0
- package/target/esbuild/shape/shapes.jsx +1 -0
- package/target/esbuild/spacing/index.jsx +1 -0
- package/target/esbuild/state/component.css +1 -0
- package/target/esbuild/state/component.jsx +1 -0
- package/target/esbuild/state/controller.jsx +1 -0
- package/target/esbuild/state/index.jsx +1 -0
- package/target/esbuild/state/ripple.jsx +1 -0
- package/target/esbuild/state/state.jsx +1 -0
- package/target/esbuild/state/style.jsx +1 -0
- package/target/esbuild/surface/carousel-layout.jsx +1 -0
- package/target/esbuild/surface/carousel.css +1 -0
- package/target/esbuild/surface/carousel.jsx +10 -0
- package/target/esbuild/surface/dialog.jsx +35 -0
- package/target/esbuild/surface/divider.jsx +1 -0
- package/target/esbuild/surface/drag.jsx +1 -0
- package/target/esbuild/surface/gestures.css +1 -0
- package/target/esbuild/surface/gestures.jsx +7 -0
- package/target/esbuild/surface/index.css +1 -0
- package/target/esbuild/surface/index.jsx +1 -0
- package/target/esbuild/surface/interactive.jsx +1 -0
- package/target/esbuild/surface/list-patterns.jsx +26 -0
- package/target/esbuild/surface/list.css +1 -0
- package/target/esbuild/surface/list.jsx +9 -0
- package/target/esbuild/surface/menu.css +1 -0
- package/target/esbuild/surface/menu.jsx +12 -0
- package/target/esbuild/surface/scaffold.jsx +47 -0
- package/target/esbuild/surface/sheet.jsx +21 -0
- package/target/esbuild/surface/side-sheet.jsx +17 -0
- package/target/esbuild/surface/slots.jsx +1 -0
- package/target/esbuild/surface/surface.css +1 -0
- package/target/esbuild/surface/surface.jsx +1 -0
- package/target/esbuild/text/index.css +1 -0
- package/target/esbuild/text/index.jsx +1 -0
- package/target/esbuild/text/text.css +1 -0
- package/target/esbuild/text/text.jsx +3 -0
- package/target/esbuild/text/typography.css +1 -0
- package/target/esbuild/text/typography.jsx +1 -0
- package/target/esbuild/util/box-side.jsx +1 -0
- package/target/esbuild/util/debug.jsx +1 -0
- package/target/esbuild/util/dom.jsx +1 -0
- package/target/esbuild/util/event.jsx +1 -0
- package/target/esbuild/util/index.jsx +1 -0
- package/target/esbuild/util/preconditions.jsx +1 -0
- package/target/esbuild/util/reactive.jsx +1 -0
- package/target/tsc/action/action.css.d.ts +3 -0
- package/target/tsc/action/base.d.ts +211 -0
- package/target/tsc/action/button.d.ts +126 -0
- package/target/tsc/action/fab-menu-context.d.ts +16 -0
- package/target/tsc/action/fab-menu.d.ts +112 -0
- package/target/tsc/action/fab.d.ts +98 -0
- package/target/tsc/action/group.d.ts +166 -0
- package/target/tsc/action/icon-button.d.ts +79 -0
- package/target/tsc/action/index.d.ts +24 -0
- package/target/tsc/action/split-button.d.ts +78 -0
- package/target/tsc/color/contrast.d.ts +48 -0
- package/target/tsc/color/dynamic.d.ts +203 -0
- package/target/tsc/color/hct.d.ts +114 -0
- package/target/tsc/color/index.css.d.ts +3 -0
- package/target/tsc/color/index.d.ts +23 -0
- package/target/tsc/color/palette.d.ts +30 -0
- package/target/tsc/color/scheme.d.ts +446 -0
- package/target/tsc/color/temperature.d.ts +24 -0
- package/target/tsc/container/card.css.d.ts +3 -0
- package/target/tsc/container/card.d.ts +110 -0
- package/target/tsc/container/elevation-shadow.css.d.ts +3 -0
- package/target/tsc/container/elevation-shadow.d.ts +23 -0
- package/target/tsc/container/index.d.ts +44 -0
- package/target/tsc/dom/client.d.ts +387 -0
- package/target/tsc/dom/index.d.ts +93 -0
- package/target/tsc/dom/server.d.ts +65 -0
- package/target/tsc/dom/types.d.ts +134 -0
- package/target/tsc/feedback/badge.d.ts +116 -0
- package/target/tsc/feedback/feedback.css.d.ts +3 -0
- package/target/tsc/feedback/focus.d.ts +20 -0
- package/target/tsc/feedback/index.d.ts +17 -0
- package/target/tsc/feedback/loading.d.ts +194 -0
- package/target/tsc/feedback/observe.d.ts +75 -0
- package/target/tsc/feedback/progress.d.ts +281 -0
- package/target/tsc/feedback/snackbar.d.ts +398 -0
- package/target/tsc/feedback/tooltip.d.ts +326 -0
- package/target/tsc/icon/icon.css.d.ts +3 -0
- package/target/tsc/icon/icon.d.ts +69 -0
- package/target/tsc/icon/index.d.ts +13 -0
- package/target/tsc/index.css.d.ts +3 -0
- package/target/tsc/index.d.ts +7 -0
- package/target/tsc/input/autocomplete.d.ts +119 -0
- package/target/tsc/input/base.d.ts +282 -0
- package/target/tsc/input/date-picker.css.d.ts +3 -0
- package/target/tsc/input/date-picker.d.ts +351 -0
- package/target/tsc/input/date-range-input.css.d.ts +3 -0
- package/target/tsc/input/date-time.d.ts +171 -0
- package/target/tsc/input/index.css.d.ts +3 -0
- package/target/tsc/input/index.d.ts +27 -0
- package/target/tsc/input/paired-input.d.ts +435 -0
- package/target/tsc/input/picker-dialog.css.d.ts +3 -0
- package/target/tsc/input/picker-dialog.d.ts +84 -0
- package/target/tsc/input/select.css.d.ts +3 -0
- package/target/tsc/input/select.d.ts +267 -0
- package/target/tsc/input/slider.css.d.ts +3 -0
- package/target/tsc/input/slider.d.ts +372 -0
- package/target/tsc/input/text-field.css.d.ts +3 -0
- package/target/tsc/input/text-field.d.ts +415 -0
- package/target/tsc/input/time-picker.css.d.ts +3 -0
- package/target/tsc/input/time-picker.d.ts +212 -0
- package/target/tsc/motion/frame.d.ts +36 -0
- package/target/tsc/motion/index.css.d.ts +3 -0
- package/target/tsc/motion/index.d.ts +34 -0
- package/target/tsc/motion/material.d.ts +110 -0
- package/target/tsc/motion/motion.d.ts +235 -0
- package/target/tsc/motion/spring.d.ts +223 -0
- package/target/tsc/motion/transition.css.d.ts +3 -0
- package/target/tsc/motion/transition.d.ts +597 -0
- package/target/tsc/motion/velocity.d.ts +54 -0
- package/target/tsc/navigation/app-bar.d.ts +473 -0
- package/target/tsc/navigation/base.d.ts +331 -0
- package/target/tsc/navigation/drawer.d.ts +301 -0
- package/target/tsc/navigation/index.d.ts +25 -0
- package/target/tsc/navigation/navigation.css.d.ts +3 -0
- package/target/tsc/navigation/navigation.d.ts +537 -0
- package/target/tsc/navigation/scroll.d.ts +218 -0
- package/target/tsc/navigation/search.d.ts +332 -0
- package/target/tsc/navigation/tabs.d.ts +497 -0
- package/target/tsc/navigation/toolbar.d.ts +248 -0
- package/target/tsc/selection/base.d.ts +100 -0
- package/target/tsc/selection/checkbox.d.ts +194 -0
- package/target/tsc/selection/chip.d.ts +358 -0
- package/target/tsc/selection/index.d.ts +21 -0
- package/target/tsc/selection/radio.d.ts +198 -0
- package/target/tsc/selection/segmented.d.ts +333 -0
- package/target/tsc/selection/selection.css.d.ts +3 -0
- package/target/tsc/selection/switch.d.ts +165 -0
- package/target/tsc/shape/corner-rounding.d.ts +36 -0
- package/target/tsc/shape/cubic.d.ts +215 -0
- package/target/tsc/shape/index.d.ts +35 -0
- package/target/tsc/shape/material-shapes.d.ts +176 -0
- package/target/tsc/shape/morph.d.ts +91 -0
- package/target/tsc/shape/path.d.ts +177 -0
- package/target/tsc/shape/point.d.ts +165 -0
- package/target/tsc/shape/rounded-polygon.d.ts +289 -0
- package/target/tsc/shape/shapes.d.ts +76 -0
- package/target/tsc/spacing/index.d.ts +19 -0
- package/target/tsc/state/component.css.d.ts +3 -0
- package/target/tsc/state/component.d.ts +276 -0
- package/target/tsc/state/controller.d.ts +257 -0
- package/target/tsc/state/index.d.ts +19 -0
- package/target/tsc/state/ripple.d.ts +50 -0
- package/target/tsc/state/state.d.ts +129 -0
- package/target/tsc/state/style.d.ts +22 -0
- package/target/tsc/surface/carousel-layout.d.ts +212 -0
- package/target/tsc/surface/carousel.css.d.ts +3 -0
- package/target/tsc/surface/carousel.d.ts +231 -0
- package/target/tsc/surface/dialog.d.ts +582 -0
- package/target/tsc/surface/divider.d.ts +92 -0
- package/target/tsc/surface/drag.d.ts +92 -0
- package/target/tsc/surface/gestures.css.d.ts +3 -0
- package/target/tsc/surface/gestures.d.ts +292 -0
- package/target/tsc/surface/index.css.d.ts +3 -0
- package/target/tsc/surface/index.d.ts +29 -0
- package/target/tsc/surface/interactive.d.ts +22 -0
- package/target/tsc/surface/list-patterns.d.ts +384 -0
- package/target/tsc/surface/list.css.d.ts +3 -0
- package/target/tsc/surface/list.d.ts +340 -0
- package/target/tsc/surface/menu.css.d.ts +3 -0
- package/target/tsc/surface/menu.d.ts +590 -0
- package/target/tsc/surface/scaffold.d.ts +337 -0
- package/target/tsc/surface/sheet.d.ts +384 -0
- package/target/tsc/surface/side-sheet.d.ts +183 -0
- package/target/tsc/surface/slots.d.ts +21 -0
- package/target/tsc/surface/surface.css.d.ts +3 -0
- package/target/tsc/surface/surface.d.ts +192 -0
- package/target/tsc/text/index.css.d.ts +3 -0
- package/target/tsc/text/index.d.ts +18 -0
- package/target/tsc/text/text.css.d.ts +3 -0
- package/target/tsc/text/text.d.ts +94 -0
- package/target/tsc/text/typography.css.d.ts +3 -0
- package/target/tsc/text/typography.d.ts +82 -0
- package/target/tsc/util/box-side.d.ts +76 -0
- package/target/tsc/util/debug.d.ts +20 -0
- package/target/tsc/util/dom.d.ts +35 -0
- package/target/tsc/util/event.d.ts +93 -0
- package/target/tsc/util/index.d.ts +12 -0
- package/target/tsc/util/preconditions.d.ts +79 -0
- package/target/tsc/util/reactive.d.ts +36 -0
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
import type { ClientDomProps, DomComponent, DomProps, RenderServerDom } from "..";
|
|
2
|
+
import type { InteractionState } from "./state";
|
|
3
|
+
import { InteractableController } from "./controller";
|
|
4
|
+
import "./component.css";
|
|
5
|
+
/**
|
|
6
|
+
* Interaction user-trigger event handler.
|
|
7
|
+
*
|
|
8
|
+
* These handlers are invoked when an event, which *may* trigger entry into or exit from an
|
|
9
|
+
* interaction {@link ./state#InteractionState | state}, is received. The event is accepted from
|
|
10
|
+
* the element which the interaction state accepts events for: focus events always target the
|
|
11
|
+
* function element, and pointer enter and leave events always target the style element. Click
|
|
12
|
+
* events may target a descendant of either element, unless a nested native control or
|
|
13
|
+
* interactable owns them. Handlers are invoked when the event is triggered, irrespective of
|
|
14
|
+
* whether the interaction state of the event is {@link
|
|
15
|
+
* ./controller#InteractableController.isInteractionStateEnabled | enabled}.
|
|
16
|
+
*
|
|
17
|
+
* @typeParam E - event type
|
|
18
|
+
* @typeParam P - component properties type
|
|
19
|
+
* @see {@link InteractableProps}
|
|
20
|
+
*
|
|
21
|
+
* @param event - native event received by the component
|
|
22
|
+
* @param cont - controller owning the interaction
|
|
23
|
+
*/
|
|
24
|
+
export type InteractionEventHandler<E extends Event, P extends DomProps> = (event: E, cont: InteractableController<P>) => void;
|
|
25
|
+
/**
|
|
26
|
+
* Interaction {@link ./state#InteractionState | state} handler.
|
|
27
|
+
*
|
|
28
|
+
* These handlers are invoked *after* an interaction state is {@link
|
|
29
|
+
* InteractableProps.onInteractionStateEntered | entered} into or {@link
|
|
30
|
+
* InteractableProps.onInteractionStateExited | exited} from.
|
|
31
|
+
*
|
|
32
|
+
* @typeParam P - component properties type
|
|
33
|
+
* @see {@link InteractableProps.onInteractionStateEntered}
|
|
34
|
+
* @see {@link InteractableProps.onInteractionStateExited}
|
|
35
|
+
*
|
|
36
|
+
* @param state - interaction state entered or exited
|
|
37
|
+
* @param cont - controller owning the state
|
|
38
|
+
* @param event - originating event, if any
|
|
39
|
+
*/
|
|
40
|
+
export type InteractionStateHandler<P extends DomProps> = (state: InteractionState, cont: InteractableController<P>, event?: Event) => void;
|
|
41
|
+
/**
|
|
42
|
+
* Interactable {@link InteractableComponent | component} properties.
|
|
43
|
+
*
|
|
44
|
+
* @typeParam P - underlying DOM component properties type
|
|
45
|
+
*/
|
|
46
|
+
export type InteractableProps<P extends DomProps = DomProps> = P & {
|
|
47
|
+
/**
|
|
48
|
+
* Handle entry of pointing device into hit test boundaries of the component.
|
|
49
|
+
*
|
|
50
|
+
* The handler specified, if any, is invoked *before* any {@link ./state#HoverState |
|
|
51
|
+
* hover} state *may* have been entered into.
|
|
52
|
+
*
|
|
53
|
+
* @remarks
|
|
54
|
+
* This is **not** reactive.
|
|
55
|
+
*/
|
|
56
|
+
readonly onPointerEnter?: InteractionEventHandler<PointerEvent, P> | undefined;
|
|
57
|
+
/**
|
|
58
|
+
* Handle exit of pointing device from hit test boundaries of the component.
|
|
59
|
+
*
|
|
60
|
+
* The handler specified, if any, is invoked *before* any {@link ./state#HoverState |
|
|
61
|
+
* hover} state *may* have been exited from.
|
|
62
|
+
*
|
|
63
|
+
* @remarks
|
|
64
|
+
* This is **not** reactive.
|
|
65
|
+
*/
|
|
66
|
+
readonly onPointerLeave?: InteractionEventHandler<PointerEvent, P> | undefined;
|
|
67
|
+
/**
|
|
68
|
+
* Handle activation of the component.
|
|
69
|
+
*
|
|
70
|
+
* The handler specified, if any, is invoked *before* any {@link ./state#PressState |
|
|
71
|
+
* press} state *may* have been exited from.
|
|
72
|
+
*
|
|
73
|
+
* @remarks
|
|
74
|
+
* This is **not** reactive.
|
|
75
|
+
*/
|
|
76
|
+
readonly onClick?: InteractionEventHandler<MouseEvent, P> | undefined;
|
|
77
|
+
/**
|
|
78
|
+
* Handle component receiving focus.
|
|
79
|
+
*
|
|
80
|
+
* The handler specified, if any, is invoked *before* any {@link ./state#FocusState |
|
|
81
|
+
* focus} state *may* have been entered into.
|
|
82
|
+
*
|
|
83
|
+
* @remarks
|
|
84
|
+
* This is **not** reactive.
|
|
85
|
+
*/
|
|
86
|
+
readonly onFocusIn?: InteractionEventHandler<FocusEvent, P> | undefined;
|
|
87
|
+
/**
|
|
88
|
+
* Handle component losing focus.
|
|
89
|
+
*
|
|
90
|
+
* The handler specified, if any, is invoked *before* any {@link ./state#FocusState |
|
|
91
|
+
* focus} state *may* have been exited from.
|
|
92
|
+
*
|
|
93
|
+
* @remarks
|
|
94
|
+
* This is **not** reactive.
|
|
95
|
+
*/
|
|
96
|
+
readonly onFocusOut?: InteractionEventHandler<FocusEvent, P> | undefined;
|
|
97
|
+
/**
|
|
98
|
+
* Handle entry into an interaction state.
|
|
99
|
+
*
|
|
100
|
+
* The handler specified, if any, is invoked *after* the component enters into a state.
|
|
101
|
+
*
|
|
102
|
+
* @remarks
|
|
103
|
+
* This is **not** reactive.
|
|
104
|
+
*/
|
|
105
|
+
readonly onInteractionStateEntered?: InteractionStateHandler<P> | undefined;
|
|
106
|
+
/**
|
|
107
|
+
* Handle exit from a interaction state.
|
|
108
|
+
*
|
|
109
|
+
* The handler specified, if any, is invoked *after* the component exits from a state.
|
|
110
|
+
*
|
|
111
|
+
* @remarks
|
|
112
|
+
* This is **not** reactive.
|
|
113
|
+
*/
|
|
114
|
+
readonly onInteractionStateExited?: InteractionStateHandler<P> | undefined;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Interactable {@link ..#DomComponent | DOM} component.
|
|
118
|
+
*
|
|
119
|
+
* Interactable components are DOM components which allow user interaction. Interactable
|
|
120
|
+
* components are usually defined using {@link defineInteractableComponent}, and are controlled
|
|
121
|
+
* using an implementation of {@link ./controller#InteractableController}.
|
|
122
|
+
*
|
|
123
|
+
* @typeParam P - component properties
|
|
124
|
+
* @see {@link defineInteractableComponent}
|
|
125
|
+
*/
|
|
126
|
+
export type InteractableComponent<P extends DomProps> = DomComponent<InteractableProps<P>>;
|
|
127
|
+
/**
|
|
128
|
+
* Define an {@link InteractableComponent | interactable} DOM component.
|
|
129
|
+
*
|
|
130
|
+
* This should be used, in place of {@link ..#defineDomComponent}, to define a component which
|
|
131
|
+
* renders elements that support user interaction. Like {@link ..#defineDomComponent}, the `server`
|
|
132
|
+
* and `client` suppliers are used to provide the server-side DOM rendering function and
|
|
133
|
+
* client-side DOM {@link ./controller#InteractableController | controller} implementation.
|
|
134
|
+
*
|
|
135
|
+
* The server-side render function behaves the same as {@link ..#defineDomComponent}. The
|
|
136
|
+
* client-side supplier, however, is invoked with the base interactable component controller, and
|
|
137
|
+
* is expected to return a controller implementation which extends the specified base controller.
|
|
138
|
+
*
|
|
139
|
+
* All interactable components support the {@link InteractableProps | base} interactable component
|
|
140
|
+
* properties. These properties are not forwarded to the server-side render function or client-side
|
|
141
|
+
* controller implementation.
|
|
142
|
+
*
|
|
143
|
+
* ```tsx
|
|
144
|
+
* import type { DomProps } from "@pg-labs-incubator/cobweb";
|
|
145
|
+
* import type { InteractableComponent, InteractableProps } from "@pg-labs-incubator/cobweb/state";
|
|
146
|
+
* import type { JSX } from "solid-js";
|
|
147
|
+
*
|
|
148
|
+
* import {
|
|
149
|
+
* HoverState,
|
|
150
|
+
* PressState,
|
|
151
|
+
* defineInteractableComponent
|
|
152
|
+
* } from "@pg-labs-incubator/cobweb/state";
|
|
153
|
+
*
|
|
154
|
+
* export type MyProps = DomProps<HTMLSpanElement, JSX.HTMLElementTags["span"]> & {
|
|
155
|
+
* size?: "large" | "medium" | "small";
|
|
156
|
+
* };
|
|
157
|
+
*
|
|
158
|
+
* export const MyComponent: InteractableComponent<MyProps> = defineInteractableComponent(
|
|
159
|
+
* // Render on server-side:
|
|
160
|
+
* () => (elemProps, localProps) => <span
|
|
161
|
+
* {...elemProps}
|
|
162
|
+
* classList={{
|
|
163
|
+
* ...elemProps.classList,
|
|
164
|
+
* [`MyComponent-size-${localProps.size ?? "small"}`]: true,
|
|
165
|
+
* "MyComponent": true
|
|
166
|
+
* }}
|
|
167
|
+
* />,
|
|
168
|
+
* // Render on client-side:
|
|
169
|
+
* (Base) => class extends Base<MyProps> {
|
|
170
|
+
* constructor(props: MyProps) {
|
|
171
|
+
* super(props, {
|
|
172
|
+
* // Our style element is our function element; without this, we would need to
|
|
173
|
+
* // include the function reference.
|
|
174
|
+
* styleElementIsFunction: true,
|
|
175
|
+
* // By default, our element supports hovering and pressing states:
|
|
176
|
+
* enabledInteractionStates: HoverState | PressState
|
|
177
|
+
* });
|
|
178
|
+
* }
|
|
179
|
+
*
|
|
180
|
+
* protected override applyComponentProps(): void {
|
|
181
|
+
* // Invoked in a reactive context. When `size` changes, we'll get invoked again.
|
|
182
|
+
* const [size, sizeChanged] = super.readProp("size");
|
|
183
|
+
*
|
|
184
|
+
* if (sizeChanged) {
|
|
185
|
+
* // `size` changed, update the style
|
|
186
|
+
* super.setClass("size", `MyComponent-size-${size ?? "small"}`);
|
|
187
|
+
* }
|
|
188
|
+
* }
|
|
189
|
+
*
|
|
190
|
+
* protected override render(children: JSX.Element): JSX.Element {
|
|
191
|
+
* return <span class="MyComponent">{children}</span>;
|
|
192
|
+
* }
|
|
193
|
+
* }
|
|
194
|
+
* );
|
|
195
|
+
* ```
|
|
196
|
+
*
|
|
197
|
+
* # Design
|
|
198
|
+
*
|
|
199
|
+
* Interactable components render state-layer, which is used to apply visual styling to the style
|
|
200
|
+
* element to indicate the state of the component. The component author is expected to define the
|
|
201
|
+
* following CSS properties, when an interaction state is entered into, to control the state-layer.
|
|
202
|
+
*
|
|
203
|
+
* | Property | Description |
|
|
204
|
+
* | -------------------------------------------- | --------------------------------------------- |
|
|
205
|
+
* | `--cw-interactable-focusIndicator-color` | Focus indicator color. |
|
|
206
|
+
* | `--cw-interactable-focusIndicator-offset` | Offset of focus indicator from style container, where a value greater than, less than, or equal to zero place the indicator outside of the style element, inside the style element, or directly on top of the style element, respectively. |
|
|
207
|
+
* | `--cw-interactable-focusIndicator-thickness` | Thickness, in pixels, of the focus indicator. |
|
|
208
|
+
* | `--cw-interactable-stateLayer-color` | State-layer color. |
|
|
209
|
+
* | `--cw-interactable-stateLayer-opacity` | Opacity of state-layer. |
|
|
210
|
+
* | `--cw-interactable-ripple-color` | Press ripple color. |
|
|
211
|
+
* | `--cw-interactable-ripple-opacity` | Opacity of press ripple. |
|
|
212
|
+
* | `--cw-interactable-ripple-radius` | Radius of an unbounded press ripple, or `auto` for a bounded ripple. |
|
|
213
|
+
*
|
|
214
|
+
* The `focusIndicator` properties can be set even if the component hasn't entered into the {@link
|
|
215
|
+
* FocusState | focus} state, as these properties are applied to the state-layer style only when
|
|
216
|
+
* the focus state is entered into. The state-layer properties, however, must be set whenever the
|
|
217
|
+
* respective state is entered into, as they determine the state-layer color for as long as the
|
|
218
|
+
* component has an interaction state enabled.
|
|
219
|
+
*
|
|
220
|
+
* The {@link PressState | press} state is shown by a ripple, painted above the state layer of the
|
|
221
|
+
* hover or focus state, whose class remains applied during a press. The ripple properties are
|
|
222
|
+
* read once the press class has been applied, and the ripple keeps them until it has faded out,
|
|
223
|
+
* after the press has been released. They are therefore set within the press class, rather than
|
|
224
|
+
* the state-layer properties, as Compose shows a press with a ripple of the pressed opacity
|
|
225
|
+
* (`RippleAlpha.pressedAlpha`), not with its state layer. A `currentcolor` ripple color is the
|
|
226
|
+
* color of the style element. A component which renders no ripple, as it is constructed with
|
|
227
|
+
* `noPressRipple`, may set the state-layer properties within its press class instead.
|
|
228
|
+
*
|
|
229
|
+
* A ripple is bounded by default: it spreads from the press position until it covers the state
|
|
230
|
+
* layer. A component whose Compose counterpart uses an unbounded ripple, such as a checkbox
|
|
231
|
+
* (`ripple(bounded = false, radius = CheckboxTokens.StateLayerSize / 2)`), assigns its radius to
|
|
232
|
+
* `--cw-interactable-ripple-radius` instead; the ripple then spreads from the center of the state
|
|
233
|
+
* layer to that radius.
|
|
234
|
+
*
|
|
235
|
+
* In the example below, `.MyComponent` is always applied to the style element, and the
|
|
236
|
+
* controller is constructed with `_MyComponent` as `baseInteractionCssClassName`. The focus
|
|
237
|
+
* indicator, when rendered, is blue, 2 pixels outside the style element, and 3 pixels wide. The
|
|
238
|
+
* state-layer is purple, except in the focus state, whose state-layer is red. Presses ripple in
|
|
239
|
+
* the state-layer color.
|
|
240
|
+
*
|
|
241
|
+
* ```css
|
|
242
|
+
* .MyComponent {
|
|
243
|
+
* --cw-interactable-focusIndicator-color: blue;
|
|
244
|
+
* --cw-interactable-focusIndicator-offset: 2px;
|
|
245
|
+
* --cw-interactable-focusIndicator-thickness: 3px;
|
|
246
|
+
* --cw-interactable-stateLayer-color: purple;
|
|
247
|
+
* }
|
|
248
|
+
*
|
|
249
|
+
* ._MyComponent-hover {
|
|
250
|
+
* --cw-interactable-stateLayer-opacity: 0.08;
|
|
251
|
+
* }
|
|
252
|
+
*
|
|
253
|
+
* ._MyComponent-focus {
|
|
254
|
+
* --cw-interactable-stateLayer-color: red;
|
|
255
|
+
* --cw-interactable-stateLayer-opacity: 0.1;
|
|
256
|
+
* }
|
|
257
|
+
*
|
|
258
|
+
* ._MyComponent-press {
|
|
259
|
+
* --cw-interactable-ripple-color: var(--cw-interactable-stateLayer-color);
|
|
260
|
+
* --cw-interactable-ripple-opacity: 0.1;
|
|
261
|
+
* }
|
|
262
|
+
* ```
|
|
263
|
+
*
|
|
264
|
+
* The [`cw-State`](./state.yaml) system design attribute can be used to assign the above
|
|
265
|
+
* properties to standard values. As the value of these properties change, the state-layer color
|
|
266
|
+
* transitions with the fast effects spring, and the focus indicator geometry with the fast
|
|
267
|
+
* spatial spring. A component which overrides the transitions of the state-layer pseudo-element
|
|
268
|
+
* must transition `color`, the state-layer color, not `background-color`.
|
|
269
|
+
*
|
|
270
|
+
* @typeParam P - component properties type
|
|
271
|
+
* @param server - server-side DOM render function supplier
|
|
272
|
+
* @param client - client-side DOM controller implementation provider
|
|
273
|
+
* @returns resulting component
|
|
274
|
+
* @see {@link ..#defineDomComponent}
|
|
275
|
+
*/
|
|
276
|
+
export declare function defineInteractableComponent<P extends DomProps>(server: () => RenderServerDom<P>, client: (Controller: typeof InteractableController) => (new (props: P) => InteractableController<P>)): InteractableComponent<ClientDomProps<InteractableProps<P>>>;
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
import type { DomControllerOptions, DomProps, FunctionElement, StyleElement } from "..";
|
|
2
|
+
import type { InteractableProps } from "./component";
|
|
3
|
+
import type { InteractionState } from "./state";
|
|
4
|
+
import { DomController } from "../dom/client";
|
|
5
|
+
/**
|
|
6
|
+
* Interactable {@link InteractableController | controller} options.
|
|
7
|
+
*/
|
|
8
|
+
export interface InteractableControllerOptions extends DomControllerOptions {
|
|
9
|
+
/**
|
|
10
|
+
* Base CSS class name of interaction states.
|
|
11
|
+
*
|
|
12
|
+
* The name specified is used as the base name for classes applied, to the style element,
|
|
13
|
+
* when an interaction state is entered into. For example, if a component enters into the
|
|
14
|
+
* {@link ./state#HoverState | hover} state, the class applied is `<base>-hover`, where
|
|
15
|
+
* `<base>` is the value specified.
|
|
16
|
+
*
|
|
17
|
+
* @defaultValue `"cw-interactable"`
|
|
18
|
+
*/
|
|
19
|
+
baseInteractionCssClassName?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Mask of enabled interaction {@link ./state#InteractionState | states}.
|
|
22
|
+
*
|
|
23
|
+
* @defaultValue `0`
|
|
24
|
+
* @see {@link InteractableController.isInteractionStateEnabled}
|
|
25
|
+
*/
|
|
26
|
+
enabledInteractionStates?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Ripple motion is not applied when entering into {@link ./state#PressState | press}
|
|
29
|
+
* state.
|
|
30
|
+
*
|
|
31
|
+
* @defaultValue `false`
|
|
32
|
+
* @see {@link InteractableController.isPressRippleDisabled}
|
|
33
|
+
*/
|
|
34
|
+
noPressRipple?: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* Focus-ring is not rendered, around style element, when container enters into a keyboard
|
|
37
|
+
* initiated {@link ./state#FocusState | focus} state.
|
|
38
|
+
*
|
|
39
|
+
* @defaultValue `false`
|
|
40
|
+
* @see {@link InteractableController.isFocusIndicatorDisabled}
|
|
41
|
+
*/
|
|
42
|
+
noFocusIndicator?: boolean;
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Client-side interactable {@link ./component#InteractableComponent | component} controller.
|
|
46
|
+
*
|
|
47
|
+
* Instances of this control the state of an interactable component instance, with respect to the
|
|
48
|
+
* {@link InteractableProps | properties} *and* interaction {@link InteractionState | states}
|
|
49
|
+
* the component is configured with. The base implementation of this extends the {@link
|
|
50
|
+
* DomController | base} DOM controller, and extends it with support for interactable component
|
|
51
|
+
* {@link InteractableProps | properties}. Implementations are expected to {@link
|
|
52
|
+
* InteractableController.setEnabledInteractionStates | control} interaction states and their local
|
|
53
|
+
* component properties, if any.
|
|
54
|
+
*
|
|
55
|
+
* The {@link DomController.onStyleElementChanged | `onStyleElementChanged`} and {@link
|
|
56
|
+
* DomController.onFunctionElementChanged | `onFunctionElementChanged`} methods, declared by {@link
|
|
57
|
+
* DomController}, are implemented by the base controller. If an implementation overrides these
|
|
58
|
+
* methods, they **must** invoke the implementations provided by this class. All other methods
|
|
59
|
+
* declared by {@link DomController} must be implemented as required by {@link DomController}.
|
|
60
|
+
*
|
|
61
|
+
* Controller instances can be constructed with {@link InteractableControllerOptions | options}.
|
|
62
|
+
* These options extend the {@link DomControllerOptions | base} options accepted by {@link
|
|
63
|
+
* DomController}. The initial set of {@link InteractableController.setEnabledInteractionStates |
|
|
64
|
+
* enabled} interaction states can be specified in {@link
|
|
65
|
+
* InteractableControllerOptions.enabledInteractionStates | `enabledInteractionStates`}.
|
|
66
|
+
*
|
|
67
|
+
* Each controller instance listens for user-trigger events to perform entry into or exit from
|
|
68
|
+
* {@link InteractableController.isInteractionStateEnabled | enabled} interaction states. If
|
|
69
|
+
* event listeners are defined in the properties the controller is constructed with, then those
|
|
70
|
+
* event listeners are invoked *irrespective* of whether the corresponding interaction state, for
|
|
71
|
+
* the respective event, is enabled or not.
|
|
72
|
+
*
|
|
73
|
+
* # Elements
|
|
74
|
+
*
|
|
75
|
+
* Styling is applied only to the {@link DomController.styleElement | style} element. User-events,
|
|
76
|
+
* however, are listened for on both the style and {@link DomController.functionElement | function}
|
|
77
|
+
* elements. The state type determines which element an event is accepted from, in terms of a
|
|
78
|
+
* trigger.
|
|
79
|
+
*
|
|
80
|
+
* | State | Element | Description |
|
|
81
|
+
* | -------------------------- | -------- | ---------------------------------------------------- |
|
|
82
|
+
* | {@link FocusState | Focus} | Function | Entry into and exit from the focus state is controlled by the `focusin` and `focusout` events targeted at the function element itself; focus moving within its descendants is ignored. When `focusin` is received, the focus state is entered into if, and only if, the `:focus-visible` pseudo-class is applied to the function element. |
|
|
83
|
+
* | {@link HoverState | Hover} | Style | Entry into and exit from the hover state is controlled by the `pointerenter` and `pointerleave` events targeted at the style element, for any pointing device except touch. |
|
|
84
|
+
* | {@link PressState | Press} | Both | A press begins with `pointerdown` from the primary pointing device, a `click` which no press preceded, or <kbd>Space</kbd> on a native function `button`. Events targeted at a descendant belong to the controller, unless a nested native control or interactable owns them. The press ends with the `click` following its release, and is cancelled by `pointercancel`, `contextmenu`, `pointerleave` of a non-touch pointer before release, or loss of focus during a keyboard press. |
|
|
85
|
+
* | {@link DragState | Drag} | Both | Entry into the drag state occurs once the pointer of a press moves {@link DRAG_THRESHOLD_PX} or more, after which the style element captures the pointer until release, cancellation, or lost capture. |
|
|
86
|
+
*
|
|
87
|
+
* # Styles
|
|
88
|
+
*
|
|
89
|
+
* The `cw-interactable` CSS class is added to the style element *while* the component has at least
|
|
90
|
+
* **one** interaction state {@link InteractableController.setEnabledInteractionStates | enabled}.
|
|
91
|
+
* The `cw-interactable` CSS class sets the `position` and `z-index` properties, of the style
|
|
92
|
+
* element, to `relative` and `0`, respectively. These two properties are *required* as the
|
|
93
|
+
* state-layer, rendered within the `::before` pseudo-element of the style element, has an
|
|
94
|
+
* absolute position.
|
|
95
|
+
*
|
|
96
|
+
* As states are entered into or exited from, state CSS classes are applied or removed from the
|
|
97
|
+
* style element. The CSS class applied or removed from the style element takes the form
|
|
98
|
+
* `<base>-<state>`, where `<base>` is configured by {@link
|
|
99
|
+
* InteractableControllerOptions.baseInteractionCssClassName}, and `<state>` is the {@link
|
|
100
|
+
* ./state#nameOfInteractionState | name} of the respective interaction state. For example, when
|
|
101
|
+
* `<base>` is `foo` and the state being entered into (or exited from) is the hover state, then
|
|
102
|
+
* the class applied (or removed) is `foo-hover`. Only the class of the highest-precedence state
|
|
103
|
+
* entered into is applied, except while the press state is the highest-precedence state: the
|
|
104
|
+
* class of the highest-precedence state below it then remains applied, since a press is shown by
|
|
105
|
+
* a ripple painted above the state layer of that state. The focus indicator is rendered for as
|
|
106
|
+
* long as the focus state is entered into.
|
|
107
|
+
*
|
|
108
|
+
* Entry into the press state applies a ripple, unless {@link
|
|
109
|
+
* InteractableControllerOptions.noPressRipple | disabled}, which follows the Compose ripple
|
|
110
|
+
* (`RippleAnimation.kt`). The ripple paints the `--cw-interactable-ripple-color` and
|
|
111
|
+
* `--cw-interactable-ripple-opacity` of the style element, read once the press class has been
|
|
112
|
+
* applied, and fades out once the press is released or cancelled, independently of the press
|
|
113
|
+
* class.
|
|
114
|
+
*
|
|
115
|
+
* # Documents and shadow roots
|
|
116
|
+
*
|
|
117
|
+
* Trigger events are delegated: a single set of capture listeners is installed on each document
|
|
118
|
+
* containing mapped elements, and on each closed shadow root containing them, since a document
|
|
119
|
+
* cannot resolve nodes within a closed shadow root. The document and closed shadow roots of an
|
|
120
|
+
* element are settled once, after the synchronous render which mapped the element. An element
|
|
121
|
+
* which is still detached at that point settles its roots on its first trigger event.
|
|
122
|
+
*
|
|
123
|
+
* Moving an already-connected control into another document, or into a closed shadow root, is
|
|
124
|
+
* **not** supported; render the control there instead. Events dispatched synchronously, within the
|
|
125
|
+
* task which rendered a control into another document or into a closed shadow root, are not
|
|
126
|
+
* delegated.
|
|
127
|
+
*
|
|
128
|
+
* # Synchronized states
|
|
129
|
+
*
|
|
130
|
+
* When interaction states become enabled, or elements are rendered into a connected tree (such as
|
|
131
|
+
* during hydration), the controller enters into the states which already apply: the focus state if
|
|
132
|
+
* the function element matches `:focus-visible`, and the hover state if the style element matches
|
|
133
|
+
* `:hover` while a pointing device of the user-agent can hover.
|
|
134
|
+
*
|
|
135
|
+
* @typeParam P - component properties type
|
|
136
|
+
* @see {@link ./component#defineInteractableComponent}
|
|
137
|
+
*/
|
|
138
|
+
export declare abstract class InteractableController<P extends DomProps> extends DomController<P> {
|
|
139
|
+
#private;
|
|
140
|
+
/**
|
|
141
|
+
* Construct a new interactable DOM controller.
|
|
142
|
+
*
|
|
143
|
+
* @param props - component properties
|
|
144
|
+
* @param opts - options to construct controller with
|
|
145
|
+
* @throws {@link Error} `opts.enabledInteractionStates` is not a valid interaction state mask
|
|
146
|
+
*/
|
|
147
|
+
constructor(props: InteractableProps<P>, opts?: InteractableControllerOptions);
|
|
148
|
+
/**
|
|
149
|
+
* Owner of the component has released the controller.
|
|
150
|
+
*
|
|
151
|
+
* This is `true` as soon as cleanup has begun, including while interaction callbacks invoked
|
|
152
|
+
* by the cleanup are still on the stack.
|
|
153
|
+
*
|
|
154
|
+
* @returns `true` if, and only if, the controller has been released
|
|
155
|
+
*/
|
|
156
|
+
protected get isControllerDisposed(): boolean;
|
|
157
|
+
/**
|
|
158
|
+
* Press triggered ripple motion is disabled.
|
|
159
|
+
*
|
|
160
|
+
* If this returns `true`, then the ripple motion is *not* applied when the component
|
|
161
|
+
* enters into a {@link PressState | press} state.
|
|
162
|
+
*
|
|
163
|
+
* @returns `true` if, and only if, press ripple is disabled
|
|
164
|
+
*/
|
|
165
|
+
isPressRippleDisabled(): boolean;
|
|
166
|
+
/**
|
|
167
|
+
* Focus indicator is disabled.
|
|
168
|
+
*
|
|
169
|
+
* If this returns `true`, then a focus indicator is *not* rendered when the component
|
|
170
|
+
* enters into a {@link FocusState | focus} state.
|
|
171
|
+
*
|
|
172
|
+
* @returns `true` if, and only if, focus indicator is disabled
|
|
173
|
+
*/
|
|
174
|
+
isFocusIndicatorDisabled(): boolean;
|
|
175
|
+
/**
|
|
176
|
+
* Mask of interaction {@link ./state#InteractionState | states} which are currently
|
|
177
|
+
* {@link InteractableController.setEnabledInteractionStates | enabled}.
|
|
178
|
+
*
|
|
179
|
+
* @returns enabled interaction state mask
|
|
180
|
+
* @see {@link InteractableController.isInteractionStateEnabled}
|
|
181
|
+
*/
|
|
182
|
+
get enabledInteractionStates(): number;
|
|
183
|
+
/**
|
|
184
|
+
* Mask of interaction {@link ./state#InteractionState | states} which are currently
|
|
185
|
+
* entered into.
|
|
186
|
+
*
|
|
187
|
+
* @returns entered interaction state mask
|
|
188
|
+
* @see {@link InteractableController.isInteractionStateEntered}
|
|
189
|
+
*/
|
|
190
|
+
get enteredInteractionStates(): number;
|
|
191
|
+
/**
|
|
192
|
+
* Test whether an interaction {@link ./state#InteractionState | state} has been {@link
|
|
193
|
+
* InteractableController.setEnabledInteractionStates | enabled}.
|
|
194
|
+
*
|
|
195
|
+
* @param state - state to test
|
|
196
|
+
* @returns `true` if, and only if, `state` is enabled
|
|
197
|
+
* @see {@link InteractableController.enabledInteractionStates}
|
|
198
|
+
*/
|
|
199
|
+
isInteractionStateEnabled(state: InteractionState): boolean;
|
|
200
|
+
/**
|
|
201
|
+
* Test whether an interaction {@link ./state#InteractionState | state} has been entered
|
|
202
|
+
* into.
|
|
203
|
+
*
|
|
204
|
+
* @param state - state to test
|
|
205
|
+
* @returns `true` if, and only if, `state` has been entered into
|
|
206
|
+
* @see {@link InteractableController.enteredInteractionStates}
|
|
207
|
+
*/
|
|
208
|
+
isInteractionStateEntered(state: InteractionState): boolean;
|
|
209
|
+
/**
|
|
210
|
+
* Set enabled interaction {@link ./state#InteractionState | states}.
|
|
211
|
+
*
|
|
212
|
+
* Upon return, only states set in `states` will be enabled for the component. Each entered
|
|
213
|
+
* state which is not set in `states` is exited from, and each newly enabled state which already
|
|
214
|
+
* applies is {@link InteractableController.#syncInteractionStates | entered} into.
|
|
215
|
+
*
|
|
216
|
+
* @param states - mask of states to enable
|
|
217
|
+
* @throws {@link Error} `states` is not a {@link ./state#isInteractionStateMask | valid}
|
|
218
|
+
* interaction state mask
|
|
219
|
+
*/
|
|
220
|
+
setEnabledInteractionStates(states: number): void;
|
|
221
|
+
/**
|
|
222
|
+
* Handle trigger event.
|
|
223
|
+
*
|
|
224
|
+
* This is invoked whenever a trigger event is received for the component. By default,
|
|
225
|
+
* this will invoke the interaction event {@link InteractionEventHandler | handler}
|
|
226
|
+
* installed for the respective event, if any: `click`, `focusin` and `focusout` of the
|
|
227
|
+
* function element, and `pointerenter` and `pointerleave` of the style element, for any
|
|
228
|
+
* pointing device except touch.
|
|
229
|
+
*
|
|
230
|
+
* @param event - trigger event received
|
|
231
|
+
*/
|
|
232
|
+
protected onEvent(event: Event): void;
|
|
233
|
+
/**
|
|
234
|
+
* Handle style element replacement before the controller reference is updated.
|
|
235
|
+
*
|
|
236
|
+
* The style-element getter still exposes the previous element during this hook.
|
|
237
|
+
*
|
|
238
|
+
* @param curr - new style element, or `null` when absent
|
|
239
|
+
* @see {@link ../dom/client#DomController.onStyleElementChanged}
|
|
240
|
+
*/
|
|
241
|
+
protected onStyleElementChanged(curr: StyleElement | null): void;
|
|
242
|
+
/**
|
|
243
|
+
* Handle function element replacement before the controller reference is updated.
|
|
244
|
+
*
|
|
245
|
+
* The function-element getter still exposes the previous element during this hook.
|
|
246
|
+
*
|
|
247
|
+
* @param curr - new function element, or `null` when absent
|
|
248
|
+
* @see {@link ../dom/client#DomController.onFunctionElementChanged}
|
|
249
|
+
*/
|
|
250
|
+
protected onFunctionElementChanged(curr: FunctionElement<P> | null): void;
|
|
251
|
+
/**
|
|
252
|
+
* Release delegated listeners and active interaction state with the owning Solid root.
|
|
253
|
+
*
|
|
254
|
+
* @see {@link ../dom/client#DomController.onControllerCleanup}
|
|
255
|
+
*/
|
|
256
|
+
protected onControllerCleanup(): void;
|
|
257
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Component state definitions.
|
|
3
|
+
*
|
|
4
|
+
* This module exports definitions for implementing user interaction states, as
|
|
5
|
+
* [defined](https://m3.material.io/foundations/interaction/states/overview) by the Material 3
|
|
6
|
+
* design specification. The {@link ./component#defineInteractableComponent} function can be
|
|
7
|
+
* used to define an interactable component, which renders DOM elements.
|
|
8
|
+
*
|
|
9
|
+
* Components defined using {@link ./component#defineInteractableComponent}, by default, render
|
|
10
|
+
* a state-layer within the `::before` pseudo element of the style element. The state-layer
|
|
11
|
+
* supports ripple press motions and focus indicators.
|
|
12
|
+
*
|
|
13
|
+
* @packageDocumentation
|
|
14
|
+
*/
|
|
15
|
+
export type { InteractableController, InteractableControllerOptions } from "./controller";
|
|
16
|
+
export type { InteractionState, InteractionStateName } from "./state";
|
|
17
|
+
export type { InteractableComponent, InteractableProps, InteractionEventHandler, InteractionStateHandler } from "./component";
|
|
18
|
+
export { defineInteractableComponent } from "./component";
|
|
19
|
+
export { DragState, FocusState, HoverState, PressState, isInteractionState, isInteractionStateMask, nameOfInteractionState } from "./state";
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Press ripple applied to a {@link ./style#STATE_LAYER_PSEUDO_ELEMENT | state-layer}.
|
|
3
|
+
*
|
|
4
|
+
* A ripple is painted above the state layer, so the state layer of the hover or focus state
|
|
5
|
+
* remains visible beneath it, and removes itself once it has faded out.
|
|
6
|
+
*
|
|
7
|
+
* @see {@link applyRipple}
|
|
8
|
+
*/
|
|
9
|
+
export interface Ripple {
|
|
10
|
+
/**
|
|
11
|
+
* Fade the ripple out, once it has spread.
|
|
12
|
+
*
|
|
13
|
+
* This is invoked once the press of the ripple is released or cancelled, as Compose finishes
|
|
14
|
+
* a ripple on `PressInteraction.Release` and `PressInteraction.Cancel`
|
|
15
|
+
* (`RippleAnimation.finish()`). A ripple still fading in switches to its full opacity, and
|
|
16
|
+
* fades out once it has spread. Subsequent invocations have no effect.
|
|
17
|
+
*/
|
|
18
|
+
finish(): void;
|
|
19
|
+
/**
|
|
20
|
+
* Remove the ripple immediately.
|
|
21
|
+
*
|
|
22
|
+
* This is required only when a ripple must disappear before it has faded out, such as when its
|
|
23
|
+
* element is released.
|
|
24
|
+
*/
|
|
25
|
+
cancel(): void;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Apply ripple motion to an element with a {@link ./style#STATE_LAYER_PSEUDO_ELEMENT |
|
|
29
|
+
* state-layer}.
|
|
30
|
+
*
|
|
31
|
+
* The ripple follows the Compose ripple (`RippleAnimation.kt`): its circle starts with a radius of
|
|
32
|
+
* 30% of the largest state-layer dimension, at the press position, and grows 10px beyond the
|
|
33
|
+
* radius covering the state layer, while its center moves to the center of the state layer. An
|
|
34
|
+
* unbounded ripple, whose `--cw-interactable-ripple-radius` is a length, starts at the center
|
|
35
|
+
* instead, and grows to that radius. The ripple paints the `--cw-interactable-ripple-color` and
|
|
36
|
+
* `--cw-interactable-ripple-opacity` of `elem`, read when the ripple is applied, above the state
|
|
37
|
+
* layer, and fades out once {@link Ripple.finish | finished}.
|
|
38
|
+
*
|
|
39
|
+
* Ripples already painted by `elem` are finished, and keep fading out while the new ripple spreads.
|
|
40
|
+
* Durations and easings are fixed, as in Compose, rather than following the motion scheme.
|
|
41
|
+
*
|
|
42
|
+
* Applying a ripple measures `elem` and its state layer once; no layout or style is read while the
|
|
43
|
+
* ripple moves.
|
|
44
|
+
*
|
|
45
|
+
* @param elem - element to enter into ripple for
|
|
46
|
+
* @param origin - position, in client coordinates, of the press or `undefined` to center the
|
|
47
|
+
* ripple within `elem`
|
|
48
|
+
* @returns applied ripple, or `undefined` when the ripple could not be applied
|
|
49
|
+
*/
|
|
50
|
+
export declare function applyRipple(elem: Element, origin?: readonly [number, number]): Ripple | undefined;
|