@realnation/builder-shared-sdk 1.3.0 → 2.1.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,7 +23,8 @@ export declare const INTERACTION_KEYS: {
23
23
  readonly scale: "selected-scale";
24
24
  readonly opacity: "selected-opacity";
25
25
  };
26
- export type InteractionTrigger = 'hover' | 'click' | 'appear' | 'loop';
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>;
@@ -47,14 +48,32 @@ export interface InteractionStyle {
47
48
  export type StyleKeyCase = 'camel' | 'kebab';
48
49
  /** Rewrites the compound property names; transition / transform / opacity are already valid CSS. */
49
50
  export declare function toKebabStyle(style: InteractionStyle): InteractionStyle;
51
+ /** Whether the operator configured any second appearance at all. Untouched keys are absent. */
52
+ export declare function hasSelectedAppearance(property: InteractionProperty | null | undefined): boolean;
53
+ export interface InteractionEnabledOptions {
54
+ /**
55
+ * The caller decides when the element is selected, so the trigger has nothing
56
+ * to decide for it. Inferred from passing an explicit `active` to style().
57
+ */
58
+ selfDriven?: boolean;
59
+ }
50
60
  /**
51
61
  * Whether the element has an interaction state at all.
52
62
  *
53
- * Easing is the section's master switch: `none` (the default) means the
54
- * element behaves exactly as it did before this feature existed. Every entry
55
- * point checks this first so unconfigured elements stay untouched.
63
+ * For elements the platform drives, the trigger is the master switch: it
64
+ * answers the first question, does this element react to anything? Easing only
65
+ * describes what the change looks like once something triggers it.
66
+ *
67
+ * For an element whose owner supplies its own `active` — personality-test's
68
+ * options, where "selected" means the answer the player picked — the trigger
69
+ * has nothing left to decide, and making the operator pick an arbitrary one
70
+ * just to switch the section on would be a riddle. There the switch is simply
71
+ * whether a second appearance was configured.
72
+ *
73
+ * Either way an element nobody configured behaves exactly as it did before
74
+ * this feature existed. Every entry point checks this first.
56
75
  */
57
- export declare function isInteractionEnabled(property: InteractionProperty | null | undefined): boolean;
76
+ export declare function isInteractionEnabled(property: InteractionProperty | null | undefined, options?: InteractionEnabledOptions): boolean;
58
77
  export declare function interactionTriggerOf(property: InteractionProperty | null | undefined): InteractionTrigger;
59
78
  export declare function interactionDurationOf(property: InteractionProperty | null | undefined): number;
60
79
  /**
@@ -73,6 +92,8 @@ export interface InteractionStyleOptions {
73
92
  instant?: boolean;
74
93
  /** Key style of the returned object. Defaults to camelCase. */
75
94
  keys?: StyleKeyCase;
95
+ /** See isInteractionEnabled. Set by style() when the caller supplies `active`. */
96
+ selfDriven?: boolean;
76
97
  }
