playhtml 0.1.8 → 1.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.
package/README.md CHANGED
@@ -46,8 +46,67 @@ If you have dynamic elements that are hydrated after the initial load, you can c
46
46
 
47
47
  A full list can be found in `types.ts` under `TagType`.
48
48
 
49
+ ## Custom Capabilities
50
+
51
+ ### `can-play`
52
+
53
+ `can-play` is the fully customizable experience of `playhtml`. You can create anything using simple HTML, CSS, and Javascript by simply adding on the functionality needed to the element itself. The library will handle magically syncing and persisting any data that you store.
54
+
55
+ Here's the simple example included on the playhtml website:
56
+
57
+ https://github.com/spencerc99/playhtml/assets/14796580/fae669b1-b3e2-404e-bd7a-3d36b81c572d
58
+
59
+ ```html
60
+ <img can-play id="customCandle" src="/candle-gif.gif" />
61
+ <!-- IMPORTANT: this data must be set _before_ importing the playhtml library. -->
62
+ <script>
63
+ // Every HTML element with an ID has a variable corresponding to that ID name in the global context (see https://stackoverflow.com/questions/3434278/do-dom-tree-elements-with-ids-become-global-properties/3434388#3434388)
64
+ // This is fun, magical, and readable for small projects, but if you have a larger, complex project, I would advise using `document.getElementById` or `document.querySelector`...
65
+ customCandle.defaultData = true;
66
+ customCandle.onClick = (_e, { data, setData }) => {
67
+ setData(!data);
68
+ };
69
+ // The above statement could also be done using the `additionalSetup`
70
+ // which can initialize several different event listeners and custom logic.
71
+ // customCandle.additionalSetup = ({ getData, setData }) => {
72
+ // customCandle.addEventListener("click", (_e) => {
73
+ // const data = getData();
74
+ // setData(!data);
75
+ // });
76
+ // };
77
+ customCandle.updateElement = ({ data }) => {
78
+ customCandle.src = data ? "/candle-gif.gif" : "/candle-off.png";
79
+ };
80
+
81
+ // Alternatively
82
+ // let candle = document.getElementById('customCandle');
83
+ // candle.defaultData = true;
84
+ // candle.onClick = (_e, { data, setData }) => {
85
+ // setData(!data);
86
+ // };
87
+ // candle.updateElement = ({ data }) => {
88
+ // candle.src = data ? "/candle-gif.gif" : "/candle-off.png";
89
+ // };
90
+ // candle.resetShortcut = "shiftKey";
91
+ </script>
92
+
93
+ <!-- Import playhtml -->
94
+ <script type="module" src="https://unpkg.com/playhtml"></script>
95
+ <link rel="stylesheet" href="https://unpkg.com/playhtml/dist/style.css" />
96
+ ```
97
+
98
+ The only required properties are `defaultData`, `updateElement` and some kind of setup to trigger those functions (in this case, `onClick`, but you can add custom event listeners and logic using the `additionalSetup` property). See more examples based on the definitions for the included capabilities in `elements.ts`.
99
+
100
+ ## Plug-and-play Capabilities
101
+
102
+ These capabilities are common ones that have been designed and created by the community. You should expect that they are relatively well-tested, and they simply build on top of the same API and constructs that `can-play` uses.
103
+
104
+ We welcome any contributions if you have custom `can-play` elements that you would like to add to the library! Please make a PR.
105
+
49
106
  ### `can-move`
50
107
 
108
+ https://github.com/spencerc99/playhtml/assets/14796580/9c2b9bf6-142c-41e2-8c8f-93a3b121a73e
109
+
51
110
  Creates a movable object using 2D `translate` on the element. Dragging the element around will move it
52
111
 
53
112
  **troubleshooting**
@@ -61,6 +120,8 @@ Creates a rotatable object using a `rotate` `transform` on the element. Dragging
61
120
 
62
121
  ### `can-toggle`
63
122
 
123
+ <blockquote class="twitter-tweet"><p lang="en" dir="ltr">today i installed some lamps on the demos-and-chill website<br><br>then <a href="https://twitter.com/_jzhao?ref_src=twsrc%5Etfw">@_jzhao</a> and i fought on whether to keep them on or not. <a href="https://t.co/sCspTwmRpS">pic.twitter.com/sCspTwmRpS</a></p>&mdash; spencer chang ☀️ (spencerchang.me @ bsky) (@spencerc99) <a href="https://twitter.com/spencerc99/status/1681048824884895744?ref_src=twsrc%5Etfw">July 17, 2023</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
124
+
64
125
  Creates an object that can be switched on and off. Clicking the element will toggle the `clicked` class on the element.
65
126
 
66
127
  ### `can-grow`
@@ -69,6 +130,8 @@ Creates an object that can be resized using a `scale` `transform`. Clicking the
69
130
 
70
131
  ### `can-post`
71
132
 
