@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
- 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>;
30
- /** The CSS properties this feature is allowed to touch, in camelCase for Vue's :style. */
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
- * Easing is the section's master switch: `none` (the default) means the
42
- * element behaves exactly as it did before this feature existed. Every entry
43
- * point checks this first so unconfigured elements stay untouched.
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;AACvE,eAAO,MAAM,oBAAoB,EAAE,SAAS,kBAAkB,EAAyC,CAAC;AAExG,uFAAuF;AACvF,MAAM,MAAM,mBAAmB,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAE1D,0FAA0F;AAC1F,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;CAClB;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;CACnB;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,mBAAmB,GAAG,IAAI,GAAG,SAAS,EAChD,MAAM,EAAE,OAAO,EACf,OAAO,GAAE,uBAA4B,GACpC,gBAAgB,CAkClB"}
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
- * Easing is the section's master switch: `none` (the default) means the
35
- * element behaves exactly as it did before this feature existed. Every entry
36
- * point checks this first so unconfigured elements stay untouched.
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
- if (!property)
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] ?? 'hover');
45
- return INTERACTION_TRIGGERS.includes(raw) ? raw : 'hover';
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
- const easing = String(bag[INTERACTION_KEYS.easing]);
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;AAExE,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;CACtC;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,CA8EjG"}
@@ -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))
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@realnation/builder-shared-sdk",
3
- "version": "1.2.1",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
5
  "private": false,
6
6
  "exports": {