77
98
  /**
78
99
  * 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;AACvE,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAAyC,CAAC;AAExG,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;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG9F;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,CAoClB"}
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;AAeD,+FAA+F;AAC/F,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,GAAG,OAAO,CAG/F;AAED,MAAM,WAAW,yBAAyB;IACxC;;;OAGG;IACH,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAChD,OAAO,GAAE,yBAA8B,GACtC,OAAO,CAGT;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;IACpB,kFAAkF;IAClF,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB;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,7 @@ 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
27
  const KEBAB = {
28
28
  backgroundColor: 'background-color',
29
29
  borderColor: 'border-color',
@@ -39,21 +39,43 @@ const num = (value, fallback) => {
39
39
  const n = Number(value);
40
40
  return Number.isFinite(n) ? n : fallback;
41
41
  };
42
+ const SELECTED_APPEARANCE_KEYS = [
43
+ INTERACTION_KEYS.bgColor,
44
+ INTERACTION_KEYS.borderColor,
45
+ INTERACTION_KEYS.rotation,
46
+ INTERACTION_KEYS.scale,
47
+ INTERACTION_KEYS.opacity,
48
+ ];
49
+ /** Whether the operator configured any second appearance at all. Untouched keys are absent. */
50
+ export function hasSelectedAppearance(property) {
51
+ if (!property)
52
+ return false;
53
+ return SELECTED_APPEARANCE_KEYS.some((k) => property[k] != null && property[k] !== '');
54
+ }
42
55
  /**
43
56
  * Whether the element has an interaction state at all.
44
57
  *
45
- * Easing is the section's master switch: `none` (the default) means the
46
- * element behaves exactly as it did before this feature existed. Every entry
47
- * point checks this first so unconfigured elements stay untouched.
58
+ * For elements the platform drives, the trigger is the master switch: it
59
+ * answers the first question, does this element react to anything? Easing only
60
+ * describes what the change looks like once something triggers it.
61
+ *
62
+ * For an element whose owner supplies its own `active` — personality-test's
63
+ * options, where "selected" means the answer the player picked — the trigger
64
+ * has nothing left to decide, and making the operator pick an arbitrary one
65
+ * just to switch the section on would be a riddle. There the switch is simply
66
+ * whether a second appearance was configured.
67
+ *
68
+ * Either way an element nobody configured behaves exactly as it did before
69
+ * this feature existed. Every entry point checks this first.
48
70
  */
49
- export function isInteractionEnabled(property) {
50
- if (!property)
51
- return false;
52
- return String(property[INTERACTION_KEYS.easing] ?? 'none') !== 'none';
71
+ export function isInteractionEnabled(property, options = {}) {
72
+ if (options.selfDriven)
73
+ return hasSelectedAppearance(property);
74
+ return interactionTriggerOf(property) !== 'none';
53
75
  }
54
76
  export function interactionTriggerOf(property) {
55
- const raw = String(property?.[INTERACTION_KEYS.trigger] ?? 'hover');
56
- return INTERACTION_TRIGGERS.includes(raw) ? raw : 'hover';
77
+ const raw = String(property?.[INTERACTION_KEYS.trigger] ?? 'none');
78
+ return INTERACTION_TRIGGERS.includes(raw) ? raw : 'none';
57
79
  }
58
80
  export function interactionDurationOf(property) {
59
81
  return num(property?.[INTERACTION_KEYS.duration], 400);
@@ -78,10 +100,12 @@ export function interactionPeriodOf(property) {
78
100
  * an unset colour must inherit the normal appearance rather than reset it.
79
101
  */
80
102
  export function interactionStyle(property, active, options = {}) {
81
- if (!isInteractionEnabled(property))
103
+ if (!isInteractionEnabled(property, { selfDriven: options.selfDriven }))
82
104
  return {};
83
105
  const bag = property;
84
- const easing = String(bag[INTERACTION_KEYS.easing]);
106
+ // An instant change is still expressible: set the duration to zero. Easing
107
+ // only decides how the time is spent, so it never needs an "off" of its own.
108
+ const easing = String(bag[INTERACTION_KEYS.easing] ?? 'ease-out');
85
109
  const duration = interactionDurationOf(bag);
86
110
  const style = {};
87
111
  if (options.instant) {
@@ -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,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"}
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,CAoFjG"}
@@ -46,7 +46,13 @@ 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, keys: options.keys });
49
+ // Passing `active` at all is the declaration: this caller owns the timing,
50
+ // so the configured trigger is not what decides whether the state exists.
51
+ return interactionStyle(property, on, {
52
+ instant: instant[key] === true,
53
+ keys: options.keys,
54
+ selfDriven: forced !== undefined,
55
+ });
50
56
  },
51
57
  bind(property, key) {
52
58
  if (!isInteractionEnabled(property))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realnation/builder-shared-sdk",
3
- "version": "1.3.0",
3
+ "version": "2.1.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "exports": {