tosijs-ui 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (134) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +165 -0
  3. package/dist/ab-test.d.ts +14 -0
  4. package/dist/ab-test.js +116 -0
  5. package/dist/babylon-3d.d.ts +53 -0
  6. package/dist/babylon-3d.js +292 -0
  7. package/dist/bodymovin-player.d.ts +32 -0
  8. package/dist/bodymovin-player.js +172 -0
  9. package/dist/bp-loader.d.ts +1 -0
  10. package/dist/bp-loader.js +26 -0
  11. package/dist/carousel.d.ts +113 -0
  12. package/dist/carousel.js +308 -0
  13. package/dist/code-editor.d.ts +27 -0
  14. package/dist/code-editor.js +102 -0
  15. package/dist/color-input.d.ts +41 -0
  16. package/dist/color-input.js +112 -0
  17. package/dist/data-table.d.ts +79 -0
  18. package/dist/data-table.js +774 -0
  19. package/dist/drag-and-drop.d.ts +2 -0
  20. package/dist/drag-and-drop.js +386 -0
  21. package/dist/editable-rect.d.ts +97 -0
  22. package/dist/editable-rect.js +450 -0
  23. package/dist/filter-builder.d.ts +64 -0
  24. package/dist/filter-builder.js +468 -0
  25. package/dist/float.d.ts +18 -0
  26. package/dist/float.js +170 -0
  27. package/dist/form.d.ts +68 -0
  28. package/dist/form.js +466 -0
  29. package/dist/gamepad.d.ts +34 -0
  30. package/dist/gamepad.js +115 -0
  31. package/dist/icon-data.d.ts +312 -0
  32. package/dist/icon-data.js +308 -0
  33. package/dist/icon-types.d.ts +7 -0
  34. package/dist/icon-types.js +1 -0
  35. package/dist/icons.d.ts +17 -0
  36. package/dist/icons.js +374 -0
  37. package/dist/iife.js +69 -0
  38. package/dist/iife.js.map +49 -0
  39. package/dist/index-iife.d.ts +1 -0
  40. package/dist/index-iife.js +4 -0
  41. package/dist/index.d.ts +37 -0
  42. package/dist/index.js +37 -0
  43. package/dist/index.js.map +47 -0
  44. package/dist/live-example.d.ts +63 -0
  45. package/dist/live-example.js +611 -0
  46. package/dist/localize.d.ts +46 -0
  47. package/dist/localize.js +381 -0
  48. package/dist/make-sorter.d.ts +3 -0
  49. package/dist/make-sorter.js +119 -0
  50. package/dist/make-sorter.test.d.ts +1 -0
  51. package/dist/make-sorter.test.js +48 -0
  52. package/dist/mapbox.d.ts +24 -0
  53. package/dist/mapbox.js +161 -0
  54. package/dist/markdown-viewer.d.ts +17 -0
  55. package/dist/markdown-viewer.js +173 -0
  56. package/dist/match-shortcut.d.ts +9 -0
  57. package/dist/match-shortcut.js +13 -0
  58. package/dist/match-shortcut.test.d.ts +1 -0
  59. package/dist/match-shortcut.test.js +194 -0
  60. package/dist/menu.d.ts +60 -0
  61. package/dist/menu.js +614 -0
  62. package/dist/notifications.d.ts +106 -0
  63. package/dist/notifications.js +308 -0
  64. package/dist/password-strength.d.ts +35 -0
  65. package/dist/password-strength.js +302 -0
  66. package/dist/playwright.config.d.ts +9 -0
  67. package/dist/playwright.config.js +73 -0
  68. package/dist/pop-float.d.ts +10 -0
  69. package/dist/pop-float.js +231 -0
  70. package/dist/rating.d.ts +62 -0
  71. package/dist/rating.js +192 -0
  72. package/dist/rich-text.d.ts +35 -0
  73. package/dist/rich-text.js +296 -0
  74. package/dist/segmented.d.ts +80 -0
  75. package/dist/segmented.js +298 -0
  76. package/dist/select.d.ts +43 -0
  77. package/dist/select.js +427 -0
  78. package/dist/side-nav.d.ts +36 -0
  79. package/dist/side-nav.js +106 -0
  80. package/dist/size-break.d.ts +18 -0
  81. package/dist/size-break.js +118 -0
  82. package/dist/sizer.d.ts +34 -0
  83. package/dist/sizer.js +92 -0
  84. package/dist/src/ab-test.d.ts +14 -0
  85. package/dist/src/babylon-3d.d.ts +53 -0
  86. package/dist/src/bodymovin-player.d.ts +32 -0
  87. package/dist/src/bp-loader.d.ts +0 -0
  88. package/dist/src/carousel.d.ts +113 -0
  89. package/dist/src/code-editor.d.ts +27 -0
  90. package/dist/src/color-input.d.ts +41 -0
  91. package/dist/src/data-table.d.ts +79 -0
  92. package/dist/src/drag-and-drop.d.ts +2 -0
  93. package/dist/src/editable-rect.d.ts +97 -0
  94. package/dist/src/filter-builder.d.ts +64 -0
  95. package/dist/src/float.d.ts +18 -0
  96. package/dist/src/form.d.ts +68 -0
  97. package/dist/src/gamepad.d.ts +34 -0
  98. package/dist/src/icon-data.d.ts +309 -0
  99. package/dist/src/icon-types.d.ts +7 -0
  100. package/dist/src/icons.d.ts +17 -0
  101. package/dist/src/index.d.ts +37 -0
  102. package/dist/src/live-example.d.ts +51 -0
  103. package/dist/src/localize.d.ts +30 -0
  104. package/dist/src/make-sorter.d.ts +3 -0
  105. package/dist/src/mapbox.d.ts +24 -0
  106. package/dist/src/markdown-viewer.d.ts +15 -0
  107. package/dist/src/match-shortcut.d.ts +9 -0
  108. package/dist/src/menu.d.ts +60 -0
  109. package/dist/src/notifications.d.ts +106 -0
  110. package/dist/src/password-strength.d.ts +35 -0
  111. package/dist/src/pop-float.d.ts +10 -0
  112. package/dist/src/rating.d.ts +62 -0
  113. package/dist/src/rich-text.d.ts +28 -0
  114. package/dist/src/segmented.d.ts +80 -0
  115. package/dist/src/select.d.ts +43 -0
  116. package/dist/src/side-nav.d.ts +36 -0
  117. package/dist/src/size-break.d.ts +18 -0
  118. package/dist/src/sizer.d.ts +34 -0
  119. package/dist/src/tab-selector.d.ts +91 -0
  120. package/dist/src/tag-list.d.ts +37 -0
  121. package/dist/src/track-drag.d.ts +5 -0
  122. package/dist/src/version.d.ts +1 -0
  123. package/dist/src/via-tag.d.ts +2 -0
  124. package/dist/tab-selector.d.ts +91 -0
  125. package/dist/tab-selector.js +326 -0
  126. package/dist/tag-list.d.ts +37 -0
  127. package/dist/tag-list.js +375 -0
  128. package/dist/track-drag.d.ts +5 -0
  129. package/dist/track-drag.js +143 -0
  130. package/dist/version.d.ts +1 -0
  131. package/dist/version.js +1 -0
  132. package/dist/via-tag.d.ts +2 -0
  133. package/dist/via-tag.js +102 -0
  134. package/package.json +58 -0
