@studiometa/ui 1.0.0-rc.1 → 1.0.0-rc.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.
@@ -1,33 +1,63 @@
1
1
  import { Base } from '@studiometa/js-toolkit';
2
2
  import type { BaseProps, BaseConfig, DragServiceProps } from '@studiometa/js-toolkit';
3
+ export interface DraggableProps extends BaseProps {
4
+ $refs: {
5
+ target: HTMLElement;
6
+ };
7
+ $options: {
8
+ x: boolean;
9
+ y: boolean;
10
+ fitBounds: boolean;
11
+ sensitivity: number;
12
+ dropSensitivity: number;
13
+ };
14
+ }
3
15
  declare const Draggable_base: import("@studiometa/js-toolkit").BaseDecorator<import("@studiometa/js-toolkit").BaseInterface, Base<BaseProps>>;
4
16
  /**
5
17
  * Draggable class.
6
18
  */
7
- export declare class Draggable<T extends BaseProps = BaseProps> extends Draggable_base<T> {
19
+ export declare class Draggable<T extends BaseProps = BaseProps> extends Draggable_base<T & DraggableProps> {
8
20
  /**
9
21
  * Config.
10
22
  */
11
23
  static config: BaseConfig;
12
24
  /**
13
- * Horizontal transformation.
25
+ * Props for the target position.
26
+ */
27
+ props: {
28
+ x: number;
29
+ y: number;
30
+ originX: number;
31
+ originY: number;
32
+ dampedX: number;
33
+ dampedY: number;
34
+ };
35
+ /**
36
+ * Smooth factor.
14
37
  */
15
- x: number;
38
+ dampFactor: number;
16
39
  /**
17
- * Vertical transformation.
40
+ * The draggable element, defaults to `this.$refs.target`.
18
41
  */
19
- y: number;
42
+ get target(): HTMLElement;
20
43
  /**
21
- * Horizontal position origin.
44
+ * The bouding element, defaults to `this.$el`.
22
45
  */
23
- originX: number;
46
+ get parent(): HTMLElement;
24
47
  /**
25
- * Vertical position origin.
48
+ * The bounds values.
26
49
  */
27
- originY: number;
50
+ get bounds(): {
51
+ yMin: number;
52
+ yMax: number;
53
+ xMin: number;
54
+ xMax: number;
55
+ };
28
56
  /**
29
57
  * Drag service hook.
30
58
  */
31
59
  dragged(props: DragServiceProps): void;
60
+ ticked(): void;
61
+ render(): void;
32
62
  }
33
63
  export {};
@@ -1,43 +1,122 @@
1
1
  import { Base, withDrag } from "@studiometa/js-toolkit";
2
- import { domScheduler, transform } from "@studiometa/js-toolkit/utils";
3
- class Draggable extends withDrag(Base) {
2
+ import { domScheduler, transform, damp, clamp, getOffsetSizes } from "@studiometa/js-toolkit/utils";
3
+ class Draggable extends withDrag(Base, {
4
+ // @ts-expect-error draggable is instance of Draggable.
5
+ target: (draggable) => draggable.target
6
+ }) {
4
7
  /**
5
8
  * Config.
6
9
  */
7
10
  static config = {
8
- name: "DraggableElement"
11
+ name: "DraggableElement",
12
+ refs: ["target"],
13
+ emits: ["drag-start", "drag-drag", "drag-drop", "drag-inertia", "drag-stop", "drag-fit"],
14
+ options: {
15
+ x: {
16
+ type: Boolean,
17
+ default: true
18
+ },
19
+ y: {
20
+ type: Boolean,
21
+ default: true
22
+ },
23
+ fitBounds: Boolean,
24
+ sensitivity: { type: Number, default: 0.5 },
25
+ dropSensitivity: { type: Number, default: 0.1 }
26
+ }
9
27
  };
10
28
  /**
11
- * Horizontal transformation.
29
+ * Props for the target position.
12
30
  */
13
- x = 0;
31
+ props = {
32
+ x: 0,
33
+ y: 0,
34
+ originX: 0,
35
+ originY: 0,
36
+ dampedX: 0,
37
+ dampedY: 0
38
+ };
14
39
  /**
15
- * Vertical transformation.
40
+ * Smooth factor.
16
41
  */
17
- y = 0;
42
+ dampFactor = 0.5;
43
+ /**
44
+ * The draggable element, defaults to `this.$refs.target`.
45
+ */
46
+ get target() {
47
+ return this.$refs.target;
48
+ }
18
49
  /**
19
- * Horizontal position origin.
50
+ * The bouding element, defaults to `this.$el`.
20
51
  */
21
- originX = 0;
52
+ get parent() {
53
+ return this.$el;
54
+ }
22
55
  /**
23
- * Vertical position origin.
56
+ * The bounds values.
24
57
  */
25
- originY = 0;
58
+ get bounds() {
59
+ const targetSizes = getOffsetSizes(this.target);
60
+ const parentSizes = getOffsetSizes(this.parent);
61
+ const xMin = targetSizes.x - parentSizes.x;
62
+ const yMin = targetSizes.y - parentSizes.y;
63
+ const xMax = xMin + targetSizes.width - parentSizes.width;
64
+ const yMax = yMin + targetSizes.height - parentSizes.height;
65
+ return {
66
+ yMin: yMin * -1,
67
+ yMax: yMax * -1,
68
+ xMin: xMin * -1,
69
+ xMax: xMax * -1
70
+ };
71
+ }
26
72
  /**
27
73
  * Drag service hook.
28
74
  */
29
75
  dragged(props) {
30
- if (props.mode === "start") {
31
- this.originX = this.x;
32
- this.originY = this.y;
33
- return;
76
+ this.$emit(`drag-${props.mode}`, this.props);
77
+ if (props.mode === props.MODES.START) {
78
+ this.props.originX = this.props.x;
79
+ this.props.originY = this.props.y;
80
+ this.dampFactor = this.$options.sensitivity;
81
+ this.render();
82
+ } else if (props.mode === props.MODES.DRAG || props.mode === props.MODES.INERTIA && !this.$options.fitBounds) {
83
+ this.props.x = this.props.originX + props.x - props.origin.x;
84
+ this.props.y = this.props.originY + props.y - props.origin.y;
85
+ this.render();
86
+ } else if (props.mode === props.MODES.DROP && this.$options.fitBounds) {
87
+ const { bounds } = this;
88
+ this.props.x = clamp(
89
+ this.props.originX + props.final.x - props.origin.x,
90
+ bounds.xMin,
91
+ bounds.xMax
92
+ );
93
+ this.props.y = clamp(
94
+ this.props.originY + props.final.y - props.origin.y,
95
+ bounds.yMin,
96
+ bounds.yMax
97
+ );
98
+ this.dampFactor = this.$options.dropSensitivity;
99
+ this.$services.enable("ticked");
34
100
  }
35
- this.x = this.originX + props.x - props.origin.x;
36
- this.y = this.originY + props.y - props.origin.y;
37
- domScheduler.write(() => {
38
- transform(this.$el, {
39
- x: this.x,
40
- y: this.y
101
+ }
102
+ ticked() {
103
+ this.$emit(`drag-inertia`, this.props);
104
+ this.render();
105
+ if (this.props.dampedX === this.props.x && this.props.dampedY === this.props.y) {
106
+ this.$services.disable("ticked");
107
+ this.$emit("drag-fit", this.props);
108
+ }
109
+ }
110
+ render() {
111
+ this.props.dampedX = damp(this.props.x, this.props.dampedX, this.dampFactor);
112
+ this.props.dampedY = damp(this.props.y, this.props.dampedY, this.dampFactor);
113
+ domScheduler.read(() => {
114
+ const { x, y } = this.$options;
115
+ domScheduler.write(() => {
116
+ transform(this.target, {
117
+ x: x ? this.props.dampedX : 0,
118
+ y: y ? this.props.dampedY : 0
119
+ });
41
120
  });
42
121
  });
43
122
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Draggable/Draggable.ts"],
4
- "sourcesContent": ["import { Base, withDrag } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig, DragServiceProps } from '@studiometa/js-toolkit';\nimport { domScheduler, transform } from '@studiometa/js-toolkit/utils';\n\n/**\n * Draggable class.\n */\nexport class Draggable<T extends BaseProps = BaseProps> extends withDrag(Base)<T> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'DraggableElement',\n };\n\n /**\n * Horizontal transformation.\n */\n x = 0;\n\n /**\n * Vertical transformation.\n */\n y = 0;\n\n /**\n * Horizontal position origin.\n */\n originX = 0;\n\n /**\n * Vertical position origin.\n */\n originY = 0;\n\n /**\n * Drag service hook.\n */\n dragged(props: DragServiceProps) {\n if (props.mode === 'start') {\n this.originX = this.x;\n this.originY = this.y;\n return;\n }\n\n this.x = this.originX + props.x - props.origin.x;\n this.y = this.originY + props.y - props.origin.y;\n\n domScheduler.write(() => {\n transform(this.$el, {\n x: this.x,\n y: this.y,\n });\n });\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,MAAM,gBAAgB;AAE/B,SAAS,cAAc,iBAAiB;AAKjC,MAAM,kBAAmD,SAAS,IAAI,EAAK;AAAA;AAAA;AAAA;AAAA,EAIhF,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,EACR;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI;AAAA;AAAA;AAAA;AAAA,EAKJ,IAAI;AAAA;AAAA;AAAA;AAAA,EAKJ,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV,QAAQ,OAAyB;AAC/B,QAAI,MAAM,SAAS,SAAS;AAC1B,WAAK,UAAU,KAAK;AACpB,WAAK,UAAU,KAAK;AACpB;AAAA,IACF;AAEA,SAAK,IAAI,KAAK,UAAU,MAAM,IAAI,MAAM,OAAO;AAC/C,SAAK,IAAI,KAAK,UAAU,MAAM,IAAI,MAAM,OAAO;AAE/C,iBAAa,MAAM,MAAM;AACvB,gBAAU,KAAK,KAAK;AAAA,QAClB,GAAG,KAAK;AAAA,QACR,GAAG,KAAK;AAAA,MACV,CAAC;AAAA,IACH,CAAC;AAAA,EACH;AACF;",
4
+ "sourcesContent": ["import { Base, withDrag } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig, DragServiceProps } from '@studiometa/js-toolkit';\nimport { domScheduler, transform, damp, clamp, getOffsetSizes } from '@studiometa/js-toolkit/utils';\n\nexport interface DraggableProps extends BaseProps {\n $refs: {\n target: HTMLElement;\n };\n $options: {\n x: boolean;\n y: boolean;\n fitBounds: boolean;\n sensitivity: number;\n dropSensitivity: number;\n };\n}\n\n/**\n * Draggable class.\n */\nexport class Draggable<T extends BaseProps = BaseProps> extends withDrag(Base, {\n // @ts-expect-error draggable is instance of Draggable.\n target: (draggable) => draggable.target,\n})<T & DraggableProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'DraggableElement',\n refs: ['target'],\n emits: ['drag-start', 'drag-drag', 'drag-drop', 'drag-inertia', 'drag-stop', 'drag-fit'],\n options: {\n x: {\n type: Boolean,\n default: true,\n },\n y: {\n type: Boolean,\n default: true,\n },\n fitBounds: Boolean,\n sensitivity: { type: Number, default: 0.5 },\n dropSensitivity: { type: Number, default: 0.1 },\n },\n };\n\n /**\n * Props for the target position.\n */\n props = {\n x: 0,\n y: 0,\n originX: 0,\n originY: 0,\n dampedX: 0,\n dampedY: 0,\n };\n\n /**\n * Smooth factor.\n */\n dampFactor = 0.5;\n\n /**\n * The draggable element, defaults to `this.$refs.target`.\n */\n get target(): HTMLElement {\n return this.$refs.target;\n }\n\n /**\n * The bouding element, defaults to `this.$el`.\n */\n get parent(): HTMLElement {\n return this.$el;\n }\n\n /**\n * The bounds values.\n */\n get bounds() {\n const targetSizes = getOffsetSizes(this.target);\n const parentSizes = getOffsetSizes(this.parent);\n const xMin = targetSizes.x - parentSizes.x;\n const yMin = targetSizes.y - parentSizes.y;\n const xMax = xMin + targetSizes.width - parentSizes.width;\n const yMax = yMin + targetSizes.height - parentSizes.height;\n\n return {\n yMin: yMin * -1,\n yMax: yMax * -1,\n xMin: xMin * -1,\n xMax: xMax * -1,\n };\n }\n\n /**\n * Drag service hook.\n */\n dragged(props: DragServiceProps) {\n this.$emit(`drag-${props.mode}`, this.props);\n\n if (props.mode === props.MODES.START) {\n this.props.originX = this.props.x;\n this.props.originY = this.props.y;\n this.dampFactor = this.$options.sensitivity;\n this.render();\n } else if (\n props.mode === props.MODES.DRAG ||\n (props.mode === props.MODES.INERTIA && !this.$options.fitBounds)\n ) {\n this.props.x = this.props.originX + props.x - props.origin.x;\n this.props.y = this.props.originY + props.y - props.origin.y;\n this.render();\n } else if (props.mode === props.MODES.DROP && this.$options.fitBounds) {\n const { bounds } = this;\n this.props.x = clamp(\n this.props.originX + props.final.x - props.origin.x,\n bounds.xMin,\n bounds.xMax,\n );\n this.props.y = clamp(\n this.props.originY + props.final.y - props.origin.y,\n bounds.yMin,\n bounds.yMax,\n );\n this.dampFactor = this.$options.dropSensitivity;\n this.$services.enable('ticked');\n }\n }\n\n ticked() {\n this.$emit(`drag-inertia`, this.props);\n this.render();\n if (this.props.dampedX === this.props.x && this.props.dampedY === this.props.y) {\n this.$services.disable('ticked');\n this.$emit('drag-fit', this.props);\n }\n }\n\n render() {\n this.props.dampedX = damp(this.props.x, this.props.dampedX, this.dampFactor);\n this.props.dampedY = damp(this.props.y, this.props.dampedY, this.dampFactor);\n\n domScheduler.read(() => {\n const { x, y } = this.$options;\n domScheduler.write(() => {\n transform(this.target, {\n x: x ? this.props.dampedX : 0,\n y: y ? this.props.dampedY : 0,\n });\n });\n });\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -41,9 +41,11 @@ class AbstractFrameTrigger extends Base {
41
41
  * Trigger FrameLoaders enter.
42
42
  */
43
43
  onFrameFetchBefore() {
44
- for (const loader of this.$children.FrameTriggerLoader) {
45
- if (getClosestParent(loader, this.constructor) === this) {
46
- loader.enter();
44
+ if (this.$children.FrameTriggerLoader) {
45
+ for (const loader of this.$children.FrameTriggerLoader) {
46
+ if (getClosestParent(loader, this.constructor) === this) {
47
+ loader.enter();
48
+ }
47
49
  }
48
50
  }
49
51
  }
@@ -51,9 +53,11 @@ class AbstractFrameTrigger extends Base {
51
53
  * Trigger FrameLoaders leave.
52
54
  */
53
55
  onFrameFetchAfter() {
54
- for (const loader of this.$children.FrameTriggerLoader) {
55
- if (getClosestParent(loader, this.constructor) === this) {
56
- loader.leave();
56
+ if (this.$children.FrameTriggerLoader) {
57
+ for (const loader of this.$children.FrameTriggerLoader) {
58
+ if (getClosestParent(loader, this.constructor) === this) {
59
+ loader.leave();
60
+ }
57
61
  }
58
62
  }
59
63
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Frame/AbstractFrameTrigger.ts"],
4
- "sourcesContent": ["import { Base, getClosestParent } from '@studiometa/js-toolkit';\nimport type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport type { FrameRequestInit } from './types.js';\nimport { EVENTS } from './utils.js';\nimport { FrameTriggerLoader } from './FrameTriggerLoader.js';\n\nexport interface AbstractFrameTriggerProps extends BaseProps {\n $el: HTMLFormElement | HTMLAnchorElement;\n $options: {\n requestInit: RequestInit;\n headers: Record<string, string>;\n };\n $children: {\n FrameTriggerLoader: FrameTriggerLoader[];\n };\n}\n\n/**\n * AbstractFrameTrigger class.\n */\nexport class AbstractFrameTrigger<T extends BaseProps = BaseProps> extends Base<\n T & AbstractFrameTriggerProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'AbstractFrameTrigger',\n emits: Object.values(EVENTS),\n options: {\n requestInit: Object,\n headers: Object,\n },\n components: {\n FrameTriggerLoader,\n },\n };\n\n /**\n * The URL to use for the request.\n */\n get url(): URL {\n return new URL(this.$el instanceof HTMLFormElement ? this.$el.action : this.$el.href);\n }\n\n /**\n * Option for the fetch request.\n */\n get requestInit(): FrameRequestInit {\n const { requestInit, headers } = this.$options;\n\n return {\n ...requestInit,\n // @ts-expect-error this will be right.\n trigger: this,\n headers: {\n ...requestInit.headers,\n ...headers,\n },\n };\n }\n\n /**\n * Trigger FrameLoaders enter.\n */\n onFrameFetchBefore() {\n for (const loader of this.$children.FrameTriggerLoader) {\n if (getClosestParent(loader, this.constructor) === this) {\n loader.enter();\n }\n }\n }\n\n /**\n * Trigger FrameLoaders leave.\n */\n onFrameFetchAfter() {\n for (const loader of this.$children.FrameTriggerLoader) {\n if (getClosestParent(loader, this.constructor) === this) {\n loader.leave();\n }\n }\n }\n\n /**\n * Trigger request.\n */\n async trigger() {\n const { url, requestInit } = this;\n this.$log('trigger', url, requestInit);\n this.$emit(EVENTS.TRIGGER, url, requestInit);\n }\n}\n"],
5
- "mappings": "AAAA,SAAS,MAAM,wBAAwB;AAGvC,SAAS,cAAc;AACvB,SAAS,0BAA0B;AAgB5B,MAAM,6BAA8D,KAEzE;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO,OAAO,OAAO,MAAM;AAAA,IAC3B,SAAS;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAW;AACb,WAAO,IAAI,IAAI,KAAK,eAAe,kBAAkB,KAAK,IAAI,SAAS,KAAK,IAAI,IAAI;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAgC;AAClC,UAAM,EAAE,aAAa,QAAQ,IAAI,KAAK;AAEtC,WAAO;AAAA,MACL,GAAG;AAAA;AAAA,MAEH,SAAS;AAAA,MACT,SAAS;AAAA,QACP,GAAG,YAAY;AAAA,QACf,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB;AACnB,eAAW,UAAU,KAAK,UAAU,oBAAoB;AACtD,UAAI,iBAAiB,QAAQ,KAAK,WAAW,MAAM,MAAM;AACvD,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB;AAClB,eAAW,UAAU,KAAK,UAAU,oBAAoB;AACtD,UAAI,iBAAiB,QAAQ,KAAK,WAAW,MAAM,MAAM;AACvD,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACd,UAAM,EAAE,KAAK,YAAY,IAAI;AAC7B,SAAK,KAAK,WAAW,KAAK,WAAW;AACrC,SAAK,MAAM,OAAO,SAAS,KAAK,WAAW;AAAA,EAC7C;AACF;",
4
+ "sourcesContent": ["import { Base, getClosestParent } from '@studiometa/js-toolkit';\nimport type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport type { FrameRequestInit } from './types.js';\nimport { EVENTS } from './utils.js';\nimport { FrameTriggerLoader } from './FrameTriggerLoader.js';\n\nexport interface AbstractFrameTriggerProps extends BaseProps {\n $el: HTMLFormElement | HTMLAnchorElement;\n $options: {\n requestInit: RequestInit;\n headers: Record<string, string>;\n };\n $children: {\n FrameTriggerLoader: FrameTriggerLoader[];\n };\n}\n\n/**\n * AbstractFrameTrigger class.\n */\nexport class AbstractFrameTrigger<T extends BaseProps = BaseProps> extends Base<\n T & AbstractFrameTriggerProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'AbstractFrameTrigger',\n emits: Object.values(EVENTS),\n options: {\n requestInit: Object,\n headers: Object,\n },\n components: {\n FrameTriggerLoader,\n },\n };\n\n /**\n * The URL to use for the request.\n */\n get url(): URL {\n return new URL(this.$el instanceof HTMLFormElement ? this.$el.action : this.$el.href);\n }\n\n /**\n * Option for the fetch request.\n */\n get requestInit(): FrameRequestInit {\n const { requestInit, headers } = this.$options;\n\n return {\n ...requestInit,\n // @ts-expect-error this will be right.\n trigger: this,\n headers: {\n ...requestInit.headers,\n ...headers,\n },\n };\n }\n\n /**\n * Trigger FrameLoaders enter.\n */\n onFrameFetchBefore() {\n if (this.$children.FrameTriggerLoader) {\n for (const loader of this.$children.FrameTriggerLoader) {\n if (getClosestParent(loader, this.constructor) === this) {\n loader.enter();\n }\n }\n }\n }\n\n /**\n * Trigger FrameLoaders leave.\n */\n onFrameFetchAfter() {\n if (this.$children.FrameTriggerLoader) {\n for (const loader of this.$children.FrameTriggerLoader) {\n if (getClosestParent(loader, this.constructor) === this) {\n loader.leave();\n }\n }\n }\n }\n\n /**\n * Trigger request.\n */\n async trigger() {\n const { url, requestInit } = this;\n this.$log('trigger', url, requestInit);\n this.$emit(EVENTS.TRIGGER, url, requestInit);\n }\n}\n"],
5
+ "mappings": "AAAA,SAAS,MAAM,wBAAwB;AAGvC,SAAS,cAAc;AACvB,SAAS,0BAA0B;AAgB5B,MAAM,6BAA8D,KAEzE;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO,OAAO,OAAO,MAAM;AAAA,IAC3B,SAAS;AAAA,MACP,aAAa;AAAA,MACb,SAAS;AAAA,IACX;AAAA,IACA,YAAY;AAAA,MACV;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAW;AACb,WAAO,IAAI,IAAI,KAAK,eAAe,kBAAkB,KAAK,IAAI,SAAS,KAAK,IAAI,IAAI;AAAA,EACtF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAAgC;AAClC,UAAM,EAAE,aAAa,QAAQ,IAAI,KAAK;AAEtC,WAAO;AAAA,MACL,GAAG;AAAA;AAAA,MAEH,SAAS;AAAA,MACT,SAAS;AAAA,QACP,GAAG,YAAY;AAAA,QACf,GAAG;AAAA,MACL;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,qBAAqB;AACnB,QAAI,KAAK,UAAU,oBAAoB;AACrC,iBAAW,UAAU,KAAK,UAAU,oBAAoB;AACtD,YAAI,iBAAiB,QAAQ,KAAK,WAAW,MAAM,MAAM;AACvD,iBAAO,MAAM;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,oBAAoB;AAClB,QAAI,KAAK,UAAU,oBAAoB;AACrC,iBAAW,UAAU,KAAK,UAAU,oBAAoB;AACtD,YAAI,iBAAiB,QAAQ,KAAK,WAAW,MAAM,MAAM;AACvD,iBAAO,MAAM;AAAA,QACf;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACd,UAAM,EAAE,KAAK,YAAY,IAAI;AAC7B,SAAK,KAAK,WAAW,KAAK,WAAW;AACrC,SAAK,MAAM,OAAO,SAAS,KAAK,WAAW;AAAA,EAC7C;AACF;",
6
6
  "names": []
7
7
  }
@@ -29,9 +29,11 @@ class FrameForm extends AbstractFrameTrigger {
29
29
  get requestInit() {
30
30
  const requestInit = { ...super.requestInit };
31
31
  requestInit.headers ??= {};
32
- for (const header of this.$refs.headers) {
33
- if (header.dataset.name && header.value) {
34
- requestInit.headers[header.dataset.name] = header.value;
32
+ if (this.$refs.headers) {
33
+ for (const header of this.$refs.headers) {
34
+ if (header.dataset.name && header.value) {
35
+ requestInit.headers[header.dataset.name] = header.value;
36
+ }
35
37
  }
36
38
  }
37
39
  if (this.method === "post") {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../packages/ui/Frame/FrameForm.ts"],
4
- "sourcesContent": ["import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { AbstractFrameTrigger } from './AbstractFrameTrigger.js';\n\nexport interface FrameFormProps extends BaseProps {\n $el: HTMLFormElement;\n $refs: {\n headers: HTMLInputElement[];\n };\n}\n\n/**\n * FrameForm class.\n */\nexport class FrameForm<T extends BaseProps = BaseProps> extends AbstractFrameTrigger<\n T & FrameFormProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameForm',\n refs: ['headers[]'],\n };\n\n /**\n * Form submission method.\n */\n get method() {\n return this.$el.method.toLowerCase() as 'post' | 'get';\n }\n\n /**\n * Add params to the requested URL for GET submissions.\n */\n get url(): URL {\n const url = new URL(this.$el.action);\n\n if (this.method === 'get') {\n // @ts-expect-error URLSearchParams accepts FormData as parameter in the browser.\n url.search = new URLSearchParams(new FormData(this.$el)).toString();\n }\n\n return url;\n }\n\n /**\n * Add body to the request for POST submissions.\n */\n get requestInit(): RequestInit {\n const requestInit = { ...super.requestInit };\n requestInit.headers ??= {};\n\n for (const header of this.$refs.headers) {\n if (header.dataset.name && header.value) {\n requestInit.headers[header.dataset.name] = header.value;\n }\n }\n\n if (this.method === 'post') {\n requestInit.method = this.method;\n requestInit.body = new FormData(this.$el);\n }\n\n return requestInit;\n }\n\n /**\n * Prevent submit on forms.\n */\n onSubmit({ event }: { event: SubmitEvent; target: FrameForm }) {\n if (this.$el.target !== '_blank') {\n event.preventDefault();\n this.trigger();\n }\n }\n}\n"],
5
- "mappings": "AACA,SAAS,4BAA4B;AAY9B,MAAM,kBAAmD,qBAE9D;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM,CAAC,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAS;AACX,WAAO,KAAK,IAAI,OAAO,YAAY;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAW;AACb,UAAM,MAAM,IAAI,IAAI,KAAK,IAAI,MAAM;AAEnC,QAAI,KAAK,WAAW,OAAO;AAEzB,UAAI,SAAS,IAAI,gBAAgB,IAAI,SAAS,KAAK,GAAG,CAAC,EAAE,SAAS;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAA2B;AAC7B,UAAM,cAAc,EAAE,GAAG,MAAM,YAAY;AAC3C,gBAAY,YAAY,CAAC;AAEzB,eAAW,UAAU,KAAK,MAAM,SAAS;AACvC,UAAI,OAAO,QAAQ,QAAQ,OAAO,OAAO;AACvC,oBAAY,QAAQ,OAAO,QAAQ,IAAI,IAAI,OAAO;AAAA,MACpD;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,QAAQ;AAC1B,kBAAY,SAAS,KAAK;AAC1B,kBAAY,OAAO,IAAI,SAAS,KAAK,GAAG;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,EAAE,MAAM,GAA8C;AAC7D,QAAI,KAAK,IAAI,WAAW,UAAU;AAChC,YAAM,eAAe;AACrB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { AbstractFrameTrigger } from './AbstractFrameTrigger.js';\n\nexport interface FrameFormProps extends BaseProps {\n $el: HTMLFormElement;\n $refs: {\n headers: HTMLInputElement[];\n };\n}\n\n/**\n * FrameForm class.\n */\nexport class FrameForm<T extends BaseProps = BaseProps> extends AbstractFrameTrigger<\n T & FrameFormProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'FrameForm',\n refs: ['headers[]'],\n };\n\n /**\n * Form submission method.\n */\n get method() {\n return this.$el.method.toLowerCase() as 'post' | 'get';\n }\n\n /**\n * Add params to the requested URL for GET submissions.\n */\n get url(): URL {\n const url = new URL(this.$el.action);\n\n if (this.method === 'get') {\n // @ts-expect-error URLSearchParams accepts FormData as parameter in the browser.\n url.search = new URLSearchParams(new FormData(this.$el)).toString();\n }\n\n return url;\n }\n\n /**\n * Add body to the request for POST submissions.\n */\n get requestInit(): RequestInit {\n const requestInit = { ...super.requestInit };\n requestInit.headers ??= {};\n\n if (this.$refs.headers) {\n for (const header of this.$refs.headers) {\n if (header.dataset.name && header.value) {\n requestInit.headers[header.dataset.name] = header.value;\n }\n }\n }\n\n if (this.method === 'post') {\n requestInit.method = this.method;\n requestInit.body = new FormData(this.$el);\n }\n\n return requestInit;\n }\n\n /**\n * Prevent submit on forms.\n */\n onSubmit({ event }: { event: SubmitEvent; target: FrameForm }) {\n if (this.$el.target !== '_blank') {\n event.preventDefault();\n this.trigger();\n }\n }\n}\n"],
5
+ "mappings": "AACA,SAAS,4BAA4B;AAY9B,MAAM,kBAAmD,qBAE9D;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,MAAM,CAAC,WAAW;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAS;AACX,WAAO,KAAK,IAAI,OAAO,YAAY;AAAA,EACrC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,MAAW;AACb,UAAM,MAAM,IAAI,IAAI,KAAK,IAAI,MAAM;AAEnC,QAAI,KAAK,WAAW,OAAO;AAEzB,UAAI,SAAS,IAAI,gBAAgB,IAAI,SAAS,KAAK,GAAG,CAAC,EAAE,SAAS;AAAA,IACpE;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,cAA2B;AAC7B,UAAM,cAAc,EAAE,GAAG,MAAM,YAAY;AAC3C,gBAAY,YAAY,CAAC;AAEzB,QAAI,KAAK,MAAM,SAAS;AACtB,iBAAW,UAAU,KAAK,MAAM,SAAS;AACvC,YAAI,OAAO,QAAQ,QAAQ,OAAO,OAAO;AACvC,sBAAY,QAAQ,OAAO,QAAQ,IAAI,IAAI,OAAO;AAAA,QACpD;AAAA,MACF;AAAA,IACF;AAEA,QAAI,KAAK,WAAW,QAAQ;AAC1B,kBAAY,SAAS,KAAK;AAC1B,kBAAY,OAAO,IAAI,SAAS,KAAK,GAAG;AAAA,IAC1C;AAEA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,EAAE,MAAM,GAA8C;AAC7D,QAAI,KAAK,IAAI,WAAW,UAAU;AAChC,YAAM,eAAe;AACrB,WAAK,QAAQ;AAAA,IACf;AAAA,EACF;AACF;",
6
6
  "names": []
7
7
  }
package/README.md CHANGED
@@ -4,10 +4,10 @@
4
4
  [![NPM Next Version](https://img.shields.io/npm/v/@studiometa/ui/next?style=flat&colorB=3e63dd&colorA=414853)](https://www.npmjs.com/package/@studiometa/ui/v/next)
5
5
  [![Downloads](https://img.shields.io/npm/dm/@studiometa/ui?style=flat&colorB=3e63dd&colorA=414853)](https://www.npmjs.com/package/@studiometa/ui/)
6
6
  [![Size](https://img.shields.io/bundlephobia/minzip/@studiometa/ui?style=flat&colorB=3e63dd&colorA=414853&label=size)](https://bundlephobia.com/package/@studiometa/ui)
7
- [![Dependency Status](https://img.shields.io/librariesio/release/npm/@studiometa/ui?style=flat&colorB=3e63dd&colorA=414853)](https://david-dm.org/studiometa/js-toolkit)
8
7
  ![Codecov](https://img.shields.io/codecov/c/github/studiometa/ui?style=flat&colorB=3e63dd&colorA=414853)
9
8
 
10
- > 📦 A set of opiniated, unstyled and accessible components based on [@studiometa/js-toolkit](https://github.com/studiometa/js-toolkit)
9
+ > A set of JS and Twig components powered by [@studiometa/js-toolkit](https://github.com/studiometa/js-toolkit), [Tailwind CSS](https://tailwindcss.com/) and
10
+ [studiometa/twig-toolkit](https://github.com/studiometa/twig-toolkit).
11
11
 
12
12
  ## Installation
13
13
 
@@ -17,7 +17,7 @@ Install the latest version via NPM:
17
17
  npm install @studiometa/ui
18
18
  ```
19
19
 
20
- If you need the Twig template as well, install the Twig extension via Composer and load it in your application:
20
+ If you need the Twig templates as well, install the Twig extension via Composer and load it in your application:
21
21
 
22
22
  ```bash
23
23
  composer require studiometa/ui
@@ -29,18 +29,23 @@ Import the components from the package as needed:
29
29
 
30
30
  ```js
31
31
  import { Base, createApp } from '@studiometa/js-toolkit';
32
- import { Modal } from '@studiometa/ui';
32
+ import { Action, Frame, Modal, ScrollAnimation, ScrollReveal, Slider } from '@studiometa/ui';
33
33
 
34
34
  class App extends Base {
35
35
  static config = {
36
36
  name: 'App',
37
37
  components: {
38
+ Action,
39
+ Frame,
38
40
  Modal,
39
- }
40
- }
41
+ ScrollAnimation,
42
+ ScrollReveal,
43
+ Slider,
44
+ },
45
+ };
41
46
  }
42
47
 
43
- export default createApp(App, document.body);
48
+ export default createApp(App);
44
49
  ```
45
50
 
46
51
  Heads up to [ui.studiometa.dev](https://ui.studiometa.dev) for more informations.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@studiometa/ui",
3
- "version": "1.0.0-rc.1",
3
+ "version": "1.0.0-rc.2",
4
4
  "description": "A set of opiniated, unstyled and accessible components",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -33,9 +33,9 @@
33
33
  "morphdom": "^2.7.5"
34
34
  },
35
35
  "devDependencies": {
36
- "@studiometa/js-toolkit": "3.0.2"
36
+ "@studiometa/js-toolkit": "3.0.4"
37
37
  },
38
38
  "peerDependencies": {
39
- "@studiometa/js-toolkit": "^3.0.0"
39
+ "@studiometa/js-toolkit": "^3.0.4"
40
40
  }
41
41
  }