@studiometa/ui 0.2.44 → 0.2.45
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 +2 -0
- package/atoms/Figure/FigureTwicpics.cjs +22 -4
- package/atoms/Figure/FigureTwicpics.cjs.map +2 -2
- package/atoms/Figure/FigureTwicpics.d.ts +9 -1
- package/atoms/Figure/FigureTwicpics.js +22 -4
- package/atoms/Figure/FigureTwicpics.js.map +2 -2
- package/molecules/MapboxStaticMap/MapboxStaticMap.twig +79 -0
- package/molecules/Reinsurance/Reinsurance.twig +63 -0
- package/molecules/Slider/Slider.cjs +8 -0
- package/molecules/Slider/Slider.cjs.map +2 -2
- package/molecules/Slider/Slider.d.ts +4 -0
- package/molecules/Slider/Slider.js +8 -0
- package/molecules/Slider/Slider.js.map +2 -2
- package/molecules/Slider/SliderItem.cjs +14 -3
- package/molecules/Slider/SliderItem.cjs.map +2 -2
- package/molecules/Slider/SliderItem.d.ts +8 -0
- package/molecules/Slider/SliderItem.js +14 -3
- package/molecules/Slider/SliderItem.js.map +2 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -46,3 +46,5 @@ Heads up to [ui.studiometa.dev](https://ui.studiometa.dev) for more informations
|
|
|
46
46
|
## Contributing
|
|
47
47
|
|
|
48
48
|
Please read the [contribution docs](https://ui.studiometa.dev/-/guide/contributing/).
|
|
49
|
+
|
|
50
|
+
[](https://gitpod.io/#https://github.com/studiometa/ui)
|
|
@@ -33,6 +33,7 @@ function normalizeSize(that, prop) {
|
|
|
33
33
|
const { step } = that.$options;
|
|
34
34
|
return Math.ceil(that.$refs.img[prop] / step) * step;
|
|
35
35
|
}
|
|
36
|
+
var isBot = /bot|crawl|slurp|spider/i.test(navigator.userAgent);
|
|
36
37
|
var FigureTwicpics = class extends import_Figure.Figure {
|
|
37
38
|
/**
|
|
38
39
|
* Get the Twicpics path.
|
|
@@ -48,10 +49,22 @@ var FigureTwicpics = class extends import_Figure.Figure {
|
|
|
48
49
|
return url.host;
|
|
49
50
|
}
|
|
50
51
|
/**
|
|
51
|
-
* Get
|
|
52
|
+
* Get formatted original source.
|
|
53
|
+
* If `disable` option is `true` returns the original src.
|
|
52
54
|
*/
|
|
53
55
|
get original() {
|
|
54
|
-
return this.formatSrc(super.original);
|
|
56
|
+
return this.$options.disable ? super.original : this.formatSrc(super.original);
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Get the current device pixel ratio
|
|
60
|
+
* Returns 1 if user agent is considered as a bot.
|
|
61
|
+
* Returns 1 if disabled by the `data-option-no-dpr` attribute.
|
|
62
|
+
*/
|
|
63
|
+
get devicePixelRatio() {
|
|
64
|
+
if (!this.$options.dpr || isBot) {
|
|
65
|
+
return 1;
|
|
66
|
+
}
|
|
67
|
+
return window.devicePixelRatio;
|
|
55
68
|
}
|
|
56
69
|
/**
|
|
57
70
|
* Format the source for Twicpics.
|
|
@@ -63,8 +76,8 @@ var FigureTwicpics = class extends import_Figure.Figure {
|
|
|
63
76
|
if (this.path && !url.pathname.startsWith((0, import_utils.withLeadingSlash)(this.path))) {
|
|
64
77
|
url.pathname = `/${this.path}${url.pathname}`;
|
|
65
78
|
}
|
|
66
|
-
const width = normalizeSize(this, "offsetWidth");
|
|
67
|
-
const height = normalizeSize(this, "offsetHeight");
|
|
79
|
+
const width = normalizeSize(this, "offsetWidth") * this.devicePixelRatio;
|
|
80
|
+
const height = normalizeSize(this, "offsetHeight") * this.devicePixelRatio;
|
|
68
81
|
url.searchParams.set(
|
|
69
82
|
"twic",
|
|
70
83
|
["v1", this.$options.transform, `${this.$options.mode}=${width}x${height}`].filter(Boolean).join("/")
|
|
@@ -96,6 +109,7 @@ __publicField(FigureTwicpics, "config", {
|
|
|
96
109
|
transform: String,
|
|
97
110
|
domain: String,
|
|
98
111
|
path: String,
|
|
112
|
+
disable: Boolean,
|
|
99
113
|
step: {
|
|
100
114
|
type: Number,
|
|
101
115
|
default: 50
|
|
@@ -103,6 +117,10 @@ __publicField(FigureTwicpics, "config", {
|
|
|
103
117
|
mode: {
|
|
104
118
|
type: String,
|
|
105
119
|
default: "cover"
|
|
120
|
+
},
|
|
121
|
+
dpr: {
|
|
122
|
+
type: Boolean,
|
|
123
|
+
default: true
|
|
106
124
|
}
|
|
107
125
|
}
|
|
108
126
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/atoms/Figure/FigureTwicpics.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport {\n withLeadingSlash,\n withoutLeadingSlash,\n withoutTrailingSlash,\n} from '@studiometa/js-toolkit/utils';\nimport { Figure, loadImage } from './Figure.js';\n\nexport interface FigureTwicpicsProps extends BaseProps {\n $options: {\n transform: string;\n domain: string;\n path: string;\n step: number;\n mode: string;\n };\n}\n\n/**\n * Normalize the given size to the step option.\n */\n// eslint-disable-next-line no-use-before-define\nfunction normalizeSize(that: FigureTwicpics, prop: string): number {\n const { step } = that.$options;\n return Math.ceil(that.$refs.img[prop] / step) * step;\n}\n\n/**\n * Figure class.\n *\n * Manager lazyloading image sources.\n */\nexport class FigureTwicpics<T extends BaseProps = BaseProps> extends Figure<\n T & FigureTwicpicsProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Figure.config,\n name: 'FigureTwicpics',\n options: {\n ...Figure.config.options,\n transform: String,\n domain: String,\n path: String,\n step: {\n type: Number,\n default: 50,\n },\n mode: {\n type: String,\n default: 'cover',\n },\n },\n };\n\n /**\n * Get the Twicpics path.\n */\n get path(): string {\n return withoutTrailingSlash(withoutLeadingSlash(this.$options.path));\n }\n\n /**\n * Get the Twicpics domain.\n */\n get domain(): string {\n const url = new URL(this.$refs.img.dataset.src);\n return url.host;\n }\n\n /**\n * Get
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAIO;AACP,oBAAkC;
|
|
4
|
+
"sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport {\n withLeadingSlash,\n withoutLeadingSlash,\n withoutTrailingSlash,\n} from '@studiometa/js-toolkit/utils';\nimport { Figure, loadImage } from './Figure.js';\n\nexport interface FigureTwicpicsProps extends BaseProps {\n $options: {\n transform: string;\n domain: string;\n path: string;\n step: number;\n mode: string;\n dpr: boolean;\n };\n}\n\n/**\n * Normalize the given size to the step option.\n */\n// eslint-disable-next-line no-use-before-define\nfunction normalizeSize(that: FigureTwicpics, prop: string): number {\n const { step } = that.$options;\n return Math.ceil(that.$refs.img[prop] / step) * step;\n}\n\n/**\n * Determine if the user agent is a bot or not.\n */\nconst isBot = /bot|crawl|slurp|spider/i.test(navigator.userAgent);\n\n/**\n * Figure class.\n *\n * Manager lazyloading image sources.\n */\nexport class FigureTwicpics<T extends BaseProps = BaseProps> extends Figure<\n T & FigureTwicpicsProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Figure.config,\n name: 'FigureTwicpics',\n options: {\n ...Figure.config.options,\n transform: String,\n domain: String,\n path: String,\n disable: Boolean,\n step: {\n type: Number,\n default: 50,\n },\n mode: {\n type: String,\n default: 'cover',\n },\n dpr: {\n type: Boolean,\n default: true,\n },\n },\n };\n\n /**\n * Get the Twicpics path.\n */\n get path(): string {\n return withoutTrailingSlash(withoutLeadingSlash(this.$options.path));\n }\n\n /**\n * Get the Twicpics domain.\n */\n get domain(): string {\n const url = new URL(this.$refs.img.dataset.src);\n return url.host;\n }\n\n /**\n * Get formatted original source.\n * If `disable` option is `true` returns the original src.\n */\n get original() {\n return this.$options.disable ? super.original : this.formatSrc(super.original);\n }\n\n /**\n * Get the current device pixel ratio\n * Returns 1 if user agent is considered as a bot.\n * Returns 1 if disabled by the `data-option-no-dpr` attribute.\n */\n get devicePixelRatio() {\n if (!this.$options.dpr || isBot) {\n return 1;\n }\n\n return window.devicePixelRatio;\n }\n\n /**\n * Format the source for Twicpics.\n */\n formatSrc(src: string): string {\n const url = new URL(src, 'https://localhost');\n url.host = this.domain;\n url.port = '';\n\n if (this.path && !url.pathname.startsWith(withLeadingSlash(this.path))) {\n url.pathname = `/${this.path}${url.pathname}`;\n }\n\n const width = normalizeSize(this, 'offsetWidth') * this.devicePixelRatio;\n const height = normalizeSize(this, 'offsetHeight') * this.devicePixelRatio;\n\n url.searchParams.set(\n 'twic',\n ['v1', this.$options.transform, `${this.$options.mode}=${width}x${height}`]\n .filter(Boolean)\n .join('/'),\n );\n\n url.search = decodeURIComponent(url.search);\n\n return url.toString();\n }\n\n /**\n * Reassign the source from the original on resize.\n */\n async resized() {\n const { src } = await loadImage(this.original);\n this.src = src;\n }\n\n /**\n * Do not terminate on image load as we need to set the src on resize.\n */\n onLoad() {\n // Do not terminate on image load as we need.\n }\n}\n"],
|
|
5
|
+
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AACA,mBAIO;AACP,oBAAkC;AAiBlC,SAAS,cAAc,MAAsB,MAAsB;AACjE,QAAM,EAAE,KAAK,IAAI,KAAK;AACtB,SAAO,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI;AAClD;AAKA,IAAM,QAAQ,0BAA0B,KAAK,UAAU,SAAS;AAOzD,IAAM,iBAAN,cAA8D,qBAEnE;AAAA;AAAA;AAAA;AAAA,EA+BA,IAAI,OAAe;AACjB,eAAO,uCAAqB,kCAAoB,KAAK,SAAS,IAAI,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAiB;AACnB,UAAM,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,QAAQ,GAAG;AAC9C,WAAO,IAAI;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,WAAW;AACb,WAAO,KAAK,SAAS,UAAU,MAAM,WAAW,KAAK,UAAU,MAAM,QAAQ;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,mBAAmB;AACrB,QAAI,CAAC,KAAK,SAAS,OAAO,OAAO;AAC/B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,KAAqB;AAC7B,UAAM,MAAM,IAAI,IAAI,KAAK,mBAAmB;AAC5C,QAAI,OAAO,KAAK;AAChB,QAAI,OAAO;AAEX,QAAI,KAAK,QAAQ,CAAC,IAAI,SAAS,eAAW,+BAAiB,KAAK,IAAI,CAAC,GAAG;AACtE,UAAI,WAAW,IAAI,KAAK,OAAO,IAAI;AAAA,IACrC;AAEA,UAAM,QAAQ,cAAc,MAAM,aAAa,IAAI,KAAK;AACxD,UAAM,SAAS,cAAc,MAAM,cAAc,IAAI,KAAK;AAE1D,QAAI,aAAa;AAAA,MACf;AAAA,MACA,CAAC,MAAM,KAAK,SAAS,WAAW,GAAG,KAAK,SAAS,QAAQ,SAAS,QAAQ,EACvE,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,IACb;AAEA,QAAI,SAAS,mBAAmB,IAAI,MAAM;AAE1C,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACd,UAAM,EAAE,IAAI,IAAI,UAAM,yBAAU,KAAK,QAAQ;AAC7C,SAAK,MAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AAAA,EAET;AACF;AAAA;AAAA;AAAA;AArGE,cANW,gBAMJ,UAAqB;AAAA,EAC1B,GAAG,qBAAO;AAAA,EACV,MAAM;AAAA,EACN,SAAS;AAAA,IACP,GAAG,qBAAO,OAAO;AAAA,IACjB,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,IACT,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,MAAM;AAAA,MACJ,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,IACA,KAAK;AAAA,MACH,MAAM;AAAA,MACN,SAAS;AAAA,IACX;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -7,6 +7,7 @@ export interface FigureTwicpicsProps extends BaseProps {
|
|
|
7
7
|
path: string;
|
|
8
8
|
step: number;
|
|
9
9
|
mode: string;
|
|
10
|
+
dpr: boolean;
|
|
10
11
|
};
|
|
11
12
|
}
|
|
12
13
|
/**
|
|
@@ -28,9 +29,16 @@ export declare class FigureTwicpics<T extends BaseProps = BaseProps> extends Fig
|
|
|
28
29
|
*/
|
|
29
30
|
get domain(): string;
|
|
30
31
|
/**
|
|
31
|
-
* Get
|
|
32
|
+
* Get formatted original source.
|
|
33
|
+
* If `disable` option is `true` returns the original src.
|
|
32
34
|
*/
|
|
33
35
|
get original(): string;
|
|
36
|
+
/**
|
|
37
|
+
* Get the current device pixel ratio
|
|
38
|
+
* Returns 1 if user agent is considered as a bot.
|
|
39
|
+
* Returns 1 if disabled by the `data-option-no-dpr` attribute.
|
|
40
|
+
*/
|
|
41
|
+
get devicePixelRatio(): number;
|
|
34
42
|
/**
|
|
35
43
|
* Format the source for Twicpics.
|
|
36
44
|
*/
|
|
@@ -8,6 +8,7 @@ function normalizeSize(that, prop) {
|
|
|
8
8
|
const { step } = that.$options;
|
|
9
9
|
return Math.ceil(that.$refs.img[prop] / step) * step;
|
|
10
10
|
}
|
|
11
|
+
const isBot = /bot|crawl|slurp|spider/i.test(navigator.userAgent);
|
|
11
12
|
class FigureTwicpics extends Figure {
|
|
12
13
|
/**
|
|
13
14
|
* Config.
|
|
@@ -20,6 +21,7 @@ class FigureTwicpics extends Figure {
|
|
|
20
21
|
transform: String,
|
|
21
22
|
domain: String,
|
|
22
23
|
path: String,
|
|
24
|
+
disable: Boolean,
|
|
23
25
|
step: {
|
|
24
26
|
type: Number,
|
|
25
27
|
default: 50
|
|
@@ -27,6 +29,10 @@ class FigureTwicpics extends Figure {
|
|
|
27
29
|
mode: {
|
|
28
30
|
type: String,
|
|
29
31
|
default: "cover"
|
|
32
|
+
},
|
|
33
|
+
dpr: {
|
|
34
|
+
type: Boolean,
|
|
35
|
+
default: true
|
|
30
36
|
}
|
|
31
37
|
}
|
|
32
38
|
};
|
|
@@ -44,10 +50,22 @@ class FigureTwicpics extends Figure {
|
|
|
44
50
|
return url.host;
|
|
45
51
|
}
|
|
46
52
|
/**
|
|
47
|
-
* Get
|
|
53
|
+
* Get formatted original source.
|
|
54
|
+
* If `disable` option is `true` returns the original src.
|
|
48
55
|
*/
|
|
49
56
|
get original() {
|
|
50
|
-
return this.formatSrc(super.original);
|
|
57
|
+
return this.$options.disable ? super.original : this.formatSrc(super.original);
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Get the current device pixel ratio
|
|
61
|
+
* Returns 1 if user agent is considered as a bot.
|
|
62
|
+
* Returns 1 if disabled by the `data-option-no-dpr` attribute.
|
|
63
|
+
*/
|
|
64
|
+
get devicePixelRatio() {
|
|
65
|
+
if (!this.$options.dpr || isBot) {
|
|
66
|
+
return 1;
|
|
67
|
+
}
|
|
68
|
+
return window.devicePixelRatio;
|
|
51
69
|
}
|
|
52
70
|
/**
|
|
53
71
|
* Format the source for Twicpics.
|
|
@@ -59,8 +77,8 @@ class FigureTwicpics extends Figure {
|
|
|
59
77
|
if (this.path && !url.pathname.startsWith(withLeadingSlash(this.path))) {
|
|
60
78
|
url.pathname = `/${this.path}${url.pathname}`;
|
|
61
79
|
}
|
|
62
|
-
const width = normalizeSize(this, "offsetWidth");
|
|
63
|
-
const height = normalizeSize(this, "offsetHeight");
|
|
80
|
+
const width = normalizeSize(this, "offsetWidth") * this.devicePixelRatio;
|
|
81
|
+
const height = normalizeSize(this, "offsetHeight") * this.devicePixelRatio;
|
|
64
82
|
url.searchParams.set(
|
|
65
83
|
"twic",
|
|
66
84
|
["v1", this.$options.transform, `${this.$options.mode}=${width}x${height}`].filter(Boolean).join("/")
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/atoms/Figure/FigureTwicpics.ts"],
|
|
4
|
-
"sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport {\n withLeadingSlash,\n withoutLeadingSlash,\n withoutTrailingSlash,\n} from '@studiometa/js-toolkit/utils';\nimport { Figure, loadImage } from './Figure.js';\n\nexport interface FigureTwicpicsProps extends BaseProps {\n $options: {\n transform: string;\n domain: string;\n path: string;\n step: number;\n mode: string;\n };\n}\n\n/**\n * Normalize the given size to the step option.\n */\n// eslint-disable-next-line no-use-before-define\nfunction normalizeSize(that: FigureTwicpics, prop: string): number {\n const { step } = that.$options;\n return Math.ceil(that.$refs.img[prop] / step) * step;\n}\n\n/**\n * Figure class.\n *\n * Manager lazyloading image sources.\n */\nexport class FigureTwicpics<T extends BaseProps = BaseProps> extends Figure<\n T & FigureTwicpicsProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Figure.config,\n name: 'FigureTwicpics',\n options: {\n ...Figure.config.options,\n transform: String,\n domain: String,\n path: String,\n step: {\n type: Number,\n default: 50,\n },\n mode: {\n type: String,\n default: 'cover',\n },\n },\n };\n\n /**\n * Get the Twicpics path.\n */\n get path(): string {\n return withoutTrailingSlash(withoutLeadingSlash(this.$options.path));\n }\n\n /**\n * Get the Twicpics domain.\n */\n get domain(): string {\n const url = new URL(this.$refs.img.dataset.src);\n return url.host;\n }\n\n /**\n * Get
|
|
5
|
-
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,QAAQ,iBAAiB;
|
|
4
|
+
"sourcesContent": ["import type { BaseConfig, BaseProps } from '@studiometa/js-toolkit';\nimport {\n withLeadingSlash,\n withoutLeadingSlash,\n withoutTrailingSlash,\n} from '@studiometa/js-toolkit/utils';\nimport { Figure, loadImage } from './Figure.js';\n\nexport interface FigureTwicpicsProps extends BaseProps {\n $options: {\n transform: string;\n domain: string;\n path: string;\n step: number;\n mode: string;\n dpr: boolean;\n };\n}\n\n/**\n * Normalize the given size to the step option.\n */\n// eslint-disable-next-line no-use-before-define\nfunction normalizeSize(that: FigureTwicpics, prop: string): number {\n const { step } = that.$options;\n return Math.ceil(that.$refs.img[prop] / step) * step;\n}\n\n/**\n * Determine if the user agent is a bot or not.\n */\nconst isBot = /bot|crawl|slurp|spider/i.test(navigator.userAgent);\n\n/**\n * Figure class.\n *\n * Manager lazyloading image sources.\n */\nexport class FigureTwicpics<T extends BaseProps = BaseProps> extends Figure<\n T & FigureTwicpicsProps\n> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n ...Figure.config,\n name: 'FigureTwicpics',\n options: {\n ...Figure.config.options,\n transform: String,\n domain: String,\n path: String,\n disable: Boolean,\n step: {\n type: Number,\n default: 50,\n },\n mode: {\n type: String,\n default: 'cover',\n },\n dpr: {\n type: Boolean,\n default: true,\n },\n },\n };\n\n /**\n * Get the Twicpics path.\n */\n get path(): string {\n return withoutTrailingSlash(withoutLeadingSlash(this.$options.path));\n }\n\n /**\n * Get the Twicpics domain.\n */\n get domain(): string {\n const url = new URL(this.$refs.img.dataset.src);\n return url.host;\n }\n\n /**\n * Get formatted original source.\n * If `disable` option is `true` returns the original src.\n */\n get original() {\n return this.$options.disable ? super.original : this.formatSrc(super.original);\n }\n\n /**\n * Get the current device pixel ratio\n * Returns 1 if user agent is considered as a bot.\n * Returns 1 if disabled by the `data-option-no-dpr` attribute.\n */\n get devicePixelRatio() {\n if (!this.$options.dpr || isBot) {\n return 1;\n }\n\n return window.devicePixelRatio;\n }\n\n /**\n * Format the source for Twicpics.\n */\n formatSrc(src: string): string {\n const url = new URL(src, 'https://localhost');\n url.host = this.domain;\n url.port = '';\n\n if (this.path && !url.pathname.startsWith(withLeadingSlash(this.path))) {\n url.pathname = `/${this.path}${url.pathname}`;\n }\n\n const width = normalizeSize(this, 'offsetWidth') * this.devicePixelRatio;\n const height = normalizeSize(this, 'offsetHeight') * this.devicePixelRatio;\n\n url.searchParams.set(\n 'twic',\n ['v1', this.$options.transform, `${this.$options.mode}=${width}x${height}`]\n .filter(Boolean)\n .join('/'),\n );\n\n url.search = decodeURIComponent(url.search);\n\n return url.toString();\n }\n\n /**\n * Reassign the source from the original on resize.\n */\n async resized() {\n const { src } = await loadImage(this.original);\n this.src = src;\n }\n\n /**\n * Do not terminate on image load as we need to set the src on resize.\n */\n onLoad() {\n // Do not terminate on image load as we need.\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAS,QAAQ,iBAAiB;AAiBlC,SAAS,cAAc,MAAsB,MAAsB;AACjE,QAAM,EAAE,KAAK,IAAI,KAAK;AACtB,SAAO,KAAK,KAAK,KAAK,MAAM,IAAI,IAAI,IAAI,IAAI,IAAI;AAClD;AAKA,MAAM,QAAQ,0BAA0B,KAAK,UAAU,SAAS;AAOzD,MAAM,uBAAwD,OAEnE;AAAA;AAAA;AAAA;AAAA,EAIA,OAAO,SAAqB;AAAA,IAC1B,GAAG,OAAO;AAAA,IACV,MAAM;AAAA,IACN,SAAS;AAAA,MACP,GAAG,OAAO,OAAO;AAAA,MACjB,WAAW;AAAA,MACX,QAAQ;AAAA,MACR,MAAM;AAAA,MACN,SAAS;AAAA,MACT,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA,MAAM;AAAA,QACJ,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,MACA,KAAK;AAAA,QACH,MAAM;AAAA,QACN,SAAS;AAAA,MACX;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,OAAe;AACjB,WAAO,qBAAqB,oBAAoB,KAAK,SAAS,IAAI,CAAC;AAAA,EACrE;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,SAAiB;AACnB,UAAM,MAAM,IAAI,IAAI,KAAK,MAAM,IAAI,QAAQ,GAAG;AAC9C,WAAO,IAAI;AAAA,EACb;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,IAAI,WAAW;AACb,WAAO,KAAK,SAAS,UAAU,MAAM,WAAW,KAAK,UAAU,MAAM,QAAQ;AAAA,EAC/E;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,IAAI,mBAAmB;AACrB,QAAI,CAAC,KAAK,SAAS,OAAO,OAAO;AAC/B,aAAO;AAAA,IACT;AAEA,WAAO,OAAO;AAAA,EAChB;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,KAAqB;AAC7B,UAAM,MAAM,IAAI,IAAI,KAAK,mBAAmB;AAC5C,QAAI,OAAO,KAAK;AAChB,QAAI,OAAO;AAEX,QAAI,KAAK,QAAQ,CAAC,IAAI,SAAS,WAAW,iBAAiB,KAAK,IAAI,CAAC,GAAG;AACtE,UAAI,WAAW,IAAI,KAAK,OAAO,IAAI;AAAA,IACrC;AAEA,UAAM,QAAQ,cAAc,MAAM,aAAa,IAAI,KAAK;AACxD,UAAM,SAAS,cAAc,MAAM,cAAc,IAAI,KAAK;AAE1D,QAAI,aAAa;AAAA,MACf;AAAA,MACA,CAAC,MAAM,KAAK,SAAS,WAAW,GAAG,KAAK,SAAS,QAAQ,SAAS,QAAQ,EACvE,OAAO,OAAO,EACd,KAAK,GAAG;AAAA,IACb;AAEA,QAAI,SAAS,mBAAmB,IAAI,MAAM;AAE1C,WAAO,IAAI,SAAS;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU;AACd,UAAM,EAAE,IAAI,IAAI,MAAM,UAAU,KAAK,QAAQ;AAC7C,SAAK,MAAM;AAAA,EACb;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS;AAAA,EAET;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{#
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
* MapboxStaticMap component.
|
|
5
|
+
* Extends Figure component.
|
|
6
|
+
*
|
|
7
|
+
* @param array $attr
|
|
8
|
+
* Use it to customize the root element attributes.
|
|
9
|
+
* @param string $alt
|
|
10
|
+
* The image alt.
|
|
11
|
+
* @param string $username
|
|
12
|
+
* The username of the account to which the style belongs.
|
|
13
|
+
* @param string $style_id
|
|
14
|
+
* The ID of the style from which to create a static map.
|
|
15
|
+
* @param number $lon
|
|
16
|
+
* Longitude for the center point of the static map; a number between -180 and 180.
|
|
17
|
+
* @param number $lat
|
|
18
|
+
* Latitude for the center point of the static map; a number between -85.0511 and 85.0511.
|
|
19
|
+
* @param number $zoom
|
|
20
|
+
* Zoom level; a number between 0 and 22. Fractional zoom levels will be rounded to two decimal places.
|
|
21
|
+
* @param number $width
|
|
22
|
+
* Width of the image; a number between 1 and 1280 pixels.
|
|
23
|
+
* @param number $height
|
|
24
|
+
* Height of the image; a number between 1 and 1280 pixels.
|
|
25
|
+
*
|
|
26
|
+
* - Optional parameters
|
|
27
|
+
*
|
|
28
|
+
* @param string $overlay
|
|
29
|
+
* Add overlays/markers, must be a valid geojson object.
|
|
30
|
+
* see https://docs.mapbox.com/api/maps/static-images/#overlay-options
|
|
31
|
+
* @param string $marker
|
|
32
|
+
* Add custom marker.
|
|
33
|
+
* see https://docs.mapbox.com/api/maps/static-images/#example-request-retrieve-a-static-map-with-a-custom-marker-overlay
|
|
34
|
+
* @param number $bearing
|
|
35
|
+
* Rotation, between 0 and 360
|
|
36
|
+
* @param number $pitch
|
|
37
|
+
* Pitch tilts the map, between 0 and 60
|
|
38
|
+
* @param string $is_hd
|
|
39
|
+
* Renders at @2x scale, default: true
|
|
40
|
+
* @param boolean $attribution
|
|
41
|
+
* Whether there is attribution on the image, if false read: https://docs.mapbox.com/help/getting-started/attribution/#static--print, default: true
|
|
42
|
+
* @param boolean $logo
|
|
43
|
+
* Whether there is a Mapbox logo, defaults: true
|
|
44
|
+
*
|
|
45
|
+
*/
|
|
46
|
+
#}
|
|
47
|
+
|
|
48
|
+
{% extends '@ui-pkg/atoms/Figure/Figure.twig' %}
|
|
49
|
+
|
|
50
|
+
{% set access_token = access_token|default('<MISSING_ACCESS_TOKEN>') %}
|
|
51
|
+
{% set username = username|default('mapbox') %}
|
|
52
|
+
{% set style_id = style_id|default('streets-v12') %}
|
|
53
|
+
{% set overlay = overlay|default({}) %}
|
|
54
|
+
{% set marker = marker|default('') %}
|
|
55
|
+
{% set lon = lon|default(0) %}
|
|
56
|
+
{% set lat = lat|default(0) %}
|
|
57
|
+
{% set zoom = zoom|default(0) %}
|
|
58
|
+
{% set bearing = bearing|default(0) %}
|
|
59
|
+
{% set pitch = pitch|default(0) %}
|
|
60
|
+
{% set is_hd = is_hd is defined and not is_hd ? false : true %}
|
|
61
|
+
|
|
62
|
+
{% set query_params = {
|
|
63
|
+
access_token: access_token,
|
|
64
|
+
} %}
|
|
65
|
+
|
|
66
|
+
{% if attribution is defined and not attribution %}
|
|
67
|
+
{% set query_params = query_params|merge({
|
|
68
|
+
attribution: 'false'
|
|
69
|
+
}) %}
|
|
70
|
+
{% endif %}
|
|
71
|
+
|
|
72
|
+
{% if logo is defined and not logo %}
|
|
73
|
+
{% set query_params = query_params|merge({
|
|
74
|
+
logo: 'false'
|
|
75
|
+
}) %}
|
|
76
|
+
{% endif %}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
{% set src = "https://api.mapbox.com/styles/v1/" ~ username ~ "/" ~ style_id ~ "/static/" ~ (marker ? marker|url_encode ~ '/' : '') ~ (overlay ? 'geojson(' ~ overlay|json_encode|url_encode ~ ')/' : '') ~ lon ~ "," ~ lat ~ "," ~ zoom ~ "," ~ bearing ~ "," ~ pitch ~ "/" ~ width ~ "x" ~ height ~ (is_hd ? '@2x' : '') ~ "?" ~ query_params|url_encode %}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{#
|
|
2
|
+
/**
|
|
3
|
+
* @file
|
|
4
|
+
* Reinsurance
|
|
5
|
+
*
|
|
6
|
+
* @param {Object} section_attr customize the section element.
|
|
7
|
+
* @param {Object} title_attr customize the title element
|
|
8
|
+
* @param {Object} content_attr customize the content element
|
|
9
|
+
* @param {Boolean} slider_mobile activate scroll on mobile
|
|
10
|
+
* @param {Array} mobile_classes adjust mobile scroll
|
|
11
|
+
* @param {Array} list list of reassurace
|
|
12
|
+
* @param {String} list.icon icon handle (svg)
|
|
13
|
+
* @param {String} list.title title of reinsurance
|
|
14
|
+
* @param {String} list.content content for reassurace
|
|
15
|
+
*
|
|
16
|
+
*/
|
|
17
|
+
#}
|
|
18
|
+
|
|
19
|
+
{% set section_attributes = merge_html_attributes(section_attr ?? null, { class: 'text-[0] pt-14 pb-6 text-center w-full' }) %}
|
|
20
|
+
|
|
21
|
+
{% set title_attributes = merge_html_attributes(title_attr ?? null, { class: 'text-xl mb-2' }) %}
|
|
22
|
+
|
|
23
|
+
{% set content_attributes = merge_html_attributes(content_attr ?? null, { class: 'text-sm text-black-50 mb-0' }) %}
|
|
24
|
+
|
|
25
|
+
{% set item_attributes = merge_html_attributes(item_attr ?? null, { class: 'inline-block align-top mb-12 s:mb-8 px-3 w-56 whitespace-normal' }) %}
|
|
26
|
+
|
|
27
|
+
{% set slider_mobile = slider_mobile|default(false) %}
|
|
28
|
+
|
|
29
|
+
{% if slider_mobile %}
|
|
30
|
+
{% set mobile_classes = mobile_classes|default(['whitespace-nowrap overflow-scroll s:whitespace-normal s:overflow-auto']) %}
|
|
31
|
+
{% set section_attributes = merge_html_attributes(
|
|
32
|
+
section_attr ?? null,
|
|
33
|
+
{
|
|
34
|
+
class: section_attributes.class|merge(mobile_classes)|join(' ')
|
|
35
|
+
}) %}
|
|
36
|
+
{% endif %}
|
|
37
|
+
|
|
38
|
+
<section {{ html_attributes(section_attributes) }}>
|
|
39
|
+
{% for item in list %}
|
|
40
|
+
{% set icon_attributes = merge_html_attributes(icon_attr ?? null, { attr: { class: 'inline-block mb-2 s:mb-8' }, name: item.icon }) %}
|
|
41
|
+
<div {{ html_attributes(item_attributes) }}>
|
|
42
|
+
{% block icon %}
|
|
43
|
+
{% if icon %}
|
|
44
|
+
{% include '@ui/atoms/Icon/IconInlineImg.twig' with icon_attributes only %}
|
|
45
|
+
{% endif %}
|
|
46
|
+
{% endblock %}
|
|
47
|
+
{% block title %}
|
|
48
|
+
{% if item.title %}
|
|
49
|
+
<p {{ html_attributes(title_attributes) }}>
|
|
50
|
+
{{ item.title|raw }}
|
|
51
|
+
</p>
|
|
52
|
+
{% endif %}
|
|
53
|
+
{% endblock %}
|
|
54
|
+
{% block content %}
|
|
55
|
+
{% if item.content %}
|
|
56
|
+
<p {{ html_attributes(content_attributes) }}>
|
|
57
|
+
{{ item.content|raw }}
|
|
58
|
+
</p>
|
|
59
|
+
{% endif %}
|
|
60
|
+
{% endblock %}
|
|
61
|
+
</div>
|
|
62
|
+
{% endfor %}
|
|
63
|
+
</section>
|
|
@@ -185,6 +185,7 @@ var Slider = class extends import_js_toolkit.Base {
|
|
|
185
185
|
*/
|
|
186
186
|
mounted() {
|
|
187
187
|
this.states = this.getStates();
|
|
188
|
+
this.setAccessibilityAttributes();
|
|
188
189
|
this.prepareInvisibleItems();
|
|
189
190
|
this.goTo(this.currentIndex);
|
|
190
191
|
}
|
|
@@ -200,6 +201,13 @@ var Slider = class extends import_js_toolkit.Base {
|
|
|
200
201
|
});
|
|
201
202
|
});
|
|
202
203
|
}
|
|
204
|
+
/**
|
|
205
|
+
* Set accessibility attributes for the component
|
|
206
|
+
*/
|
|
207
|
+
setAccessibilityAttributes() {
|
|
208
|
+
this.$el.setAttribute("role", "group");
|
|
209
|
+
this.$el.setAttribute("aria-roledescription", "carousel");
|
|
210
|
+
}
|
|
203
211
|
/**
|
|
204
212
|
* Go to the next slide.
|
|
205
213
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/molecules/Slider/Slider.ts"],
|
|
4
|
-
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type {\n BaseProps,\n BaseConfig,\n DragServiceProps,\n KeyServiceProps,\n} from '@studiometa/js-toolkit';\nimport { clamp, inertiaFinalValue, nextFrame, isDev } from '@studiometa/js-toolkit/utils';\nimport { SliderDrag } from './SliderDrag.js';\nimport { SliderItem } from './SliderItem.js';\n\nexport type SliderModes = 'left' | 'center' | 'right';\n\ntype SliderState = { x: Record<SliderModes, number> };\n\nexport interface SliderProps extends BaseProps {\n $refs: {\n wrapper: HTMLElement;\n };\n $children: {\n SliderItem: SliderItem[];\n SliderDrag: SliderDrag[];\n };\n $options: {\n mode: SliderModes;\n fitBounds: boolean;\n contain: boolean;\n sensitivity: number;\n dropSensitivity: number;\n };\n}\n\n/**\n * Orchestrate the slider items state transition.\n * @todo a11y\n */\nexport class Slider<T extends BaseProps = BaseProps> extends Base<T & SliderProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Slider',\n refs: ['wrapper', 'debug'],\n emits: ['goto', 'index'],\n components: {\n SliderItem,\n SliderDrag,\n },\n options: {\n mode: { type: String, default: 'left' },\n fitBounds: Boolean,\n contain: Boolean,\n sensitivity: { type: Number, default: 1 },\n dropSensitivity: { type: Number, default: 2 },\n },\n };\n\n __distanceX = 0;\n\n __initialX = 0;\n\n /**\n * Index of the current active slide.\n */\n __currentIndex = 0;\n\n __isDragging = false;\n\n /**\n * Get the current index.\n */\n get currentIndex() {\n return this.__currentIndex;\n }\n\n /**\n * Set the current index and emit the `index` event.\n */\n set currentIndex(value: number) {\n this.currentSliderItem.disactivate();\n this.$emit('index', value);\n this.__currentIndex = value;\n this.currentSliderItem.activate();\n }\n\n /**\n * Store all the states.\n */\n states: SliderState[] = [];\n\n /**\n * Origins for the different modes.\n */\n origins: Record<SliderModes, number> = {\n left: 0,\n center: 0,\n right: 0,\n };\n\n /**\n * Wether or not the wrapper is focused.\n * @type {boolean}\n */\n hasFocus = false;\n\n /**\n * Get the current state.\n */\n get currentState() {\n return this.states[this.currentIndex];\n }\n\n /**\n * Get the first state.\n */\n get firstState() {\n return this.states[0];\n }\n\n /**\n * Get the last state.\n */\n get lastState() {\n return this.states.at(-1);\n }\n\n /**\n * Get the minimal contain state value.\n */\n get containMinState(): number {\n return this.getStateValueByMode(this.firstState.x, 'left');\n }\n\n /**\n * Get the maximal contain state value.\n */\n get containMaxState(): number {\n return this.getStateValueByMode(this.lastState.x, 'right');\n }\n\n /**\n * Get the last index.\n */\n get indexMax(): number {\n return this.$children.SliderItem.length - 1;\n }\n\n /**\n * Get the current SliderItem\n */\n get currentSliderItem() {\n return this.$children.SliderItem[this.currentIndex];\n }\n\n /**\n * Get the states for each SliderItem.\n */\n getStates(): SliderState[] {\n const { wrapper } = this.$refs;\n const originRect = wrapper.getBoundingClientRect();\n\n this.origins = {\n left: originRect.left,\n center: originRect.x + originRect.width / 2,\n right: originRect.x + originRect.width,\n };\n\n const states: SliderState[] = this.$children.SliderItem.map((item) => ({\n x: {\n left: (item.rect.x - this.origins.left) * -1,\n center: (item.rect.x + item.rect.width / 2 - this.origins.center) * -1,\n right: (item.rect.x + item.rect.width - this.origins.right) * -1,\n },\n }));\n\n if (this.$options.contain) {\n const { mode } = this.$options;\n // Find state where last child has passed the wrapper bound completely\n if (mode === 'left') {\n const lastChild = this.$children.SliderItem.at(-1);\n\n const maxState = states.find((state) => {\n const lastChildPosition =\n lastChild.rect.x - this.origins.left + lastChild.rect.width + state.x.left;\n const diffWithWrapperBound = originRect.width - lastChildPosition;\n if (diffWithWrapperBound > 0) {\n state.x.left = Math.min(state.x.left + diffWithWrapperBound, 0);\n return true;\n }\n\n return false;\n });\n\n if (maxState) {\n return states.map((state) => {\n state.x.left = Math.max(state.x.left, maxState.x.left);\n return state;\n });\n }\n }\n\n if (mode === 'right') {\n const maxStateIndex = states.findIndex((state) => state.x.right <= 0);\n const maxState = maxStateIndex < 0 ? states.at(-1) : states[maxStateIndex - 1];\n\n return states.map((state) => {\n state.x.right = maxStateIndex < 0 ? maxState.x.right : Math.min(state.x.right, 0);\n return state;\n });\n }\n\n if (mode === 'center' && isDev) {\n console.warn(\n `[${this.$id}]`,\n 'The `center` mode is not yet compatible with the `contain` mode.',\n );\n }\n }\n\n return states;\n }\n\n /**\n * Get an origin by mode.\n */\n getOriginByMode(mode?: SliderModes) {\n return this.origins[mode ?? this.$options.mode];\n }\n\n /**\n * Get a state value according to the given mode.\n */\n getStateValueByMode(state: SliderState['x'], mode?: SliderModes) {\n return state[mode ?? this.$options.mode];\n }\n\n /**\n * Mounted hook.\n */\n mounted() {\n this.states = this.getStates();\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n }\n\n /**\n * Resized hook.\n */\n resized() {\n nextFrame(() => {\n this.states = this.getStates();\n nextFrame(() => {\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n });\n });\n }\n\n /**\n * Go to the next slide.\n */\n goNext() {\n if (this.currentIndex + 1 > this.indexMax) {\n return;\n }\n\n this.goTo(this.currentIndex + 1);\n }\n\n /**\n * Go to the previous slide.\n */\n goPrev() {\n if (this.currentIndex - 1 < 0) {\n return;\n }\n\n this.goTo(this.currentIndex - 1);\n }\n\n /**\n * Go to the given index.\n */\n goTo(index: number, { withInstantMove = true } = {}) {\n if (index < 0 || index > this.indexMax) {\n throw new Error('Index out of bound.');\n }\n\n const currentState = this.getStateValueByMode(this.currentState.x);\n const state = this.getStateValueByMode(this.states[index].x);\n const itemsToMove = this.getVisibleItems(state);\n const invisibleItemsToMoveInstantly = this.getInvisibleItems(state);\n\n itemsToMove.forEach((item) => {\n // Better perfs when going fast through the slides\n if (currentState !== state && withInstantMove) {\n item.moveInstantly(currentState);\n }\n nextFrame(() => item.move(state));\n });\n invisibleItemsToMoveInstantly.forEach((item) => {\n item.moveInstantly(state);\n });\n\n this.currentIndex = index;\n this.$emit('goto', index);\n }\n\n /**\n * Listen to the Draggable `start` event.\n */\n onSliderDragStart() {\n this.__initialX = this.currentSliderItem ? this.currentSliderItem.x : 0;\n this.__distanceX = this.__initialX;\n\n this.__isDragging = true;\n }\n\n /**\n * Listen to the Draggable `drag` event.\n */\n onSliderDragDrag(props: DragServiceProps) {\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n this.__distanceX = this.__initialX + props.distance.x * this.$options.sensitivity;\n\n this.getVisibleItems(this.__distanceX).forEach((item) => {\n item.moveInstantly(this.__distanceX);\n });\n }\n\n /**\n * Listen to the Draggable `drop` event and find the new active slide.\n */\n onSliderDragDrop(props: DragServiceProps) {\n if (!this.__isDragging) {\n return;\n }\n this.__isDragging = false;\n\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n let finalX = clamp(\n inertiaFinalValue(this.__distanceX, props.delta.x * this.$options.dropSensitivity),\n this.getStateValueByMode(this.firstState.x),\n this.getStateValueByMode(this.lastState.x),\n );\n\n const absoluteDifferencesBetweenDistanceAndState = this.states.map((state) =>\n Math.abs(finalX - this.getStateValueByMode(state.x)),\n );\n const minimumDifference = Math.min(...absoluteDifferencesBetweenDistanceAndState);\n const closestIndex = absoluteDifferencesBetweenDistanceAndState.indexOf(minimumDifference);\n\n if (this.$options.fitBounds) {\n this.goTo(closestIndex, { withInstantMove: false });\n } else {\n if (this.$options.contain) {\n finalX = Math.min(this.containMinState, finalX);\n finalX = Math.max(this.containMaxState, finalX);\n }\n this.$children.SliderItem.forEach((item) => {\n item.move(finalX);\n });\n this.currentIndex = closestIndex;\n }\n }\n\n /**\n * Enable focus.\n */\n onWrapperFocus() {\n this.hasFocus = true;\n }\n\n /**\n * Disable focus.\n */\n onWrapperBlur() {\n this.hasFocus = false;\n }\n\n /**\n * Go prev or next when focus is on the wrapper and pressing arrow keys.\n */\n keyed({ LEFT, RIGHT, isDown }: KeyServiceProps) {\n if (this.hasFocus && isDown) {\n if (LEFT) {\n this.goPrev();\n } else if (RIGHT) {\n this.goNext();\n }\n }\n }\n\n /**\n * Prepare invisible items.\n */\n prepareInvisibleItems() {\n const state = this.states[this.currentIndex];\n const nextItemsToPrepare = [];\n const previousItemsToPrepare = [];\n\n this.getInvisibleItems(this.getStateValueByMode(state.x)).forEach((item, i) => {\n if (i > this.currentIndex) {\n nextItemsToPrepare.push(item);\n return;\n }\n\n if (i < this.currentIndex) {\n previousItemsToPrepare.push(item);\n }\n });\n\n nextItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item);\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n\n previousItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item, { reversed: true });\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n }\n\n /**\n * Get the state where the given item will be visible.\n */\n getStateWhereItemWillBeInvisible(item: SliderItem, { reversed = false } = {}): SliderState {\n const visibleStates = this.states.filter((state) =>\n item.willBeVisible(this.getStateValueByMode(state.x)),\n );\n const firstVisibleState = visibleStates[0];\n const lastVisibleState = visibleStates.at(-1);\n const firstVisibleStateIndex = this.states.findIndex(\n (state) =>\n this.getStateValueByMode(state.x) === this.getStateValueByMode(firstVisibleState.x),\n );\n const lastVisibleStateIndex = this.states.findIndex((state) => state.x === lastVisibleState.x);\n\n return reversed\n ? this.states[lastVisibleStateIndex + 1]\n : this.states[firstVisibleStateIndex - 1];\n }\n\n /**\n * Get the visible slides for the given position.\n */\n getVisibleItems(target: number) {\n return this.$children.SliderItem.filter((item) => item.isVisible || item.willBeVisible(target));\n }\n\n /**\n * Get the invisible slides for the given position.\n */\n getInvisibleItems(target: number) {\n return this.$children.SliderItem.filter(\n (item) => !item.isVisible && !item.willBeVisible(target),\n );\n }\n}\n"],
|
|
5
|
-
"mappings": "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
|
|
4
|
+
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type {\n BaseProps,\n BaseConfig,\n DragServiceProps,\n KeyServiceProps,\n} from '@studiometa/js-toolkit';\nimport { clamp, inertiaFinalValue, nextFrame, isDev } from '@studiometa/js-toolkit/utils';\nimport { SliderDrag } from './SliderDrag.js';\nimport { SliderItem } from './SliderItem.js';\n\nexport type SliderModes = 'left' | 'center' | 'right';\n\ntype SliderState = { x: Record<SliderModes, number> };\n\nexport interface SliderProps extends BaseProps {\n $refs: {\n wrapper: HTMLElement;\n };\n $children: {\n SliderItem: SliderItem[];\n SliderDrag: SliderDrag[];\n };\n $options: {\n mode: SliderModes;\n fitBounds: boolean;\n contain: boolean;\n sensitivity: number;\n dropSensitivity: number;\n };\n}\n\n/**\n * Orchestrate the slider items state transition.\n * @todo a11y\n */\nexport class Slider<T extends BaseProps = BaseProps> extends Base<T & SliderProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Slider',\n refs: ['wrapper', 'debug'],\n emits: ['goto', 'index'],\n components: {\n SliderItem,\n SliderDrag,\n },\n options: {\n mode: { type: String, default: 'left' },\n fitBounds: Boolean,\n contain: Boolean,\n sensitivity: { type: Number, default: 1 },\n dropSensitivity: { type: Number, default: 2 },\n },\n };\n\n __distanceX = 0;\n\n __initialX = 0;\n\n /**\n * Index of the current active slide.\n */\n __currentIndex = 0;\n\n __isDragging = false;\n\n /**\n * Get the current index.\n */\n get currentIndex() {\n return this.__currentIndex;\n }\n\n /**\n * Set the current index and emit the `index` event.\n */\n set currentIndex(value: number) {\n this.currentSliderItem.disactivate();\n this.$emit('index', value);\n this.__currentIndex = value;\n this.currentSliderItem.activate();\n }\n\n /**\n * Store all the states.\n */\n states: SliderState[] = [];\n\n /**\n * Origins for the different modes.\n */\n origins: Record<SliderModes, number> = {\n left: 0,\n center: 0,\n right: 0,\n };\n\n /**\n * Wether or not the wrapper is focused.\n * @type {boolean}\n */\n hasFocus = false;\n\n /**\n * Get the current state.\n */\n get currentState() {\n return this.states[this.currentIndex];\n }\n\n /**\n * Get the first state.\n */\n get firstState() {\n return this.states[0];\n }\n\n /**\n * Get the last state.\n */\n get lastState() {\n return this.states.at(-1);\n }\n\n /**\n * Get the minimal contain state value.\n */\n get containMinState(): number {\n return this.getStateValueByMode(this.firstState.x, 'left');\n }\n\n /**\n * Get the maximal contain state value.\n */\n get containMaxState(): number {\n return this.getStateValueByMode(this.lastState.x, 'right');\n }\n\n /**\n * Get the last index.\n */\n get indexMax(): number {\n return this.$children.SliderItem.length - 1;\n }\n\n /**\n * Get the current SliderItem\n */\n get currentSliderItem() {\n return this.$children.SliderItem[this.currentIndex];\n }\n\n /**\n * Get the states for each SliderItem.\n */\n getStates(): SliderState[] {\n const { wrapper } = this.$refs;\n const originRect = wrapper.getBoundingClientRect();\n\n this.origins = {\n left: originRect.left,\n center: originRect.x + originRect.width / 2,\n right: originRect.x + originRect.width,\n };\n\n const states: SliderState[] = this.$children.SliderItem.map((item) => ({\n x: {\n left: (item.rect.x - this.origins.left) * -1,\n center: (item.rect.x + item.rect.width / 2 - this.origins.center) * -1,\n right: (item.rect.x + item.rect.width - this.origins.right) * -1,\n },\n }));\n\n if (this.$options.contain) {\n const { mode } = this.$options;\n // Find state where last child has passed the wrapper bound completely\n if (mode === 'left') {\n const lastChild = this.$children.SliderItem.at(-1);\n\n const maxState = states.find((state) => {\n const lastChildPosition =\n lastChild.rect.x - this.origins.left + lastChild.rect.width + state.x.left;\n const diffWithWrapperBound = originRect.width - lastChildPosition;\n if (diffWithWrapperBound > 0) {\n state.x.left = Math.min(state.x.left + diffWithWrapperBound, 0);\n return true;\n }\n\n return false;\n });\n\n if (maxState) {\n return states.map((state) => {\n state.x.left = Math.max(state.x.left, maxState.x.left);\n return state;\n });\n }\n }\n\n if (mode === 'right') {\n const maxStateIndex = states.findIndex((state) => state.x.right <= 0);\n const maxState = maxStateIndex < 0 ? states.at(-1) : states[maxStateIndex - 1];\n\n return states.map((state) => {\n state.x.right = maxStateIndex < 0 ? maxState.x.right : Math.min(state.x.right, 0);\n return state;\n });\n }\n\n if (mode === 'center' && isDev) {\n console.warn(\n `[${this.$id}]`,\n 'The `center` mode is not yet compatible with the `contain` mode.',\n );\n }\n }\n\n return states;\n }\n\n /**\n * Get an origin by mode.\n */\n getOriginByMode(mode?: SliderModes) {\n return this.origins[mode ?? this.$options.mode];\n }\n\n /**\n * Get a state value according to the given mode.\n */\n getStateValueByMode(state: SliderState['x'], mode?: SliderModes) {\n return state[mode ?? this.$options.mode];\n }\n\n /**\n * Mounted hook.\n */\n mounted() {\n this.states = this.getStates();\n this.setAccessibilityAttributes();\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n }\n\n /**\n * Resized hook.\n */\n resized() {\n nextFrame(() => {\n this.states = this.getStates();\n nextFrame(() => {\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n });\n });\n }\n\n /**\n * Set accessibility attributes for the component\n */\n setAccessibilityAttributes() {\n this.$el.setAttribute('role', 'group');\n this.$el.setAttribute('aria-roledescription', 'carousel');\n }\n\n /**\n * Go to the next slide.\n */\n goNext() {\n if (this.currentIndex + 1 > this.indexMax) {\n return;\n }\n\n this.goTo(this.currentIndex + 1);\n }\n\n /**\n * Go to the previous slide.\n */\n goPrev() {\n if (this.currentIndex - 1 < 0) {\n return;\n }\n\n this.goTo(this.currentIndex - 1);\n }\n\n /**\n * Go to the given index.\n */\n goTo(index: number, { withInstantMove = true } = {}) {\n if (index < 0 || index > this.indexMax) {\n throw new Error('Index out of bound.');\n }\n\n const currentState = this.getStateValueByMode(this.currentState.x);\n const state = this.getStateValueByMode(this.states[index].x);\n const itemsToMove = this.getVisibleItems(state);\n const invisibleItemsToMoveInstantly = this.getInvisibleItems(state);\n\n itemsToMove.forEach((item) => {\n // Better perfs when going fast through the slides\n if (currentState !== state && withInstantMove) {\n item.moveInstantly(currentState);\n }\n nextFrame(() => item.move(state));\n });\n invisibleItemsToMoveInstantly.forEach((item) => {\n item.moveInstantly(state);\n });\n\n this.currentIndex = index;\n this.$emit('goto', index);\n }\n\n /**\n * Listen to the Draggable `start` event.\n */\n onSliderDragStart() {\n this.__initialX = this.currentSliderItem ? this.currentSliderItem.x : 0;\n this.__distanceX = this.__initialX;\n\n this.__isDragging = true;\n }\n\n /**\n * Listen to the Draggable `drag` event.\n */\n onSliderDragDrag(props: DragServiceProps) {\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n this.__distanceX = this.__initialX + props.distance.x * this.$options.sensitivity;\n\n this.getVisibleItems(this.__distanceX).forEach((item) => {\n item.moveInstantly(this.__distanceX);\n });\n }\n\n /**\n * Listen to the Draggable `drop` event and find the new active slide.\n */\n onSliderDragDrop(props: DragServiceProps) {\n if (!this.__isDragging) {\n return;\n }\n this.__isDragging = false;\n\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n let finalX = clamp(\n inertiaFinalValue(this.__distanceX, props.delta.x * this.$options.dropSensitivity),\n this.getStateValueByMode(this.firstState.x),\n this.getStateValueByMode(this.lastState.x),\n );\n\n const absoluteDifferencesBetweenDistanceAndState = this.states.map((state) =>\n Math.abs(finalX - this.getStateValueByMode(state.x)),\n );\n const minimumDifference = Math.min(...absoluteDifferencesBetweenDistanceAndState);\n const closestIndex = absoluteDifferencesBetweenDistanceAndState.indexOf(minimumDifference);\n\n if (this.$options.fitBounds) {\n this.goTo(closestIndex, { withInstantMove: false });\n } else {\n if (this.$options.contain) {\n finalX = Math.min(this.containMinState, finalX);\n finalX = Math.max(this.containMaxState, finalX);\n }\n this.$children.SliderItem.forEach((item) => {\n item.move(finalX);\n });\n this.currentIndex = closestIndex;\n }\n }\n\n /**\n * Enable focus.\n */\n onWrapperFocus() {\n this.hasFocus = true;\n }\n\n /**\n * Disable focus.\n */\n onWrapperBlur() {\n this.hasFocus = false;\n }\n\n /**\n * Go prev or next when focus is on the wrapper and pressing arrow keys.\n */\n keyed({ LEFT, RIGHT, isDown }: KeyServiceProps) {\n if (this.hasFocus && isDown) {\n if (LEFT) {\n this.goPrev();\n } else if (RIGHT) {\n this.goNext();\n }\n }\n }\n\n /**\n * Prepare invisible items.\n */\n prepareInvisibleItems() {\n const state = this.states[this.currentIndex];\n const nextItemsToPrepare = [];\n const previousItemsToPrepare = [];\n\n this.getInvisibleItems(this.getStateValueByMode(state.x)).forEach((item, i) => {\n if (i > this.currentIndex) {\n nextItemsToPrepare.push(item);\n return;\n }\n\n if (i < this.currentIndex) {\n previousItemsToPrepare.push(item);\n }\n });\n\n nextItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item);\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n\n previousItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item, { reversed: true });\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n }\n\n /**\n * Get the state where the given item will be visible.\n */\n getStateWhereItemWillBeInvisible(item: SliderItem, { reversed = false } = {}): SliderState {\n const visibleStates = this.states.filter((state) =>\n item.willBeVisible(this.getStateValueByMode(state.x)),\n );\n const firstVisibleState = visibleStates[0];\n const lastVisibleState = visibleStates.at(-1);\n const firstVisibleStateIndex = this.states.findIndex(\n (state) =>\n this.getStateValueByMode(state.x) === this.getStateValueByMode(firstVisibleState.x),\n );\n const lastVisibleStateIndex = this.states.findIndex((state) => state.x === lastVisibleState.x);\n\n return reversed\n ? this.states[lastVisibleStateIndex + 1]\n : this.states[firstVisibleStateIndex - 1];\n }\n\n /**\n * Get the visible slides for the given position.\n */\n getVisibleItems(target: number) {\n return this.$children.SliderItem.filter((item) => item.isVisible || item.willBeVisible(target));\n }\n\n /**\n * Get the invisible slides for the given position.\n */\n getInvisibleItems(target: number) {\n return this.$children.SliderItem.filter(\n (item) => !item.isVisible && !item.willBeVisible(target),\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -107,6 +107,10 @@ export declare class Slider<T extends BaseProps = BaseProps> extends Base<T & Sl
|
|
|
107
107
|
* Resized hook.
|
|
108
108
|
*/
|
|
109
109
|
resized(): void;
|
|
110
|
+
/**
|
|
111
|
+
* Set accessibility attributes for the component
|
|
112
|
+
*/
|
|
113
|
+
setAccessibilityAttributes(): void;
|
|
110
114
|
/**
|
|
111
115
|
* Go to the next slide.
|
|
112
116
|
*/
|
|
@@ -175,6 +175,7 @@ class Slider extends Base {
|
|
|
175
175
|
*/
|
|
176
176
|
mounted() {
|
|
177
177
|
this.states = this.getStates();
|
|
178
|
+
this.setAccessibilityAttributes();
|
|
178
179
|
this.prepareInvisibleItems();
|
|
179
180
|
this.goTo(this.currentIndex);
|
|
180
181
|
}
|
|
@@ -190,6 +191,13 @@ class Slider extends Base {
|
|
|
190
191
|
});
|
|
191
192
|
});
|
|
192
193
|
}
|
|
194
|
+
/**
|
|
195
|
+
* Set accessibility attributes for the component
|
|
196
|
+
*/
|
|
197
|
+
setAccessibilityAttributes() {
|
|
198
|
+
this.$el.setAttribute("role", "group");
|
|
199
|
+
this.$el.setAttribute("aria-roledescription", "carousel");
|
|
200
|
+
}
|
|
193
201
|
/**
|
|
194
202
|
* Go to the next slide.
|
|
195
203
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/molecules/Slider/Slider.ts"],
|
|
4
|
-
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type {\n BaseProps,\n BaseConfig,\n DragServiceProps,\n KeyServiceProps,\n} from '@studiometa/js-toolkit';\nimport { clamp, inertiaFinalValue, nextFrame, isDev } from '@studiometa/js-toolkit/utils';\nimport { SliderDrag } from './SliderDrag.js';\nimport { SliderItem } from './SliderItem.js';\n\nexport type SliderModes = 'left' | 'center' | 'right';\n\ntype SliderState = { x: Record<SliderModes, number> };\n\nexport interface SliderProps extends BaseProps {\n $refs: {\n wrapper: HTMLElement;\n };\n $children: {\n SliderItem: SliderItem[];\n SliderDrag: SliderDrag[];\n };\n $options: {\n mode: SliderModes;\n fitBounds: boolean;\n contain: boolean;\n sensitivity: number;\n dropSensitivity: number;\n };\n}\n\n/**\n * Orchestrate the slider items state transition.\n * @todo a11y\n */\nexport class Slider<T extends BaseProps = BaseProps> extends Base<T & SliderProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Slider',\n refs: ['wrapper', 'debug'],\n emits: ['goto', 'index'],\n components: {\n SliderItem,\n SliderDrag,\n },\n options: {\n mode: { type: String, default: 'left' },\n fitBounds: Boolean,\n contain: Boolean,\n sensitivity: { type: Number, default: 1 },\n dropSensitivity: { type: Number, default: 2 },\n },\n };\n\n __distanceX = 0;\n\n __initialX = 0;\n\n /**\n * Index of the current active slide.\n */\n __currentIndex = 0;\n\n __isDragging = false;\n\n /**\n * Get the current index.\n */\n get currentIndex() {\n return this.__currentIndex;\n }\n\n /**\n * Set the current index and emit the `index` event.\n */\n set currentIndex(value: number) {\n this.currentSliderItem.disactivate();\n this.$emit('index', value);\n this.__currentIndex = value;\n this.currentSliderItem.activate();\n }\n\n /**\n * Store all the states.\n */\n states: SliderState[] = [];\n\n /**\n * Origins for the different modes.\n */\n origins: Record<SliderModes, number> = {\n left: 0,\n center: 0,\n right: 0,\n };\n\n /**\n * Wether or not the wrapper is focused.\n * @type {boolean}\n */\n hasFocus = false;\n\n /**\n * Get the current state.\n */\n get currentState() {\n return this.states[this.currentIndex];\n }\n\n /**\n * Get the first state.\n */\n get firstState() {\n return this.states[0];\n }\n\n /**\n * Get the last state.\n */\n get lastState() {\n return this.states.at(-1);\n }\n\n /**\n * Get the minimal contain state value.\n */\n get containMinState(): number {\n return this.getStateValueByMode(this.firstState.x, 'left');\n }\n\n /**\n * Get the maximal contain state value.\n */\n get containMaxState(): number {\n return this.getStateValueByMode(this.lastState.x, 'right');\n }\n\n /**\n * Get the last index.\n */\n get indexMax(): number {\n return this.$children.SliderItem.length - 1;\n }\n\n /**\n * Get the current SliderItem\n */\n get currentSliderItem() {\n return this.$children.SliderItem[this.currentIndex];\n }\n\n /**\n * Get the states for each SliderItem.\n */\n getStates(): SliderState[] {\n const { wrapper } = this.$refs;\n const originRect = wrapper.getBoundingClientRect();\n\n this.origins = {\n left: originRect.left,\n center: originRect.x + originRect.width / 2,\n right: originRect.x + originRect.width,\n };\n\n const states: SliderState[] = this.$children.SliderItem.map((item) => ({\n x: {\n left: (item.rect.x - this.origins.left) * -1,\n center: (item.rect.x + item.rect.width / 2 - this.origins.center) * -1,\n right: (item.rect.x + item.rect.width - this.origins.right) * -1,\n },\n }));\n\n if (this.$options.contain) {\n const { mode } = this.$options;\n // Find state where last child has passed the wrapper bound completely\n if (mode === 'left') {\n const lastChild = this.$children.SliderItem.at(-1);\n\n const maxState = states.find((state) => {\n const lastChildPosition =\n lastChild.rect.x - this.origins.left + lastChild.rect.width + state.x.left;\n const diffWithWrapperBound = originRect.width - lastChildPosition;\n if (diffWithWrapperBound > 0) {\n state.x.left = Math.min(state.x.left + diffWithWrapperBound, 0);\n return true;\n }\n\n return false;\n });\n\n if (maxState) {\n return states.map((state) => {\n state.x.left = Math.max(state.x.left, maxState.x.left);\n return state;\n });\n }\n }\n\n if (mode === 'right') {\n const maxStateIndex = states.findIndex((state) => state.x.right <= 0);\n const maxState = maxStateIndex < 0 ? states.at(-1) : states[maxStateIndex - 1];\n\n return states.map((state) => {\n state.x.right = maxStateIndex < 0 ? maxState.x.right : Math.min(state.x.right, 0);\n return state;\n });\n }\n\n if (mode === 'center' && isDev) {\n console.warn(\n `[${this.$id}]`,\n 'The `center` mode is not yet compatible with the `contain` mode.',\n );\n }\n }\n\n return states;\n }\n\n /**\n * Get an origin by mode.\n */\n getOriginByMode(mode?: SliderModes) {\n return this.origins[mode ?? this.$options.mode];\n }\n\n /**\n * Get a state value according to the given mode.\n */\n getStateValueByMode(state: SliderState['x'], mode?: SliderModes) {\n return state[mode ?? this.$options.mode];\n }\n\n /**\n * Mounted hook.\n */\n mounted() {\n this.states = this.getStates();\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n }\n\n /**\n * Resized hook.\n */\n resized() {\n nextFrame(() => {\n this.states = this.getStates();\n nextFrame(() => {\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n });\n });\n }\n\n /**\n * Go to the next slide.\n */\n goNext() {\n if (this.currentIndex + 1 > this.indexMax) {\n return;\n }\n\n this.goTo(this.currentIndex + 1);\n }\n\n /**\n * Go to the previous slide.\n */\n goPrev() {\n if (this.currentIndex - 1 < 0) {\n return;\n }\n\n this.goTo(this.currentIndex - 1);\n }\n\n /**\n * Go to the given index.\n */\n goTo(index: number, { withInstantMove = true } = {}) {\n if (index < 0 || index > this.indexMax) {\n throw new Error('Index out of bound.');\n }\n\n const currentState = this.getStateValueByMode(this.currentState.x);\n const state = this.getStateValueByMode(this.states[index].x);\n const itemsToMove = this.getVisibleItems(state);\n const invisibleItemsToMoveInstantly = this.getInvisibleItems(state);\n\n itemsToMove.forEach((item) => {\n // Better perfs when going fast through the slides\n if (currentState !== state && withInstantMove) {\n item.moveInstantly(currentState);\n }\n nextFrame(() => item.move(state));\n });\n invisibleItemsToMoveInstantly.forEach((item) => {\n item.moveInstantly(state);\n });\n\n this.currentIndex = index;\n this.$emit('goto', index);\n }\n\n /**\n * Listen to the Draggable `start` event.\n */\n onSliderDragStart() {\n this.__initialX = this.currentSliderItem ? this.currentSliderItem.x : 0;\n this.__distanceX = this.__initialX;\n\n this.__isDragging = true;\n }\n\n /**\n * Listen to the Draggable `drag` event.\n */\n onSliderDragDrag(props: DragServiceProps) {\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n this.__distanceX = this.__initialX + props.distance.x * this.$options.sensitivity;\n\n this.getVisibleItems(this.__distanceX).forEach((item) => {\n item.moveInstantly(this.__distanceX);\n });\n }\n\n /**\n * Listen to the Draggable `drop` event and find the new active slide.\n */\n onSliderDragDrop(props: DragServiceProps) {\n if (!this.__isDragging) {\n return;\n }\n this.__isDragging = false;\n\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n let finalX = clamp(\n inertiaFinalValue(this.__distanceX, props.delta.x * this.$options.dropSensitivity),\n this.getStateValueByMode(this.firstState.x),\n this.getStateValueByMode(this.lastState.x),\n );\n\n const absoluteDifferencesBetweenDistanceAndState = this.states.map((state) =>\n Math.abs(finalX - this.getStateValueByMode(state.x)),\n );\n const minimumDifference = Math.min(...absoluteDifferencesBetweenDistanceAndState);\n const closestIndex = absoluteDifferencesBetweenDistanceAndState.indexOf(minimumDifference);\n\n if (this.$options.fitBounds) {\n this.goTo(closestIndex, { withInstantMove: false });\n } else {\n if (this.$options.contain) {\n finalX = Math.min(this.containMinState, finalX);\n finalX = Math.max(this.containMaxState, finalX);\n }\n this.$children.SliderItem.forEach((item) => {\n item.move(finalX);\n });\n this.currentIndex = closestIndex;\n }\n }\n\n /**\n * Enable focus.\n */\n onWrapperFocus() {\n this.hasFocus = true;\n }\n\n /**\n * Disable focus.\n */\n onWrapperBlur() {\n this.hasFocus = false;\n }\n\n /**\n * Go prev or next when focus is on the wrapper and pressing arrow keys.\n */\n keyed({ LEFT, RIGHT, isDown }: KeyServiceProps) {\n if (this.hasFocus && isDown) {\n if (LEFT) {\n this.goPrev();\n } else if (RIGHT) {\n this.goNext();\n }\n }\n }\n\n /**\n * Prepare invisible items.\n */\n prepareInvisibleItems() {\n const state = this.states[this.currentIndex];\n const nextItemsToPrepare = [];\n const previousItemsToPrepare = [];\n\n this.getInvisibleItems(this.getStateValueByMode(state.x)).forEach((item, i) => {\n if (i > this.currentIndex) {\n nextItemsToPrepare.push(item);\n return;\n }\n\n if (i < this.currentIndex) {\n previousItemsToPrepare.push(item);\n }\n });\n\n nextItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item);\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n\n previousItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item, { reversed: true });\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n }\n\n /**\n * Get the state where the given item will be visible.\n */\n getStateWhereItemWillBeInvisible(item: SliderItem, { reversed = false } = {}): SliderState {\n const visibleStates = this.states.filter((state) =>\n item.willBeVisible(this.getStateValueByMode(state.x)),\n );\n const firstVisibleState = visibleStates[0];\n const lastVisibleState = visibleStates.at(-1);\n const firstVisibleStateIndex = this.states.findIndex(\n (state) =>\n this.getStateValueByMode(state.x) === this.getStateValueByMode(firstVisibleState.x),\n );\n const lastVisibleStateIndex = this.states.findIndex((state) => state.x === lastVisibleState.x);\n\n return reversed\n ? this.states[lastVisibleStateIndex + 1]\n : this.states[firstVisibleStateIndex - 1];\n }\n\n /**\n * Get the visible slides for the given position.\n */\n getVisibleItems(target: number) {\n return this.$children.SliderItem.filter((item) => item.isVisible || item.willBeVisible(target));\n }\n\n /**\n * Get the invisible slides for the given position.\n */\n getInvisibleItems(target: number) {\n return this.$children.SliderItem.filter(\n (item) => !item.isVisible && !item.willBeVisible(target),\n );\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import { Base } from '@studiometa/js-toolkit';\nimport type {\n BaseProps,\n BaseConfig,\n DragServiceProps,\n KeyServiceProps,\n} from '@studiometa/js-toolkit';\nimport { clamp, inertiaFinalValue, nextFrame, isDev } from '@studiometa/js-toolkit/utils';\nimport { SliderDrag } from './SliderDrag.js';\nimport { SliderItem } from './SliderItem.js';\n\nexport type SliderModes = 'left' | 'center' | 'right';\n\ntype SliderState = { x: Record<SliderModes, number> };\n\nexport interface SliderProps extends BaseProps {\n $refs: {\n wrapper: HTMLElement;\n };\n $children: {\n SliderItem: SliderItem[];\n SliderDrag: SliderDrag[];\n };\n $options: {\n mode: SliderModes;\n fitBounds: boolean;\n contain: boolean;\n sensitivity: number;\n dropSensitivity: number;\n };\n}\n\n/**\n * Orchestrate the slider items state transition.\n * @todo a11y\n */\nexport class Slider<T extends BaseProps = BaseProps> extends Base<T & SliderProps> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'Slider',\n refs: ['wrapper', 'debug'],\n emits: ['goto', 'index'],\n components: {\n SliderItem,\n SliderDrag,\n },\n options: {\n mode: { type: String, default: 'left' },\n fitBounds: Boolean,\n contain: Boolean,\n sensitivity: { type: Number, default: 1 },\n dropSensitivity: { type: Number, default: 2 },\n },\n };\n\n __distanceX = 0;\n\n __initialX = 0;\n\n /**\n * Index of the current active slide.\n */\n __currentIndex = 0;\n\n __isDragging = false;\n\n /**\n * Get the current index.\n */\n get currentIndex() {\n return this.__currentIndex;\n }\n\n /**\n * Set the current index and emit the `index` event.\n */\n set currentIndex(value: number) {\n this.currentSliderItem.disactivate();\n this.$emit('index', value);\n this.__currentIndex = value;\n this.currentSliderItem.activate();\n }\n\n /**\n * Store all the states.\n */\n states: SliderState[] = [];\n\n /**\n * Origins for the different modes.\n */\n origins: Record<SliderModes, number> = {\n left: 0,\n center: 0,\n right: 0,\n };\n\n /**\n * Wether or not the wrapper is focused.\n * @type {boolean}\n */\n hasFocus = false;\n\n /**\n * Get the current state.\n */\n get currentState() {\n return this.states[this.currentIndex];\n }\n\n /**\n * Get the first state.\n */\n get firstState() {\n return this.states[0];\n }\n\n /**\n * Get the last state.\n */\n get lastState() {\n return this.states.at(-1);\n }\n\n /**\n * Get the minimal contain state value.\n */\n get containMinState(): number {\n return this.getStateValueByMode(this.firstState.x, 'left');\n }\n\n /**\n * Get the maximal contain state value.\n */\n get containMaxState(): number {\n return this.getStateValueByMode(this.lastState.x, 'right');\n }\n\n /**\n * Get the last index.\n */\n get indexMax(): number {\n return this.$children.SliderItem.length - 1;\n }\n\n /**\n * Get the current SliderItem\n */\n get currentSliderItem() {\n return this.$children.SliderItem[this.currentIndex];\n }\n\n /**\n * Get the states for each SliderItem.\n */\n getStates(): SliderState[] {\n const { wrapper } = this.$refs;\n const originRect = wrapper.getBoundingClientRect();\n\n this.origins = {\n left: originRect.left,\n center: originRect.x + originRect.width / 2,\n right: originRect.x + originRect.width,\n };\n\n const states: SliderState[] = this.$children.SliderItem.map((item) => ({\n x: {\n left: (item.rect.x - this.origins.left) * -1,\n center: (item.rect.x + item.rect.width / 2 - this.origins.center) * -1,\n right: (item.rect.x + item.rect.width - this.origins.right) * -1,\n },\n }));\n\n if (this.$options.contain) {\n const { mode } = this.$options;\n // Find state where last child has passed the wrapper bound completely\n if (mode === 'left') {\n const lastChild = this.$children.SliderItem.at(-1);\n\n const maxState = states.find((state) => {\n const lastChildPosition =\n lastChild.rect.x - this.origins.left + lastChild.rect.width + state.x.left;\n const diffWithWrapperBound = originRect.width - lastChildPosition;\n if (diffWithWrapperBound > 0) {\n state.x.left = Math.min(state.x.left + diffWithWrapperBound, 0);\n return true;\n }\n\n return false;\n });\n\n if (maxState) {\n return states.map((state) => {\n state.x.left = Math.max(state.x.left, maxState.x.left);\n return state;\n });\n }\n }\n\n if (mode === 'right') {\n const maxStateIndex = states.findIndex((state) => state.x.right <= 0);\n const maxState = maxStateIndex < 0 ? states.at(-1) : states[maxStateIndex - 1];\n\n return states.map((state) => {\n state.x.right = maxStateIndex < 0 ? maxState.x.right : Math.min(state.x.right, 0);\n return state;\n });\n }\n\n if (mode === 'center' && isDev) {\n console.warn(\n `[${this.$id}]`,\n 'The `center` mode is not yet compatible with the `contain` mode.',\n );\n }\n }\n\n return states;\n }\n\n /**\n * Get an origin by mode.\n */\n getOriginByMode(mode?: SliderModes) {\n return this.origins[mode ?? this.$options.mode];\n }\n\n /**\n * Get a state value according to the given mode.\n */\n getStateValueByMode(state: SliderState['x'], mode?: SliderModes) {\n return state[mode ?? this.$options.mode];\n }\n\n /**\n * Mounted hook.\n */\n mounted() {\n this.states = this.getStates();\n this.setAccessibilityAttributes();\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n }\n\n /**\n * Resized hook.\n */\n resized() {\n nextFrame(() => {\n this.states = this.getStates();\n nextFrame(() => {\n this.prepareInvisibleItems();\n this.goTo(this.currentIndex);\n });\n });\n }\n\n /**\n * Set accessibility attributes for the component\n */\n setAccessibilityAttributes() {\n this.$el.setAttribute('role', 'group');\n this.$el.setAttribute('aria-roledescription', 'carousel');\n }\n\n /**\n * Go to the next slide.\n */\n goNext() {\n if (this.currentIndex + 1 > this.indexMax) {\n return;\n }\n\n this.goTo(this.currentIndex + 1);\n }\n\n /**\n * Go to the previous slide.\n */\n goPrev() {\n if (this.currentIndex - 1 < 0) {\n return;\n }\n\n this.goTo(this.currentIndex - 1);\n }\n\n /**\n * Go to the given index.\n */\n goTo(index: number, { withInstantMove = true } = {}) {\n if (index < 0 || index > this.indexMax) {\n throw new Error('Index out of bound.');\n }\n\n const currentState = this.getStateValueByMode(this.currentState.x);\n const state = this.getStateValueByMode(this.states[index].x);\n const itemsToMove = this.getVisibleItems(state);\n const invisibleItemsToMoveInstantly = this.getInvisibleItems(state);\n\n itemsToMove.forEach((item) => {\n // Better perfs when going fast through the slides\n if (currentState !== state && withInstantMove) {\n item.moveInstantly(currentState);\n }\n nextFrame(() => item.move(state));\n });\n invisibleItemsToMoveInstantly.forEach((item) => {\n item.moveInstantly(state);\n });\n\n this.currentIndex = index;\n this.$emit('goto', index);\n }\n\n /**\n * Listen to the Draggable `start` event.\n */\n onSliderDragStart() {\n this.__initialX = this.currentSliderItem ? this.currentSliderItem.x : 0;\n this.__distanceX = this.__initialX;\n\n this.__isDragging = true;\n }\n\n /**\n * Listen to the Draggable `drag` event.\n */\n onSliderDragDrag(props: DragServiceProps) {\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n this.__distanceX = this.__initialX + props.distance.x * this.$options.sensitivity;\n\n this.getVisibleItems(this.__distanceX).forEach((item) => {\n item.moveInstantly(this.__distanceX);\n });\n }\n\n /**\n * Listen to the Draggable `drop` event and find the new active slide.\n */\n onSliderDragDrop(props: DragServiceProps) {\n if (!this.__isDragging) {\n return;\n }\n this.__isDragging = false;\n\n if (Math.abs(props.delta.y) > Math.abs(props.delta.x)) {\n return;\n }\n\n let finalX = clamp(\n inertiaFinalValue(this.__distanceX, props.delta.x * this.$options.dropSensitivity),\n this.getStateValueByMode(this.firstState.x),\n this.getStateValueByMode(this.lastState.x),\n );\n\n const absoluteDifferencesBetweenDistanceAndState = this.states.map((state) =>\n Math.abs(finalX - this.getStateValueByMode(state.x)),\n );\n const minimumDifference = Math.min(...absoluteDifferencesBetweenDistanceAndState);\n const closestIndex = absoluteDifferencesBetweenDistanceAndState.indexOf(minimumDifference);\n\n if (this.$options.fitBounds) {\n this.goTo(closestIndex, { withInstantMove: false });\n } else {\n if (this.$options.contain) {\n finalX = Math.min(this.containMinState, finalX);\n finalX = Math.max(this.containMaxState, finalX);\n }\n this.$children.SliderItem.forEach((item) => {\n item.move(finalX);\n });\n this.currentIndex = closestIndex;\n }\n }\n\n /**\n * Enable focus.\n */\n onWrapperFocus() {\n this.hasFocus = true;\n }\n\n /**\n * Disable focus.\n */\n onWrapperBlur() {\n this.hasFocus = false;\n }\n\n /**\n * Go prev or next when focus is on the wrapper and pressing arrow keys.\n */\n keyed({ LEFT, RIGHT, isDown }: KeyServiceProps) {\n if (this.hasFocus && isDown) {\n if (LEFT) {\n this.goPrev();\n } else if (RIGHT) {\n this.goNext();\n }\n }\n }\n\n /**\n * Prepare invisible items.\n */\n prepareInvisibleItems() {\n const state = this.states[this.currentIndex];\n const nextItemsToPrepare = [];\n const previousItemsToPrepare = [];\n\n this.getInvisibleItems(this.getStateValueByMode(state.x)).forEach((item, i) => {\n if (i > this.currentIndex) {\n nextItemsToPrepare.push(item);\n return;\n }\n\n if (i < this.currentIndex) {\n previousItemsToPrepare.push(item);\n }\n });\n\n nextItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item);\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n\n previousItemsToPrepare.forEach((item) => {\n const invisibleState = this.getStateWhereItemWillBeInvisible(item, { reversed: true });\n if (invisibleState) {\n item.moveInstantly(this.getStateValueByMode(invisibleState.x));\n }\n });\n }\n\n /**\n * Get the state where the given item will be visible.\n */\n getStateWhereItemWillBeInvisible(item: SliderItem, { reversed = false } = {}): SliderState {\n const visibleStates = this.states.filter((state) =>\n item.willBeVisible(this.getStateValueByMode(state.x)),\n );\n const firstVisibleState = visibleStates[0];\n const lastVisibleState = visibleStates.at(-1);\n const firstVisibleStateIndex = this.states.findIndex(\n (state) =>\n this.getStateValueByMode(state.x) === this.getStateValueByMode(firstVisibleState.x),\n );\n const lastVisibleStateIndex = this.states.findIndex((state) => state.x === lastVisibleState.x);\n\n return reversed\n ? this.states[lastVisibleStateIndex + 1]\n : this.states[firstVisibleStateIndex - 1];\n }\n\n /**\n * Get the visible slides for the given position.\n */\n getVisibleItems(target: number) {\n return this.$children.SliderItem.filter((item) => item.isVisible || item.willBeVisible(target));\n }\n\n /**\n * Get the invisible slides for the given position.\n */\n getInvisibleItems(target: number) {\n return this.$children.SliderItem.filter(\n (item) => !item.isVisible && !item.willBeVisible(target),\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -66,6 +66,12 @@ var SliderItem = class extends (0, import_js_toolkit.withIntersectionObserver)(i
|
|
|
66
66
|
}
|
|
67
67
|
return this.__rect;
|
|
68
68
|
}
|
|
69
|
+
/**
|
|
70
|
+
* Mounted hook
|
|
71
|
+
*/
|
|
72
|
+
mounted() {
|
|
73
|
+
this.setAccessibilityAttributes();
|
|
74
|
+
}
|
|
69
75
|
/**
|
|
70
76
|
* Update SliderItem bounding rectangle on resize.
|
|
71
77
|
*/
|
|
@@ -84,13 +90,10 @@ var SliderItem = class extends (0, import_js_toolkit.withIntersectionObserver)(i
|
|
|
84
90
|
intersected([{ intersectionRatio, isIntersecting }]) {
|
|
85
91
|
if (intersectionRatio >= 1) {
|
|
86
92
|
this.$emit("is-fully-visible");
|
|
87
|
-
this.$el.setAttribute("aria-hidden", "false");
|
|
88
93
|
} else if (intersectionRatio > 0) {
|
|
89
94
|
this.$emit("is-partially-visible");
|
|
90
|
-
this.$el.setAttribute("aria-hidden", "true");
|
|
91
95
|
} else {
|
|
92
96
|
this.$emit("is-hidden");
|
|
93
|
-
this.$el.setAttribute("aria-hidden", "true");
|
|
94
97
|
}
|
|
95
98
|
this.isVisible = isIntersecting;
|
|
96
99
|
}
|
|
@@ -108,6 +111,14 @@ var SliderItem = class extends (0, import_js_toolkit.withIntersectionObserver)(i
|
|
|
108
111
|
this.$services.disable("ticked");
|
|
109
112
|
}
|
|
110
113
|
}
|
|
114
|
+
/**
|
|
115
|
+
* Set accessibility attributes for the component
|
|
116
|
+
*/
|
|
117
|
+
setAccessibilityAttributes() {
|
|
118
|
+
this.$el.setAttribute("role", "group");
|
|
119
|
+
this.$el.setAttribute("aria-roledescription", "slide");
|
|
120
|
+
this.$el.setAttribute("aria-label", this.$id);
|
|
121
|
+
}
|
|
111
122
|
/**
|
|
112
123
|
* Enable the SliderItem.
|
|
113
124
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/molecules/Slider/SliderItem.ts"],
|
|
4
|
-
"sourcesContent": ["import { Base, withIntersectionObserver } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { damp, domScheduler, transform } from '@studiometa/js-toolkit/utils';\n\n/**\n * Manage a slider item and its state transition.\n */\nexport class SliderItem<T extends BaseProps = BaseProps> extends withIntersectionObserver(Base, {\n threshold: [0, 1],\n})<T> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'SliderItem',\n emits: ['is-fully-visible', 'is-partially-visible', 'is-hidden'],\n };\n\n /**\n * Wether the SliderItem is visible or not.\n * @type {boolean}\n */\n isVisible = false;\n\n /**\n * The SliderItem `x` position.\n * @type {number}\n */\n x = 0;\n\n /**\n * The smoothed `x` position.\n * @type {number}\n */\n dampedX = 0;\n\n /**\n * Item original position.\n */\n __rect: {\n x: number;\n y: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n width: number;\n height: number;\n };\n\n shouldEvaluateRect = false;\n\n get rect() {\n if (!this.__rect || this.shouldEvaluateRect) {\n this.shouldEvaluateRect = false;\n const x = this.x * -1;\n const rect = this.$el.getBoundingClientRect().toJSON();\n this.__rect = {\n ...rect,\n left: rect.left + x,\n right: rect.left + x + rect.width,\n x: rect.left + x,\n };\n }\n\n return this.__rect;\n }\n\n /**\n * Update SliderItem bounding rectangle on resize.\n */\n resized() {\n this.shouldEvaluateRect = true;\n }\n\n /**\n * Reset position to `0` on destroy.\n */\n destroyed() {\n this.moveInstantly(0);\n }\n\n /**\n * Intersected hook.\n */\n intersected([{ intersectionRatio, isIntersecting }]: IntersectionObserverEntry[]) {\n if (intersectionRatio >= 1) {\n this.$emit('is-fully-visible');\n
|
|
5
|
-
"mappings": ";;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wBAA+C;AAE/C,mBAA8C;AAKvC,IAAM,aAAN,kBAA0D,4CAAyB,wBAAM;AAAA,EAC9F,WAAW,CAAC,GAAG,CAAC;AAClB,CAAC,EAAK;AAAA;AAAA;AAAA;AAAA;AAAA,EAaJ,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAMJ,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV;AAAA,EAWA,qBAAqB;AAAA,EAErB,IAAI,OAAO;AACT,QAAI,CAAC,KAAK,UAAU,KAAK,oBAAoB;AAC3C,WAAK,qBAAqB;AAC1B,YAAM,IAAI,KAAK,IAAI;AACnB,YAAM,OAAO,KAAK,IAAI,sBAAsB,EAAE,OAAO;AACrD,WAAK,SAAS;AAAA,QACZ,GAAG;AAAA,QACH,MAAM,KAAK,OAAO;AAAA,QAClB,OAAO,KAAK,OAAO,IAAI,KAAK;AAAA,QAC5B,GAAG,KAAK,OAAO;AAAA,MACjB;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACR,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,SAAK,cAAc,CAAC;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,CAAC,EAAE,mBAAmB,eAAe,CAAC,GAAgC;AAChF,QAAI,qBAAqB,GAAG;AAC1B,WAAK,MAAM,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { Base, withIntersectionObserver } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { damp, domScheduler, transform } from '@studiometa/js-toolkit/utils';\n\n/**\n * Manage a slider item and its state transition.\n */\nexport class SliderItem<T extends BaseProps = BaseProps> extends withIntersectionObserver(Base, {\n threshold: [0, 1],\n})<T> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'SliderItem',\n emits: ['is-fully-visible', 'is-partially-visible', 'is-hidden'],\n };\n\n /**\n * Wether the SliderItem is visible or not.\n * @type {boolean}\n */\n isVisible = false;\n\n /**\n * The SliderItem `x` position.\n * @type {number}\n */\n x = 0;\n\n /**\n * The smoothed `x` position.\n * @type {number}\n */\n dampedX = 0;\n\n /**\n * Item original position.\n */\n __rect: {\n x: number;\n y: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n width: number;\n height: number;\n };\n\n shouldEvaluateRect = false;\n\n get rect() {\n if (!this.__rect || this.shouldEvaluateRect) {\n this.shouldEvaluateRect = false;\n const x = this.x * -1;\n const rect = this.$el.getBoundingClientRect().toJSON();\n this.__rect = {\n ...rect,\n left: rect.left + x,\n right: rect.left + x + rect.width,\n x: rect.left + x,\n };\n }\n\n return this.__rect;\n }\n\n /**\n * Mounted hook\n */\n mounted() {\n this.setAccessibilityAttributes();\n }\n\n /**\n * Update SliderItem bounding rectangle on resize.\n */\n resized() {\n this.shouldEvaluateRect = true;\n }\n\n /**\n * Reset position to `0` on destroy.\n */\n destroyed() {\n this.moveInstantly(0);\n }\n\n /**\n * Intersected hook.\n */\n intersected([{ intersectionRatio, isIntersecting }]: IntersectionObserverEntry[]) {\n if (intersectionRatio >= 1) {\n this.$emit('is-fully-visible');\n } else if (intersectionRatio > 0) {\n this.$emit('is-partially-visible');\n } else {\n this.$emit('is-hidden');\n }\n\n this.isVisible = isIntersecting;\n }\n\n /**\n * Ticked hook.\n * @todo create AbstractSliderItem with `render` method\n * @todo add state to SliderItem\n * @todo add origin to SliderItem\n * @returns {void}\n */\n ticked() {\n this.dampedX = damp(this.x, this.dampedX, 0.1, 0.00001);\n this.render();\n\n if (this.dampedX === this.x) {\n this.$services.disable('ticked');\n }\n }\n\n /**\n * Set accessibility attributes for the component\n */\n setAccessibilityAttributes() {\n this.$el.setAttribute('role', 'group');\n this.$el.setAttribute('aria-roledescription', 'slide');\n this.$el.setAttribute('aria-label', this.$id);\n }\n\n /**\n * Enable the SliderItem.\n */\n activate() {\n this.$el.classList.add('is-active');\n }\n\n /**\n * Disable the SliderItem.\n */\n disactivate() {\n this.$el.classList.remove('is-active');\n }\n\n /**\n * Move the SliderItem to the given target position.\n */\n move(targetPosition: number) {\n this.x = targetPosition;\n\n if (!this.$services.has('ticked')) {\n this.$services.enable('ticked');\n }\n }\n\n /**\n * Move the SliderItem instantly to the given target position.\n */\n moveInstantly(targetPosition: number) {\n this.x = targetPosition;\n this.dampedX = targetPosition;\n this.render();\n }\n\n /**\n * Render the component.\n */\n render() {\n domScheduler.write(() => {\n transform(this.$el, { x: this.dampedX });\n });\n }\n\n /**\n * Check if SliderItem is partially visible for the given target position.\n */\n willBeVisible(targetPosition: number) {\n return (\n this.rect.x + targetPosition < window.innerWidth * 1.5 &&\n this.rect.x + targetPosition + this.rect.width > window.innerWidth * -0.5\n );\n }\n\n /**\n * Check if SliderItem is fully visible for the given target position.\n * @param {number} targetPosition\n * @returns {boolean}\n */\n willBeFullyVisible(targetPosition) {\n return (\n this.rect.x + targetPosition < window.innerWidth &&\n this.rect.x + targetPosition > 0 &&\n this.rect.x + targetPosition + this.rect.width < window.innerWidth &&\n this.rect.x + targetPosition + this.rect.width > 0\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -48,6 +48,10 @@ export declare class SliderItem<T extends BaseProps = BaseProps> extends SliderI
|
|
|
48
48
|
width: number;
|
|
49
49
|
height: number;
|
|
50
50
|
};
|
|
51
|
+
/**
|
|
52
|
+
* Mounted hook
|
|
53
|
+
*/
|
|
54
|
+
mounted(): void;
|
|
51
55
|
/**
|
|
52
56
|
* Update SliderItem bounding rectangle on resize.
|
|
53
57
|
*/
|
|
@@ -68,6 +72,10 @@ export declare class SliderItem<T extends BaseProps = BaseProps> extends SliderI
|
|
|
68
72
|
* @returns {void}
|
|
69
73
|
*/
|
|
70
74
|
ticked(): void;
|
|
75
|
+
/**
|
|
76
|
+
* Set accessibility attributes for the component
|
|
77
|
+
*/
|
|
78
|
+
setAccessibilityAttributes(): void;
|
|
71
79
|
/**
|
|
72
80
|
* Enable the SliderItem.
|
|
73
81
|
*/
|
|
@@ -44,6 +44,12 @@ class SliderItem extends withIntersectionObserver(Base, {
|
|
|
44
44
|
}
|
|
45
45
|
return this.__rect;
|
|
46
46
|
}
|
|
47
|
+
/**
|
|
48
|
+
* Mounted hook
|
|
49
|
+
*/
|
|
50
|
+
mounted() {
|
|
51
|
+
this.setAccessibilityAttributes();
|
|
52
|
+
}
|
|
47
53
|
/**
|
|
48
54
|
* Update SliderItem bounding rectangle on resize.
|
|
49
55
|
*/
|
|
@@ -62,13 +68,10 @@ class SliderItem extends withIntersectionObserver(Base, {
|
|
|
62
68
|
intersected([{ intersectionRatio, isIntersecting }]) {
|
|
63
69
|
if (intersectionRatio >= 1) {
|
|
64
70
|
this.$emit("is-fully-visible");
|
|
65
|
-
this.$el.setAttribute("aria-hidden", "false");
|
|
66
71
|
} else if (intersectionRatio > 0) {
|
|
67
72
|
this.$emit("is-partially-visible");
|
|
68
|
-
this.$el.setAttribute("aria-hidden", "true");
|
|
69
73
|
} else {
|
|
70
74
|
this.$emit("is-hidden");
|
|
71
|
-
this.$el.setAttribute("aria-hidden", "true");
|
|
72
75
|
}
|
|
73
76
|
this.isVisible = isIntersecting;
|
|
74
77
|
}
|
|
@@ -86,6 +89,14 @@ class SliderItem extends withIntersectionObserver(Base, {
|
|
|
86
89
|
this.$services.disable("ticked");
|
|
87
90
|
}
|
|
88
91
|
}
|
|
92
|
+
/**
|
|
93
|
+
* Set accessibility attributes for the component
|
|
94
|
+
*/
|
|
95
|
+
setAccessibilityAttributes() {
|
|
96
|
+
this.$el.setAttribute("role", "group");
|
|
97
|
+
this.$el.setAttribute("aria-roledescription", "slide");
|
|
98
|
+
this.$el.setAttribute("aria-label", this.$id);
|
|
99
|
+
}
|
|
89
100
|
/**
|
|
90
101
|
* Enable the SliderItem.
|
|
91
102
|
*/
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../packages/ui/molecules/Slider/SliderItem.ts"],
|
|
4
|
-
"sourcesContent": ["import { Base, withIntersectionObserver } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { damp, domScheduler, transform } from '@studiometa/js-toolkit/utils';\n\n/**\n * Manage a slider item and its state transition.\n */\nexport class SliderItem<T extends BaseProps = BaseProps> extends withIntersectionObserver(Base, {\n threshold: [0, 1],\n})<T> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'SliderItem',\n emits: ['is-fully-visible', 'is-partially-visible', 'is-hidden'],\n };\n\n /**\n * Wether the SliderItem is visible or not.\n * @type {boolean}\n */\n isVisible = false;\n\n /**\n * The SliderItem `x` position.\n * @type {number}\n */\n x = 0;\n\n /**\n * The smoothed `x` position.\n * @type {number}\n */\n dampedX = 0;\n\n /**\n * Item original position.\n */\n __rect: {\n x: number;\n y: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n width: number;\n height: number;\n };\n\n shouldEvaluateRect = false;\n\n get rect() {\n if (!this.__rect || this.shouldEvaluateRect) {\n this.shouldEvaluateRect = false;\n const x = this.x * -1;\n const rect = this.$el.getBoundingClientRect().toJSON();\n this.__rect = {\n ...rect,\n left: rect.left + x,\n right: rect.left + x + rect.width,\n x: rect.left + x,\n };\n }\n\n return this.__rect;\n }\n\n /**\n * Update SliderItem bounding rectangle on resize.\n */\n resized() {\n this.shouldEvaluateRect = true;\n }\n\n /**\n * Reset position to `0` on destroy.\n */\n destroyed() {\n this.moveInstantly(0);\n }\n\n /**\n * Intersected hook.\n */\n intersected([{ intersectionRatio, isIntersecting }]: IntersectionObserverEntry[]) {\n if (intersectionRatio >= 1) {\n this.$emit('is-fully-visible');\n
|
|
5
|
-
"mappings": "AAAA,SAAS,MAAM,gCAAgC;AAE/C,SAAS,MAAM,cAAc,iBAAiB;AAKvC,MAAM,mBAAoD,yBAAyB,MAAM;AAAA,EAC9F,WAAW,CAAC,GAAG,CAAC;AAClB,CAAC,EAAK;AAAA;AAAA;AAAA;AAAA,EAIJ,OAAO,SAAqB;AAAA,IAC1B,MAAM;AAAA,IACN,OAAO,CAAC,oBAAoB,wBAAwB,WAAW;AAAA,EACjE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA,EAMZ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA,EAMJ,UAAU;AAAA;AAAA;AAAA;AAAA,EAKV;AAAA,EAWA,qBAAqB;AAAA,EAErB,IAAI,OAAO;AACT,QAAI,CAAC,KAAK,UAAU,KAAK,oBAAoB;AAC3C,WAAK,qBAAqB;AAC1B,YAAM,IAAI,KAAK,IAAI;AACnB,YAAM,OAAO,KAAK,IAAI,sBAAsB,EAAE,OAAO;AACrD,WAAK,SAAS;AAAA,QACZ,GAAG;AAAA,QACH,MAAM,KAAK,OAAO;AAAA,QAClB,OAAO,KAAK,OAAO,IAAI,KAAK;AAAA,QAC5B,GAAG,KAAK,OAAO;AAAA,MACjB;AAAA,IACF;AAEA,WAAO,KAAK;AAAA,EACd;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU;AACR,SAAK,qBAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY;AACV,SAAK,cAAc,CAAC;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,YAAY,CAAC,EAAE,mBAAmB,eAAe,CAAC,GAAgC;AAChF,QAAI,qBAAqB,GAAG;AAC1B,WAAK,MAAM,kBAAkB;
|
|
4
|
+
"sourcesContent": ["import { Base, withIntersectionObserver } from '@studiometa/js-toolkit';\nimport type { BaseProps, BaseConfig } from '@studiometa/js-toolkit';\nimport { damp, domScheduler, transform } from '@studiometa/js-toolkit/utils';\n\n/**\n * Manage a slider item and its state transition.\n */\nexport class SliderItem<T extends BaseProps = BaseProps> extends withIntersectionObserver(Base, {\n threshold: [0, 1],\n})<T> {\n /**\n * Config.\n */\n static config: BaseConfig = {\n name: 'SliderItem',\n emits: ['is-fully-visible', 'is-partially-visible', 'is-hidden'],\n };\n\n /**\n * Wether the SliderItem is visible or not.\n * @type {boolean}\n */\n isVisible = false;\n\n /**\n * The SliderItem `x` position.\n * @type {number}\n */\n x = 0;\n\n /**\n * The smoothed `x` position.\n * @type {number}\n */\n dampedX = 0;\n\n /**\n * Item original position.\n */\n __rect: {\n x: number;\n y: number;\n top: number;\n right: number;\n bottom: number;\n left: number;\n width: number;\n height: number;\n };\n\n shouldEvaluateRect = false;\n\n get rect() {\n if (!this.__rect || this.shouldEvaluateRect) {\n this.shouldEvaluateRect = false;\n const x = this.x * -1;\n const rect = this.$el.getBoundingClientRect().toJSON();\n this.__rect = {\n ...rect,\n left: rect.left + x,\n right: rect.left + x + rect.width,\n x: rect.left + x,\n };\n }\n\n return this.__rect;\n }\n\n /**\n * Mounted hook\n */\n mounted() {\n this.setAccessibilityAttributes();\n }\n\n /**\n * Update SliderItem bounding rectangle on resize.\n */\n resized() {\n this.shouldEvaluateRect = true;\n }\n\n /**\n * Reset position to `0` on destroy.\n */\n destroyed() {\n this.moveInstantly(0);\n }\n\n /**\n * Intersected hook.\n */\n intersected([{ intersectionRatio, isIntersecting }]: IntersectionObserverEntry[]) {\n if (intersectionRatio >= 1) {\n this.$emit('is-fully-visible');\n } else if (intersectionRatio > 0) {\n this.$emit('is-partially-visible');\n } else {\n this.$emit('is-hidden');\n }\n\n this.isVisible = isIntersecting;\n }\n\n /**\n * Ticked hook.\n * @todo create AbstractSliderItem with `render` method\n * @todo add state to SliderItem\n * @todo add origin to SliderItem\n * @returns {void}\n */\n ticked() {\n this.dampedX = damp(this.x, this.dampedX, 0.1, 0.00001);\n this.render();\n\n if (this.dampedX === this.x) {\n this.$services.disable('ticked');\n }\n }\n\n /**\n * Set accessibility attributes for the component\n */\n setAccessibilityAttributes() {\n this.$el.setAttribute('role', 'group');\n this.$el.setAttribute('aria-roledescription', 'slide');\n this.$el.setAttribute('aria-label', this.$id);\n }\n\n /**\n * Enable the SliderItem.\n */\n activate() {\n this.$el.classList.add('is-active');\n }\n\n /**\n * Disable the SliderItem.\n */\n disactivate() {\n this.$el.classList.remove('is-active');\n }\n\n /**\n * Move the SliderItem to the given target position.\n */\n move(targetPosition: number) {\n this.x = targetPosition;\n\n if (!this.$services.has('ticked')) {\n this.$services.enable('ticked');\n }\n }\n\n /**\n * Move the SliderItem instantly to the given target position.\n */\n moveInstantly(targetPosition: number) {\n this.x = targetPosition;\n this.dampedX = targetPosition;\n this.render();\n }\n\n /**\n * Render the component.\n */\n render() {\n domScheduler.write(() => {\n transform(this.$el, { x: this.dampedX });\n });\n }\n\n /**\n * Check if SliderItem is partially visible for the given target position.\n */\n willBeVisible(targetPosition: number) {\n return (\n this.rect.x + targetPosition < window.innerWidth * 1.5 &&\n this.rect.x + targetPosition + this.rect.width > window.innerWidth * -0.5\n );\n }\n\n /**\n * Check if SliderItem is fully visible for the given target position.\n * @param {number} targetPosition\n * @returns {boolean}\n */\n willBeFullyVisible(targetPosition) {\n return (\n this.rect.x + targetPosition < window.innerWidth &&\n this.rect.x + targetPosition > 0 &&\n this.rect.x + targetPosition + this.rect.width < window.innerWidth &&\n this.rect.x + targetPosition + this.rect.width > 0\n );\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|