@@ -0,0 +1,172 @@
1
+ /*#
2
+ # lottie / bodymovin
3
+
4
+ A [lottie](https://airbnb.io/lottie/#/web) (a.k.a. **bodymovin**) player.
5
+
6
+ It's designed to work like an `<img>` element (just set its `src` attribute).
7
+
8
+ ```js
9
+ const { xinProxy } = xinjs
10
+ const { icons, popFloat } = xinjsui
11
+ const { div, label, input, select, option, span } = xinjs.elements
12
+
13
+ const rocket = preview.querySelector('xin-lottie')
14
+ setTimeout(
15
+ () => {
16
+ preview.append(
17
+ popFloat({
18
+ content: [
19
+ { class: 'panel', drag: true },
20
+ div({ class: 'panel-header' }, 'Player Controls' ),
21
+ label(
22
+ { class: 'no-drag' },
23
+ 'speed',
24
+ input({ type: 'range', min: -1, max: 1, step: 0.1, value: 0, onInput(event) {
25
+ const speed = Math.pow(5, Number(event.target.value))
26
+ rocket.animation.setSpeed(speed)
27
+ event.target.nextSibling.textContent = (speed * 100).toFixed(0) + '%'
28
+ } }),
29
+ span('100%', {style: { textAlign: 'right', width: '40px'}})
30
+ ),
31
+ label(
32
+ { class: 'no-drag' },
33
+ 'direction',
34
+ select(
35
+ option('Forwards', {value: 1, selected: true}),
36
+ option('Backwards', {value: -1}),
37
+ {
38
+ onChange(event) {
39
+ rocket.animation.setDirection(event.target.value)
40
+ }
41
+ }
42
+ ),
43
+ icons.chevronDown(),
44
+ )
45
+ ],
46
+ target: rocket,
47
+ position: 's'
48
+ })
49
+ )
50
+ },
51
+ 500
52
+ )
53
+ ```
54
+ ```html
55
+ <xin-lottie
56
+ style="height: 100%; max-width: 100%"
57
+ src="88140-rocket-livetrade.json"
58
+ ></xin-lottie>
59
+ <div class="caption">
60
+ Animation by <a target="_blank" href="https://lottiefiles.com/dvskjbicfc">chiến lê hồng</a>
61
+ </div>
62
+ ```
63
+ ```css
64
+ .preview {
65
+ padding: var(--spacing);
66
+ text-align: center;
67
+ }
68
+
69
+ .preview .panel {
70
+ padding: 10px;
71
+ border-radius: 5px;
72
+ gap: 5px;
73
+ background: white;
74
+ box-shadow: 0 2px 8px rgba(0,0,0,0.25);
75
+ display: flex;
76
+ flex-direction: column;
77
+ overflow: hidden;
78
+ }
79
+
80
+ .preview .caption {
81
+ position: absolute;
82
+ right: 5px;
83
+ bottom: 5px;
84
+ }
85
+
86
+ .preview .panel-header {
87
+ margin: 0;
88
+ text-align: center;
89
+ font-weight: bold;
90
+ background: var(--brand-color);
91
+ color: white;
92
+ padding: 5px;
93
+ margin: -10px -10px 0 -10px;
94
+ cursor: move;
95
+ }
96
+ ```
97
+
98
+ You can also directly set its `json` property to the content of a `lottie.json` file.
99
+
100
+ And of course just access the element's `animation` property to [use the bodymovin API](https://airbnb.io/lottie/#/web).
101
+
102
+ Also see the [documentation for advanced interactions](https://lottiefiles.github.io/lottie-docs/advanced_interactions/)
103
+ */
104
+ import { Component as WebComponent } from 'xinjs';
105
+ import { scriptTag } from './via-tag';
106
+ export class BodymovinPlayer extends WebComponent {
107
+ content = null;
108
+ src = '';
109
+ json = '';
110
+ config = {
111
+ renderer: 'svg',
112
+ loop: true,
113
+ autoplay: true,
114
+ };
115
+ static bodymovinAvailable;
116
+ animation;
117
+ static styleSpec = {
118
+ ':host': {
119
+ width: 400,
120
+ height: 400,
121
+ display: 'inline-block',
122
+ },
123
+ };
124
+ _loading = false;
125
+ get loading() {
126
+ return this._loading;
127
+ }
128
+ constructor() {
129
+ super();
130
+ this.initAttributes('src', 'json');
131
+ if (BodymovinPlayer.bodymovinAvailable === undefined) {
132
+ BodymovinPlayer.bodymovinAvailable = scriptTag('https://cdnjs.cloudflare.com/ajax/libs/bodymovin/5.12.2/lottie.min.js', 'bodymovin');
133
+ }
134
+ }
135
+ doneLoading = () => {
136
+ this._loading = false;
137
+ };
138
+ load = ({ bodymovin }) => {
139
+ this._loading = true;
140
+ this.config.container =
141
+ this.shadowRoot !== null ? this.shadowRoot : undefined;
142
+ if (this.json !== '') {
143
+ this.config.animationData = this.json;
144
+ delete this.config.path;
145
+ }
146
+ else if (this.src !== '') {
147
+ delete this.config.animationData;
148
+ this.config.path = this.src;
149
+ }
150
+ else {
151
+ console.log('%c<xin-lottie>%c expected either %cjson%c (animation data) or %csrc% c(url) but found neither.', 'color: #44f; background: #fff; padding: 0 5px', 'color: default', 'color: #44f; background: #fff; padding: 0 5px', 'color: default', 'color: #44f; background: #fff; padding: 0 5px', 'color: default');
152
+ }
153
+ if (this.animation) {
154
+ this.animation.destroy();
155
+ const root = this.shadowRoot;
156
+ if (root !== null) {
157
+ root.querySelector('svg')?.remove();
158
+ }
159
+ }
160
+ this.animation = bodymovin.loadAnimation(this.config);
161
+ this.animation.addEventListener('DOMLoaded', this.doneLoading);
162
+ };
163
+ render() {
164
+ super.render();
165
+ BodymovinPlayer.bodymovinAvailable.then(this.load).catch((e) => {
166
+ console.error(e);
167
+ });
168
+ }
169
+ }
170
+ export const bodymovinPlayer = BodymovinPlayer.elementCreator({
171
+ tag: 'xin-lottie',
172
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,26 @@
1
+ export {};
2
+ /*#
3
+ # blueprint loading
4
+
5
+ <center>
6
+ <xin-icon icon="blueprint" class="logo" size=256></xin-icon>
7
+ </center>
8
+
9
+ `<xin-loader>` and `<xin-blueprint>` are simple elements provided by `xinjs` for the dynamic loading
10
+ of component **blueprints**.
11
+
12
+ ```html
13
+ <xin-loader>
14
+ <xin-blueprint tag="swiss-clock" src="https://tonioloewald.github.io/xin-clock/dist/blueprint.js"></xin-blueprint>
15
+ </xin-loader>
16
+ <swiss-clock></swiss-clock>
17
+ ```
18
+
19
+ ## Attributes
20
+
21
+ - `blueprint` is the url of the `blueprint` javascript module (required)
22
+ - `tag` is the tagName you wish to use. If the name of the blueprint is
23
+ hyphenated, then that will be used by default
24
+ - `property` if the blueprint module exports the blueprint function as
25
+ a property, you can specify the property here.
26
+ */
@@ -0,0 +1,113 @@
1
+ import { Component as WebComponent, ElementCreator } from 'tosijs';
2
+ export declare class XinCarousel extends WebComponent {
3
+ arrows: boolean;
4
+ dots: boolean;
5
+ loop: boolean;
6
+ maxVisibleItems: number;
7
+ snapDelay: number;
8
+ snapDuration: number;
9
+ auto: number;
10
+ private lastAutoAdvance;
11
+ private interval?;
12
+ private autoAdvance;
13
+ private _page;
14
+ get page(): number;
15
+ set page(p: number);
16
+ get visibleItems(): HTMLElement[];
17
+ get lastPage(): number;
18
+ static styleSpec: {
19
+ ':host': {
20
+ display: string;
21
+ flexDirection: string;
22
+ position: string;
23
+ };
24
+ ':host svg': {
25
+ height: string;
26
+ };
27
+ ':host button': {
28
+ outline: string;
29
+ border: string;
30
+ boxShadow: string;
31
+ background: string;
32
+ color: string;
33
+ padding: number;
34
+ };
35
+ ':host::part(back), :host::part(forward)': {
36
+ position: string;
37
+ top: number;
38
+ bottom: number;
39
+ width: string;
40
+ zIndex: number;
41
+ };
42
+ ':host::part(back)': {
43
+ left: number;
44
+ };
45
+ ':host::part(forward)': {
46
+ right: number;
47
+ };
48
+ ':host button:disabled': {
49
+ opacity: number;
50
+ pointerEvents: string;
51
+ };
52
+ ':host button:hover': {
53
+ color: string;
54
+ };
55
+ ':host button:active': {
56
+ color: string;
57
+ };
58
+ ':host::part(pager)': {
59
+ position: string;
60
+ };
61
+ ':host::part(scroller)': {
62
+ overflow: string;
63
+ position: string;
64
+ };
65
+ ':host::part(grid)': {
66
+ display: string;
67
+ justifyItems: string;
68
+ };
69
+ ':host *::-webkit-scrollbar, *::-webkit-scrollbar-thumb': {
70
+ display: string;
71
+ };
72
+ ':host .dot': {
73
+ background: string;
74
+ borderRadius: string;
75
+ height: string;
76
+ width: string;
77
+ transition: string;
78
+ };
79
+ ':host .dot:not(.current):hover': {
80
+ background: string;
81
+ height: string;
82
+ width: string;
83
+ margin: string;
84
+ };
85
+ ':host .dot:not(.current):active': {
86
+ background: string;
87
+ };
88
+ ':host .dot.current': {
89
+ background: string;
90
+ };
91
+ ':host::part(progress)': {
92
+ display: string;
93
+ gap: string;
94
+ justifyContent: string;
95
+ padding: string;
96
+ };
97
+ };
98
+ easing: (t: number) => number;
99
+ indicateCurrent: () => void;
100
+ snapPosition: () => void;
101
+ back: () => void;
102
+ forward: () => void;
103
+ handleDotClick: (event: Event) => void;
104
+ private snapTimer;
105
+ private animationFrame;
106
+ animateScroll(position: number, startingPosition?: number, timestamp?: number): void;
107
+ content: () => HTMLDivElement[];
108
+ constructor();
109
+ connectedCallback(): void;
110
+ disconnectedCallback(): void;
111
+ render(): void;
112
+ }
113
+ export declare const xinCarousel: ElementCreator<XinCarousel>;
@@ -0,0 +1,308 @@
1
+ /*#
2
+ # carousel
3
+
4
+ ```html
5
+ <xin-carousel arrows dots max-visible-items=2 auto=2 snap-delay=4 snap-duration=0.5 loop>
6
+ <xin-icon icon="tosiFavicon" class="thing"></xin-icon>
7
+ <xin-icon icon="tosi" class="thing"></xin-icon>
8
+ <xin-icon icon="tosiUi" class="thing"></xin-icon>
9
+ <xin-icon icon="tosiPlatform" class="thing"></xin-icon>
10
+ <xin-icon icon="tosiXr" class="thing"></xin-icon>
11
+ <xin-icon icon="blueprint" class="thing"></xin-icon>
12
+ <xin-icon icon="cmy" class="thing"></xin-icon>
13
+ <xin-icon icon="rgb" class="thing"></xin-icon>
14
+ </xin-carousel>
15
+ ```
16
+ ```css
17
+ .thing {
18
+ --xin-icon-size: 160px;
19
+ height: 160px;
20
+ margin: 30px 0 70px;
21
+ position: relative;
22
+ }
23
+
24
+ .thing::after {
25
+ content: attr(icon);
26
+ color: white;
27
+ position: absolute;
28
+ bottom: -50px;
29
+ left: 50%;
30
+ padding: 5px 15px;
31
+ transform: translateX(-50%);
32
+ filter: drop-shadow(0 1px 1px #0008);
33
+ background: #0004;
34
+ border-radius: 5px;
35
+ }
36
+
37
+ .preview xin-carousel {
38
+ margin: 10px;
39
+ }
40
+ ```
41
+
42
+ This is a minimalist carousel component that supports the usual stuff.
43
+
44
+ ## Attributes
45
+
46
+ - `arrows` (boolean, false by default) shows/hides the arrow paging controls
47
+ - `dots` (boolean, false by default) shows/hides the dot progress indicators
48
+ - `max-visible-items` (number, 1 by default) determines how many items are shown at once.
49
+ - `snap-duration` (number, 0.25 [seconds] by default) determines the time taken to scroll / snap scroll.
50
+ - `snap-delay` (number, 0.1 [seconds] by default)
51
+ - `loop` (boolean, false by default) causes next/previous buttons to loop
52
+ - `auto` (number, 0 [seconds] by default) if > 0, automatically advances after that many seconds (always loops!)
53
+
54
+ <xin-css-var-editor element-selector="xin-carousel"></xin-css-var-editor>
55
+ */
56
+ import { Component as WebComponent, elements, vars, } from 'xinjs';
57
+ import { icons } from './icons';
58
+ const { button, slot, div } = elements;
59
+ export class XinCarousel extends WebComponent {
60
+ arrows = false;
61
+ dots = false;
62
+ loop = false;
63
+ maxVisibleItems = 1;
64
+ snapDelay = 0.1;
65
+ snapDuration = 0.25;
66
+ auto = 0;
67
+ lastAutoAdvance = Date.now();
68
+ interval;
69
+ autoAdvance = () => {
70
+ if (this.auto > 0 && this.auto * 1000 < Date.now() - this.lastAutoAdvance) {
71
+ this.forward();
72
+ }
73
+ };
74
+ _page = 0;
75
+ get page() {
76
+ return this._page;
77
+ }
78
+ set page(p) {
79
+ const { scroller, back, forward } = this.parts;
80
+ if (this.lastPage <= 0) {
81
+ forward.disabled = back.disabled = true;
82
+ p = 0;
83
+ }
84
+ else {
85
+ p = Math.max(0, Math.min(this.lastPage, p));
86
+ p = isNaN(p) ? 0 : p;
87
+ }
88
+ if (this._page !== p) {
89
+ this._page = isNaN(p) ? 0 : p;
90
+ this.animateScroll(this._page * scroller.offsetWidth);
91
+ back.disabled = this.page <= 0 && !this.loop;
92
+ forward.disabled = this.page >= this.lastPage && !this.loop;
93
+ }
94
+ }
95
+ get visibleItems() {
96
+ return [...this.children].filter((element) => getComputedStyle(element).display !== 'none');
97
+ }
98
+ get lastPage() {
99
+ return Math.max(Math.ceil(this.visibleItems.length / (this.maxVisibleItems || 1)) - 1, 0);
100
+ }
101
+ static styleSpec = {
102
+ ':host': {
103
+ display: 'flex',
104
+ flexDirection: 'column',
105
+ position: 'relative',
106
+ },
107
+ ':host svg': {
108
+ height: vars.carouselIconSize,
109
+ },
110
+ ':host button': {
111
+ outline: 'none',
112
+ border: 'none',
113
+ boxShadow: 'none',
114
+ background: 'transparent',
115
+ color: vars.carouselButtonColor,
116
+ padding: 0,
117
+ },
118
+ ':host::part(back), :host::part(forward)': {
119
+ position: 'absolute',
120
+ top: 0,
121
+ bottom: 0,
122
+ width: vars.carouseButtonWidth,
123
+ zIndex: 2,
124
+ },
125
+ ':host::part(back)': {
126
+ left: 0,
127
+ },
128
+ ':host::part(forward)': {
129
+ right: 0,
130
+ },
131
+ ':host button:disabled': {
132
+ opacity: 0.5,
133
+ pointerEvents: 'none',
134
+ },
135
+ ':host button:hover': {
136
+ color: vars.carouselButtonHoverColor,
137
+ },
138
+ ':host button:active': {
139
+ color: vars.carouselButtonActiveColor,
140
+ },
141
+ ':host::part(pager)': {
142
+ position: 'relative',
143
+ },
144
+ ':host::part(scroller)': {
145
+ overflow: 'auto hidden',
146
+ position: 'relative',
147
+ },
148
+ ':host::part(grid)': {
149
+ display: 'grid',
150
+ justifyItems: 'center',
151
+ },
152
+ ':host *::-webkit-scrollbar, *::-webkit-scrollbar-thumb': {
153
+ display: 'none',
154
+ },
155
+ ':host .dot': {
156
+ background: vars.carouselButtonColor,
157
+ borderRadius: vars.carouselDotSize,
158
+ height: vars.carouselDotSize,
159
+ width: vars.carouselDotSize,
160
+ transition: vars.carouselDotTransition,
161
+ },
162
+ ':host .dot:not(.current):hover': {
163
+ background: vars.carouselButtonHoverColor,
164
+ height: vars.carouselDotSize150,
165
+ width: vars.carouselDotSize150,
166
+ margin: vars.carouselDotSize_25,
167
+ },
168
+ ':host .dot:not(.current):active': {
169
+ background: vars.carouselButtonActiveColor,
170
+ },
171
+ ':host .dot.current': {
172
+ background: vars.carouselDotCurrentColor,
173
+ },
174
+ ':host::part(progress)': {
175
+ display: 'flex',
176
+ gap: vars.carouselDotSpacing,
177
+ justifyContent: 'center',
178
+ padding: vars.carouselProgressPadding,
179
+ },
180
+ };
181
+ easing = (t) => {
182
+ return Math.sin(t * Math.PI * 0.5);
183
+ };
184
+ indicateCurrent = () => {
185
+ const { scroller, progress } = this.parts;
186
+ const page = scroller.scrollLeft / scroller.offsetWidth;
187
+ [...progress.children].forEach((dot, index) => {
188
+ dot.classList.toggle('current', Math.floor(index / this.maxVisibleItems - page) === 0);
189
+ });
190
+ this.lastAutoAdvance = Date.now();
191
+ clearTimeout(this.snapTimer);
192
+ this.snapTimer = setTimeout(this.snapPosition, this.snapDelay * 1000);
193
+ };
194
+ snapPosition = () => {
195
+ const { scroller } = this.parts;
196
+ const currentPosition = Math.round(scroller.scrollLeft / scroller.offsetWidth);
197
+ if (currentPosition !== this.page) {
198
+ this.page =
199
+ currentPosition > this.page
200
+ ? Math.ceil(currentPosition)
201
+ : Math.floor(currentPosition);
202
+ }
203
+ this.lastAutoAdvance = Date.now();
204
+ };
205
+ back = () => {
206
+ this.page = this.page > 0 ? this.page - 1 : this.lastPage;
207
+ };
208
+ forward = () => {
209
+ this.page = this.page < this.lastPage ? this.page + 1 : 0;
210
+ };
211
+ handleDotClick = (event) => {
212
+ const { progress } = this.parts;
213
+ const index = [...progress.children].indexOf(event.target);
214
+ if (index > -1) {
215
+ this.page = Math.floor(index / this.maxVisibleItems);
216
+ }
217
+ };
218
+ snapTimer;
219
+ animationFrame;
220
+ animateScroll(position, startingPosition = -1, timestamp = 0) {
221
+ cancelAnimationFrame(this.animationFrame);
222
+ const { scroller } = this.parts;
223
+ if (startingPosition === -1) {
224
+ startingPosition = scroller.scrollLeft;
225
+ timestamp = Date.now();
226
+ this.animationFrame = requestAnimationFrame(() => {
227
+ this.animateScroll(position, startingPosition, timestamp);
228
+ });
229
+ return;
230
+ }
231
+ const elapsed = (Date.now() - timestamp) / 1000;
232
+ if (elapsed >= this.snapDuration ||
233
+ Math.abs(scroller.scrollLeft - position) < 2) {
234
+ scroller.scrollLeft = position;
235
+ this.animationFrame = null;
236
+ }
237
+ else {
238
+ scroller.scrollLeft =
239
+ startingPosition +
240
+ this.easing(elapsed / this.snapDuration) * (position - startingPosition);
241
+ this.animationFrame = requestAnimationFrame(() => {
242
+ this.animateScroll(position, startingPosition, timestamp);
243
+ });
244
+ }
245
+ }
246
+ content = () => [
247
+ div({ part: 'pager' }, button({ title: 'previous slide', part: 'back' }, icons.chevronLeft()), div({ title: 'slides', role: 'group', part: 'scroller' }, div({ part: 'grid' }, slot())), button({ title: 'next slide', part: 'forward' }, icons.chevronRight())),
248
+ div({ title: 'choose slide to display', role: 'group', part: 'progress' }),
249
+ ];
250
+ constructor() {
251
+ super();
252
+ this.initAttributes('dots', 'arrows', 'maxVisibleItems', 'snapDuration', 'loop', 'auto');
253
+ }
254
+ connectedCallback() {
255
+ super.connectedCallback();
256
+ this.ariaRoleDescription = 'carousel';
257
+ this.ariaOrientation = 'horizontal';
258
+ this.ariaReadOnly = 'true';
259
+ const { back, forward, scroller, progress } = this.parts;
260
+ back.addEventListener('click', this.back);
261
+ forward.addEventListener('click', this.forward);
262
+ scroller.addEventListener('scroll', this.indicateCurrent);
263
+ progress.addEventListener('click', this.handleDotClick);
264
+ this.lastAutoAdvance = Date.now();
265
+ this.interval = setInterval(this.autoAdvance, 100);
266
+ }
267
+ disconnectedCallback() {
268
+ clearInterval(this.interval);
269
+ }
270
+ render() {
271
+ super.render();
272
+ const { dots, arrows, visibleItems, lastPage } = this;
273
+ const { progress, back, forward, grid } = this.parts;
274
+ visibleItems.forEach((item) => {
275
+ item.role = 'group';
276
+ });
277
+ grid.style.gridTemplateColumns = `${100 / this.maxVisibleItems / (1 + this.lastPage)}% `
278
+ .repeat(visibleItems.length)
279
+ .trim();
280
+ grid.style.width = (1 + this.lastPage) * 100 + '%';
281
+ progress.textContent = '';
282
+ progress.append(...visibleItems.map((_, index) => button({ title: `item ${index + 1}`, class: 'dot' })));
283
+ this.indicateCurrent();
284
+ progress.style.display = dots && lastPage > 0 ? '' : 'none';
285
+ back.hidden = forward.hidden = !(arrows && lastPage > 0);
286
+ }
287
+ }
288
+ export const xinCarousel = XinCarousel.elementCreator({
289
+ tag: 'xin-carousel',
290
+ styleSpec: {
291
+ ':host': {
292
+ _carouselIconSize: 24,
293
+ _carouselButtonColor: '#0004',
294
+ _carouselButtonHoverColor: '#0006',
295
+ _carouselButtonActiveColor: '#000c',
296
+ _carouseButtonWidth: 48,
297
+ _carouselDotCurrentColor: '#0008',
298
+ _carouselDotSize: 8,
299
+ _carouselDotSpacing: vars.carouselDotSize,
300
+ _carouselProgressPadding: 12,
301
+ _carouselDotTransition: '0.125s ease-in-out',
302
+ },
303
+ ':host:focus': {
304
+ outline: 'none',
305
+ boxShadow: 'none',
306
+ },
307
+ },
308
+ });
@@ -0,0 +1,27 @@
1
+ import { Component as WebComponent, ElementCreator } from 'tosijs';
2
+ export declare class CodeEditor extends WebComponent {
3
+ private source;
4
+ get value(): string;
5
+ set value(text: string);
6
+ mode: string;
7
+ disabled: boolean;
8
+ role: string;
9
+ get editor(): any;
10
+ private _editor;
11
+ private _editorPromise;
12
+ options: any;
13
+ theme: string;
14
+ static styleSpec: {
15
+ ':host': {
16
+ display: string;
17
+ position: string;
18
+ width: string;
19
+ height: string;
20
+ };
21
+ };
22
+ constructor();
23
+ onResize(): void;
24
+ connectedCallback(): void;
25
+ render(): void;
26
+ }
27
+ export declare const codeEditor: ElementCreator<CodeEditor>;