133
+ ![image](https://github.com/spencerc99/playhtml/assets/14796580/6de3fcab-2372-4080-b46f-cd768f1ed44e)
134
+
72
135
  Creates a communal forum from a `form` element. The form will sync any new submissions including all the `input` elements in the form, using their `name` property as the key and their value as the value. New messages will be currently prepended to the element with the `guestbookMessages` ID. TODO: make this generic and take user input
73
136
 
74
137
  ---
Binary file
Binary file
@@ -1,17 +1,14 @@
1
1
  /// <reference lib="dom" />
2
2
  import { TagType } from "./types";
3
3
  type ModifierKey = "ctrlKey" | "altKey" | "shiftKey" | "metaKey";
4
- interface ElementInitializer<T = any, U = any> {
5
- defaultData: T;
6
- defaultLocalData?: U;
4
+ export interface ElementInitializer<T = any, U = any> {
5
+ defaultData: T | ((element: HTMLElement) => T);
6
+ defaultLocalData?: U | ((element: HTMLElement) => U);
7
7
  updateElement: (data: ElementEventHandlerData<T, U>) => void;
8
- onClick?: (e: MouseEvent, eventData: ElementEventHandlerData<T, U>) => void;
9
8
  onDrag?: (e: MouseEvent, eventData: ElementEventHandlerData<T, U>) => void;
9
+ onClick?: (e: MouseEvent, eventData: ElementEventHandlerData<T, U>) => void;
10
10
  onDragStart?: (e: MouseEvent, eventData: ElementEventHandlerData<T, U>) => void;
11
- onMouseEnter?: (e: MouseEvent, eventData: ElementEventHandlerData<T, U>) => void;
12
- onKeyDown?: (e: KeyboardEvent, eventData: ElementEventHandlerData<T, U>) => void;
13
- onKeyUp?: (e: KeyboardEvent, eventData: ElementEventHandlerData<T, U>) => void;
14
- onSubmit?: (e: SubmitEvent, eventData: ElementEventHandlerData<T, U>) => void;
11
+ additionalSetup?: (eventData: ElementSetupData<T, U>) => void;
15
12
  resetShortcut?: ModifierKey;
16
13
  debounceMs?: number;
17
14
  }
@@ -28,7 +25,14 @@ interface ElementEventHandlerData<T = any, U = any> {
28
25
  setData: (data: T) => void;
29
26
  setLocalData: (data: U) => void;
30
27
  }
31
- export declare const TagTypeToElement: Record<TagType, ElementInitializer>;
28
+ interface ElementSetupData<T = any, U = any> {
29
+ getData: () => T;
30
+ getLocalData: () => U;
31
+ getElement: () => HTMLElement;
32
+ setData: (data: T) => void;
33
+ setLocalData: (data: U) => void;
34
+ }
35
+ export declare const TagTypeToElement: Record<Exclude<TagType, "can-play">, ElementInitializer>;
32
36
  export declare class ElementHandler<T = any, U = any> {
33
37
  defaultData: T;
34
38
  localData: U;
@@ -38,7 +42,7 @@ export declare class ElementHandler<T = any, U = any> {
38
42
  debouncedOnChange: (data: T) => void;
39
43
  resetShortcut?: ModifierKey;
40
44
  updateElement: (data: ElementEventHandlerData<T, U>) => void;
41
- constructor({ element, onChange, defaultData, defaultLocalData, data, updateElement, onClick, onDrag, onDragStart, onMouseEnter, onKeyDown, onKeyUp, onSubmit, resetShortcut, debounceMs, }: ElementData<T>);
45
+ constructor({ element, onChange, defaultData, defaultLocalData, data, updateElement, onClick, onDrag, onDragStart, additionalSetup, resetShortcut, debounceMs, }: ElementData<T>);
42
46
  get data(): T;
43
47
  setLocalData(localData: U): void;
44
48
  /**
@@ -50,6 +54,7 @@ export declare class ElementHandler<T = any, U = any> {
50
54
  */
51
55
  set __data(data: T);
52
56
  getEventHandlerData(): ElementEventHandlerData<T, U>;
57
+ getSetupData(): ElementSetupData<T, U>;
53
58
  /**
54
59
  * Public-use setter for data that makes the change to all clients.
55
60
  */
package/dist/main.d.ts CHANGED
@@ -1,7 +1,9 @@
1
1
  /// <reference lib="dom" />
2
2
  import * as Y from "yjs";
3
+ import { ElementHandler } from "./elements";
3
4
  export declare const globalData: Y.Map<Y.Map<any>>;
4
5
  export declare function getElementFromId(id: string): HTMLElement | null;
6
+ export declare const elementHandlers: Map<string, Map<string, ElementHandler<any, any>>>;
5
7
  /**
6
8
  * Sets up any playhtml elements that are currently on the page.
7
9
  * Can be repeatedly called to set up new elements without affecting existing ones.