@realnation/builder-shared-sdk 1.2.1 → 2.0.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.
|
@@ -23,24 +23,39 @@ export declare const INTERACTION_KEYS: {
|
|
|
23
23
|
readonly scale: "selected-scale";
|
|
24
24
|
readonly opacity: "selected-opacity";
|
|
25
25
|
};
|
|
26
|
-
|
|
26
|
+
/** `none` is the section's off switch: the element has no interaction state at all. */
|
|
27
|
+
export type InteractionTrigger = 'none' | 'hover' | 'click' | 'appear' | 'loop';
|
|
27
28
|
export declare const INTERACTION_TRIGGERS: readonly InteractionTrigger[];
|
|
28
29
|
/** Anything the Builder stores for one element. Values arrive untyped from the API. */
|
|
29
30
|
export type InteractionProperty = Record<string, unknown>;
|
|
30
|
-
/**
|
|
31
|
+
/**
|
|
32
|
+
* The CSS properties this feature is allowed to touch.
|
|
33
|
+
*
|
|
34
|
+
* camelCase by default, which is what a Vue `:style` binding expects. Hosts
|
|
35
|
+
* that build their style objects out of literal CSS property names can ask for
|
|
36
|
+
* kebab-case instead: mixing the two on one element leaves the winner decided
|
|
37
|
+
* by object key order, which is not a thing to leave to chance.
|
|
38
|
+
*/
|
|
31
39
|
export interface InteractionStyle {
|
|
32
40
|
transition?: string;
|
|
33
41
|
transform?: string;
|
|
34
42
|
backgroundColor?: string;
|
|
35
43
|
borderColor?: string;
|
|
36
44
|
opacity?: string;
|
|
45
|
+
/** Present instead of the camelCase names when kebab-case keys are requested. */
|
|
46
|
+
[cssProperty: string]: string | undefined;
|
|
37
47
|
}
|
|
48
|
+
export type StyleKeyCase = 'camel' | 'kebab';
|
|
49
|
+
/** Rewrites the compound property names; transition / transform / opacity are already valid CSS. */
|
|
50
|
+
export declare function toKebabStyle(style: InteractionStyle): InteractionStyle;
|
|
38
51
|
/**
|
|
39
52
|
* Whether the element has an interaction state at all.
|
|
40
53
|
*
|
|
41
|
-
*
|
|
42
|
-
*
|
|
43
|
-
*
|
|
54
|
+
* The trigger is the section's master switch, because it answers the first
|
|
55
|
+
* question: does this element react to anything? Easing only describes what
|
|
56
|
+
* the change looks like once something does trigger it. `none` is the default,
|
|
57
|
+
* so an element nobody configured behaves exactly as it did before this
|
|
58
|
+
* feature existed. Every entry point checks this first.
|
|
44
59
|
*/
|
|
45
60
|
export declare function isInteractionEnabled(property: InteractionProperty | null | undefined): boolean;
|
|
46
61
|
export declare function interactionTriggerOf(property: InteractionProperty | null | undefined): InteractionTrigger;
|
|
@@ -59,6 +74,8 @@ export interface InteractionStyleOptions {
|
|
|
59
74
|
* easing towards normal immediately and the starting point is never seen.
|
|
60
75
|
*/
|
|
61
76
|
instant?: boolean;
|
|
77
|
+
/** Key style of the returned object. Defaults to camelCase. */
|
|
78
|
+
keys?: StyleKeyCase;
|
|
62
79
|
}
|
|
63
80
|
/**
|
|
64
81
|
* The style to merge onto an element for a given state.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interaction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUnB,CAAC;AAEX,MAAM,MAAM,kBAAkB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/interaction/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,wEAAwE;AACxE,eAAO,MAAM,gBAAgB;;;;;;;;;;CAUnB,CAAC;AAEX,uFAAuF;AACvF,MAAM,MAAM,kBAAkB,GAAG,MAAM,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,GAAG,MAAM,CAAC;AAChF,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAAiD,CAAC;AAEhH,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D;;;;;;;GAOG;AACH,MAAM,WAAW,gBAAgB;IAC/B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,iFAAiF;IACjF,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,MAAM,YAAY,GAAG,OAAO,GAAG,OAAO,CAAC;AAO7C,oGAAoG;AACpG,wBAAgB,YAAY,CAAC,KAAK,EAAE,gBAAgB,GAAG,gBAAgB,CAItE;AAOD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAE9F;AAED,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB,CAGzG;AAED,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAE9F;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,MAAM,CAG5F;AAED,MAAM,WAAW,uBAAuB;IACtC;;;;OAIG;IACH,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,+DAA+D;IAC/D,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAChD,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAsClB"}
|
|
@@ -23,7 +23,18 @@ export const INTERACTION_KEYS = {
|
|
|
23
23
|
scale: 'selected-scale',
|
|
24
24
|
opacity: 'selected-opacity',
|
|
25
25
|
};
|
|
26
|
-
export const INTERACTION_TRIGGERS = ['hover', 'click', 'appear', 'loop'];
|
|
26
|
+
export const INTERACTION_TRIGGERS = ['none', 'hover', 'click', 'appear', 'loop'];
|
|
27
|
+
const KEBAB = {
|
|
28
|
+
backgroundColor: 'background-color',
|
|
29
|
+
borderColor: 'border-color',
|
|
30
|
+
};
|
|
31
|
+
/** Rewrites the compound property names; transition / transform / opacity are already valid CSS. */
|
|
32
|
+
export function toKebabStyle(style) {
|
|
33
|
+
const out = {};
|
|
34
|
+
for (const [k, v] of Object.entries(style))
|
|
35
|
+
out[KEBAB[k] ?? k] = v;
|
|
36
|
+
return out;
|
|
37
|
+
}
|
|
27
38
|
const num = (value, fallback) => {
|
|
28
39
|
const n = Number(value);
|
|
29
40
|
return Number.isFinite(n) ? n : fallback;
|
|
@@ -31,18 +42,18 @@ const num = (value, fallback) => {
|
|
|
31
42
|
/**
|
|
32
43
|
* Whether the element has an interaction state at all.
|
|
33
44
|
*
|
|
34
|
-
*
|
|
35
|
-
*
|
|
36
|
-
*
|
|
45
|
+
* The trigger is the section's master switch, because it answers the first
|
|
46
|
+
* question: does this element react to anything? Easing only describes what
|
|
47
|
+
* the change looks like once something does trigger it. `none` is the default,
|
|
48
|
+
* so an element nobody configured behaves exactly as it did before this
|
|
49
|
+
* feature existed. Every entry point checks this first.
|
|
37
50
|
*/
|
|
38
51
|
export function isInteractionEnabled(property) {
|
|
39
|
-
|
|
40
|
-
return false;
|
|
41
|
-
return String(property[INTERACTION_KEYS.easing] ?? 'none') !== 'none';
|
|
52
|
+
return interactionTriggerOf(property) !== 'none';
|
|
42
53
|
}
|
|
43
54
|
export function interactionTriggerOf(property) {
|
|
44
|
-
const raw = String(property?.[INTERACTION_KEYS.trigger] ?? '
|
|
45
|
-
return INTERACTION_TRIGGERS.includes(raw) ? raw : '
|
|
55
|
+
const raw = String(property?.[INTERACTION_KEYS.trigger] ?? 'none');
|
|
56
|
+
return INTERACTION_TRIGGERS.includes(raw) ? raw : 'none';
|
|
46
57
|
}
|
|
47
58
|
export function interactionDurationOf(property) {
|
|
48
59
|
return num(property?.[INTERACTION_KEYS.duration], 400);
|
|
@@ -70,7 +81,9 @@ export function interactionStyle(property, active, options = {}) {
|
|
|
70
81
|
if (!isInteractionEnabled(property))
|
|
71
82
|
return {};
|
|
72
83
|
const bag = property;
|
|
73
|
-
|
|
84
|
+
// An instant change is still expressible: set the duration to zero. Easing
|
|
85
|
+
// only decides how the time is spent, so it never needs an "off" of its own.
|
|
86
|
+
const easing = String(bag[INTERACTION_KEYS.easing] ?? 'ease-out');
|
|
74
87
|
const duration = interactionDurationOf(bag);
|
|
75
88
|
const style = {};
|
|
76
89
|
if (options.instant) {
|
|
@@ -81,6 +94,8 @@ export function interactionStyle(property, active, options = {}) {
|
|
|
81
94
|
.map((prop) => `${prop} ${duration}ms ${easing}`)
|
|
82
95
|
.join(', ');
|
|
83
96
|
}
|
|
97
|
+
// The normal state only ever carries `transition`, whose name is the same in
|
|
98
|
+
// both conventions, so this early return needs no conversion.
|
|
84
99
|
if (!active)
|
|
85
100
|
return style;
|
|
86
101
|
const bg = bag[INTERACTION_KEYS.bgColor];
|
|
@@ -101,5 +116,5 @@ export function interactionStyle(property, active, options = {}) {
|
|
|
101
116
|
const opacity = bag[INTERACTION_KEYS.opacity];
|
|
102
117
|
if (opacity != null)
|
|
103
118
|
style.opacity = String(num(opacity, 100) / 100);
|
|
104
|
-
return style;
|
|
119
|
+
return options.keys === 'kebab' ? toKebabStyle(style) : style;
|
|
105
120
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { InteractionProperty, InteractionStyle } from './index.js';
|
|
1
|
+
import type { InteractionProperty, InteractionStyle, StyleKeyCase } from './index.js';
|
|
2
2
|
/** One element to drive: a stable key plus the properties the Builder stored for it. */
|
|
3
3
|
export interface InteractionEntry {
|
|
4
4
|
key: string;
|
|
@@ -10,6 +10,14 @@ export interface UseInteractionStateOptions {
|
|
|
10
10
|
clearTimer?: (handle: unknown) => void;
|
|
11
11
|
/** Schedules the frame after next. Defaults to double rAF, or a macrotask. */
|
|
12
12
|
nextFrame?: (fn: () => void) => void;
|
|
13
|
+
/**
|
|
14
|
+
* Key style for every style() call. Defaults to camelCase.
|
|
15
|
+
*
|
|
16
|
+
* Set 'kebab' when the host merges these into a style object it builds out of
|
|
17
|
+
* literal CSS property names, so the same property never appears twice under
|
|
18
|
+
* two spellings.
|
|
19
|
+
*/
|
|
20
|
+
keys?: StyleKeyCase;
|
|
13
21
|
}
|
|
14
22
|
export interface InteractionStateApi {
|
|
15
23
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/interaction/vue.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"vue.d.ts","sourceRoot":"","sources":["../../src/interaction/vue.ts"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,mBAAmB,EAAE,gBAAgB,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAEtF,wFAAwF;AACxF,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,CAAC;CAClD;AAED,MAAM,WAAW,0BAA0B;IACzC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC;IACnD,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,8EAA8E;IAC9E,SAAS,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;IACrC;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,YAAY,CAAC;CACrB;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;OAKG;IACH,KAAK,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,OAAO,GAAG,gBAAgB,CAAC;IACzG,oFAAoF;IACpF,IAAI,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC;IAChG;;;;;;OAMG;IACH,IAAI,CAAC,OAAO,EAAE,gBAAgB,EAAE,GAAG,IAAI,CAAC;IACxC,oEAAoE;IACpE,IAAI,IAAI,IAAI,CAAC;IACb,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IAC/B,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,EAAE,OAAO,GAAG,IAAI,CAAC;CAC3C;AAUD,wBAAgB,mBAAmB,CAAC,OAAO,GAAE,0BAA+B,GAAG,mBAAmB,CA8EjG"}
|
package/dist/interaction/vue.js
CHANGED
|
@@ -46,7 +46,7 @@ export function useInteractionState(options = {}) {
|
|
|
46
46
|
const api = {
|
|
47
47
|
style(property, key, forced) {
|
|
48
48
|
const on = forced ?? active[key] ?? false;
|
|
49
|
-
return interactionStyle(property, on, { instant: instant[key] === true });
|
|
49
|
+
return interactionStyle(property, on, { instant: instant[key] === true, keys: options.keys });
|
|
50
50
|
},
|
|
51
51
|
bind(property, key) {
|
|
52
52
|
if (!isInteractionEnabled(property))
|