@esportsplus/ui 0.18.1 → 0.19.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 (91) hide show
  1. package/.github/dependabot.yml +2 -0
  2. package/.github/workflows/bump.yml +2 -0
  3. package/.github/workflows/dependabot.yml +12 -0
  4. package/.github/workflows/publish.yml +2 -0
  5. package/build/components/accordion/index.d.ts +5 -15
  6. package/build/components/accordion/index.js +28 -20
  7. package/build/components/counter/index.d.ts +2 -2
  8. package/build/components/counter/index.js +10 -10
  9. package/build/components/ellipsis/index.d.ts +1 -1
  10. package/build/components/field/checkbox.d.ts +9 -339
  11. package/build/components/field/checkbox.js +24 -21
  12. package/build/components/field/description.d.ts +3 -3
  13. package/build/components/field/error.d.ts +3 -2
  14. package/build/components/field/index.d.ts +1721 -3152
  15. package/build/components/field/input.d.ts +18 -348
  16. package/build/components/field/input.js +33 -23
  17. package/build/components/field/select.d.ts +119 -226
  18. package/build/components/field/select.js +81 -69
  19. package/build/components/field/title.d.ts +114 -107
  20. package/build/components/field/title.js +15 -8
  21. package/build/components/form/action.d.ts +21 -6
  22. package/build/components/form/action.js +20 -9
  23. package/build/components/form/index.d.ts +130 -2
  24. package/build/components/frame/index.d.ts +3 -112
  25. package/build/components/frame/index.js +4 -6
  26. package/build/components/highlight/index.d.ts +5 -7
  27. package/build/components/highlight/index.js +23 -15
  28. package/build/components/icon/index.d.ts +3 -3
  29. package/build/components/index.d.ts +2 -2
  30. package/build/components/index.js +2 -2
  31. package/build/components/loader/index.d.ts +3 -3
  32. package/build/components/loader/index.js +13 -16
  33. package/build/components/loading/index.d.ts +1 -1
  34. package/build/components/overlay/index.d.ts +3 -112
  35. package/build/components/overlay/index.js +4 -6
  36. package/build/components/page/index.d.ts +0 -12
  37. package/build/components/page/index.js +0 -10
  38. package/build/components/root/onclick.js +4 -6
  39. package/build/components/scrollbar/index.d.ts +8 -112
  40. package/build/components/scrollbar/index.js +25 -20
  41. package/build/components/sidebar/index.d.ts +3 -112
  42. package/build/components/sidebar/index.js +4 -6
  43. package/build/components/site/index.d.ts +3 -112
  44. package/build/components/site/index.js +5 -8
  45. package/build/components/template/index.d.ts +8 -4
  46. package/build/components/template/index.js +5 -4
  47. package/build/components/tooltip/index.d.ts +235 -332
  48. package/build/components/tooltip/index.js +3 -106
  49. package/build/components/tooltip/menu.d.ts +20 -0
  50. package/build/components/tooltip/menu.js +28 -0
  51. package/build/components/tooltip/onclick.d.ts +124 -0
  52. package/build/components/tooltip/onclick.js +67 -0
  53. package/build/components/tooltip/onhover.d.ts +7 -0
  54. package/build/components/tooltip/onhover.js +25 -0
  55. package/build/components/typewriter/index.d.ts +4 -6
  56. package/build/components/typewriter/index.js +34 -33
  57. package/package.json +10 -9
  58. package/src/components/accordion/index.ts +41 -26
  59. package/src/components/counter/index.ts +15 -13
  60. package/src/components/field/checkbox.ts +31 -30
  61. package/src/components/field/description.ts +2 -2
  62. package/src/components/field/error.ts +2 -2
  63. package/src/components/field/input.ts +41 -33
  64. package/src/components/field/select.ts +123 -108
  65. package/src/components/field/title.ts +18 -8
  66. package/src/components/form/action.ts +75 -47
  67. package/src/components/frame/index.ts +4 -9
  68. package/src/components/highlight/index.ts +53 -39
  69. package/src/components/icon/index.ts +3 -3
  70. package/src/components/index.ts +2 -2
  71. package/src/components/loader/index.ts +15 -17
  72. package/src/components/overlay/index.ts +4 -9
  73. package/src/components/page/index.ts +1 -17
  74. package/src/components/root/onclick.ts +6 -7
  75. package/src/components/scrollbar/index.ts +34 -23
  76. package/src/components/sidebar/index.ts +4 -9
  77. package/src/components/site/index.ts +5 -13
  78. package/src/components/template/index.ts +18 -10
  79. package/src/components/tooltip/index.ts +4 -156
  80. package/src/components/tooltip/menu.ts +52 -0
  81. package/src/components/tooltip/onclick.ts +97 -0
  82. package/src/components/tooltip/onhover.ts +35 -0
  83. package/src/components/typewriter/index.ts +44 -41
  84. package/build/components/footer/index.d.ts +0 -22
  85. package/build/components/footer/index.js +0 -61
  86. package/build/components/footer/scss/index.scss +0 -2
  87. package/build/components/form/types.d.ts +0 -10
  88. package/build/components/form/types.js +0 -1
  89. package/src/components/footer/index.ts +0 -74
  90. package/src/components/footer/scss/index.scss +0 -26
  91. package/src/components/form/types.ts +0 -14
@@ -1,8 +1,25 @@
1
- import response from '@esportsplus/action';
2
- import { Action } from './types';
1
+ import response, { Response } from '@esportsplus/action';
2
+ import { html, Attributes, Element } from '@esportsplus/template';
3
+ import { omit } from '@esportsplus/utilities';
4
+ import template from '~/components/template';
3
5
  import input from './input';
4
6
 
5
7
 
8
+ type A = Attributes & { action: Action, state?: { processing: boolean } };
9
+
10
+ type Action = (data: Payload) => Promise<Errors> | Errors;
11
+
12
+ type Errors = { errors: Response<unknown>['errors'] };
13
+
14
+ type Payload = {
15
+ input: Record<string, any>;
16
+ response: typeof response;
17
+ };
18
+
19
+
20
+ const OMIT = ['action', 'state'];
21
+
22
+
6
23
  function parse(input: ReturnType<FormData['entries']>) {
7
24
  let data: Record<string, any> = {};
8
25
 
@@ -33,48 +50,59 @@ function parse(input: ReturnType<FormData['entries']>) {
33
50
  };
34
51
 
35
52
 
36
- export default function(action: Action, s?: { processing: boolean }) {
37
- return {
38
- onclick: function(this: HTMLFormElement, event: Event) {
39
- let trigger = event.target as HTMLButtonElement;
40
-
41
- if (trigger?.type !== 'submit') {
42
- return;
43
- }
44
-
45
- // On initial page load both events will be dispatched without preventDefault
46
- event.preventDefault();
47
-
48
- this.dispatchEvent(
49
- new SubmitEvent('submit', { cancelable: true, bubbles:true, submitter: trigger })
50
- );
51
- },
52
- onsubmit: async function(this: HTMLFormElement, event: SubmitEvent) {
53
- event.preventDefault();
54
-
55
- if (s) {
56
- s.processing = true;
57
- }
58
-
59
- let { errors } = await action({
60
- input: parse( new FormData( this ).entries() ),
61
- response
62
- });
63
-
64
- for (let i = 0, n = errors.length; i < n; i++) {
65
- let { message, path } = errors[i],
66
- reactive = input.get( this[path!] );
67
-
68
- if (!reactive) {
69
- continue;
70
- }
71
-
72
- reactive.error = `${message[0].toUpperCase()}${message.substring(1)}`;
73
- }
74
-
75
- if (s) {
76
- s.processing = false;
77
- }
78
- }
79
- };
80
- };
53
+ export default template.factory<A>(
54
+ (attributes, content) => {
55
+ let { action, state } = attributes;
56
+
57
+ return html`
58
+ <form
59
+ ${omit(attributes, OMIT)}
60
+ ${{
61
+ onclick: function(event) {
62
+ let trigger = event.target as HTMLButtonElement;
63
+
64
+ if (trigger?.type !== 'submit') {
65
+ return;
66
+ }
67
+
68
+ // On initial page load both events will be dispatched without preventDefault
69
+ event.preventDefault();
70
+
71
+ this.dispatchEvent(
72
+ new SubmitEvent('submit', { cancelable: true, bubbles:true, submitter: trigger })
73
+ );
74
+ },
75
+ onsubmit: async function(event) {
76
+ event.preventDefault();
77
+
78
+ if (state) {
79
+ state.processing = true;
80
+ }
81
+
82
+ let { errors } = await action({
83
+ input: parse( new FormData( this as any as HTMLFormElement ).entries() ),
84
+ response
85
+ });
86
+
87
+ for (let i = 0, n = errors.length; i < n; i++) {
88
+ let { message, path } = errors[i],
89
+ reactive = input.get( (this as any as HTMLFormElement)[path!] as Element | undefined );
90
+
91
+ if (!reactive) {
92
+ continue;
93
+ }
94
+
95
+ reactive.error = `${message[0].toUpperCase()}${message.substring(1)}`;
96
+ }
97
+
98
+ if (state) {
99
+ state.processing = false;
100
+ }
101
+ }
102
+ }}
103
+ >
104
+ ${content}
105
+ </form>
106
+ `;
107
+ }
108
+ );
@@ -1,14 +1,9 @@
1
- import { toArray } from '@esportsplus/utilities';
2
1
  import scrollbar from '~/components/scrollbar';
3
- import template from '~/components/template';
4
2
  import './scss/index.scss';
5
3
 
6
4
 
7
- export default template.factory<Parameters<typeof scrollbar>[0]>(
8
- (attributes, content) => {
9
- attributes.class = toArray(attributes.class);
10
- attributes.class.push('frame');
11
-
12
- return scrollbar(attributes, content);
5
+ export default scrollbar.bind({
6
+ attributes: {
7
+ class: 'frame'
13
8
  }
14
- );
9
+ });
@@ -1,53 +1,67 @@
1
1
  import { reactive } from '@esportsplus/reactivity'
2
- import { Element } from '@esportsplus/template';
2
+ import { html, Attributes } from '@esportsplus/template';
3
+ import { omit } from '@esportsplus/utilities';
4
+ import template from '~/components/template';
3
5
  import './scss/index.scss';
4
6
 
5
7
 
8
+ type A = Attributes & { background?: string };
9
+
10
+
11
+ const OMIT = ['background'];
12
+
13
+
6
14
  let key = Symbol(),
7
15
  observer: IntersectionObserver | null = null;
8
16
 
9
17
 
10
- export default (background: string) => {
11
- if (observer === null) {
12
- observer = new IntersectionObserver((entries) => {
13
- let disconnected = 0,
14
- n = entries.length;
18
+ export default template.factory(
19
+ (attributes: A, content) => {
20
+ if (observer === null) {
21
+ observer = new IntersectionObserver((entries) => {
22
+ let disconnected = 0,
23
+ n = entries.length;
15
24
 
16
- for (let i = 0; i < n; i++) {
17
- let { isIntersecting, target } = entries[i];
25
+ for (let i = 0; i < n; i++) {
26
+ let { isIntersecting, target } = entries[i];
18
27
 
19
- if (target.isConnected) {
20
- // @ts-ignore
21
- target[key].highlight = +isIntersecting;
28
+ if (target.isConnected) {
29
+ // @ts-ignore
30
+ target[key].highlight = +isIntersecting;
31
+ }
32
+ else {
33
+ disconnected++;
34
+ observer!.unobserve(target);
35
+ }
22
36
  }
23
- else {
24
- disconnected++;
25
- observer!.unobserve(target);
37
+
38
+ if (n - disconnected === 0) {
39
+ observer!.disconnect();
40
+ observer = null;
26
41
  }
27
- }
42
+ }, { threshold: 1 });
43
+ }
28
44
 
29
- if (n - disconnected === 0) {
30
- observer!.disconnect();
31
- observer = null;
32
- }
33
- }, { threshold: 1 });
34
- }
45
+ let state = reactive({
46
+ highlight: 0
47
+ });
35
48
 
36
- let state = reactive({
37
- highlight: 0
38
- });
39
-
40
- return {
41
- attributes: {
42
- class: 'highlight',
43
- onrender: function(element: Element) {
44
- element[key] = state;
45
- observer!.observe(element);
46
- },
47
- style: [
48
- () => `--highlight: ${state.highlight}`,
49
- `--background: ${background}`,
50
- ]
51
- }
52
- };
53
- }
49
+ return html`
50
+ <div class='highlight'
51
+ ${omit(attributes, OMIT)}
52
+ ${{
53
+ onrender: (element) => {
54
+ element[key] = state;
55
+ observer!.observe(element);
56
+ },
57
+ style: [
58
+ () => `--highlight: ${state.highlight}`,
59
+ `--background: ${attributes.background}`,
60
+ ]
61
+ }}
62
+ >
63
+ ${content}
64
+ </div>
65
+ `;
66
+ }
67
+ );
@@ -1,10 +1,10 @@
1
- import { html, Attributes, svg } from '@esportsplus/template';
1
+ import { html, svg } from '@esportsplus/template';
2
2
  import template from '~/components/template';
3
3
  import './scss/index.scss';
4
4
 
5
5
 
6
- export default template.factory<Attributes, Parameters<typeof svg.sprite>[0]>(
7
- (attributes, icon) => {
6
+ export default template.factory(
7
+ (attributes, icon: Parameters<typeof svg.sprite>[0]) => {
8
8
  return html`
9
9
  <div class='icon' ${attributes}>
10
10
  ${svg.sprite(icon)}
@@ -10,7 +10,6 @@ export * as container from './container';
10
10
  export { default as counter } from './counter';
11
11
  export { default as ellipsis } from './ellipsis';
12
12
  export { default as field } from './field';
13
- export { default as footer } from './footer';
14
13
  export { default as form } from './form';
15
14
  export * as frame from './frame';
16
15
  export * as grid from './grid';
@@ -24,12 +23,13 @@ export { default as loading } from './loading';
24
23
  export * as modal from './modal';
25
24
  export { default as number } from './number';
26
25
  export { default as overlay } from './overlay';
27
- export { default as page } from './page';
26
+ export * from './page';
28
27
  export { default as root } from './root';
29
28
  export * as row from './row';
30
29
  export { default as scrollbar } from './scrollbar';
31
30
  export { default as sidebar } from './sidebar';
32
31
  export { default as site } from './site';
32
+ export { default as template } from './template';
33
33
  export * as text from './text';
34
34
  export * as thumbnail from './thumbnail';
35
35
  export { default as tooltip } from './tooltip';
@@ -1,12 +1,13 @@
1
- import { html, Attributes } from '@esportsplus/template';
2
1
  import { reactive } from '@esportsplus/reactivity';
2
+ import { html } from '@esportsplus/template';
3
3
  import template from '~/components/template';
4
4
  import './scss/index.scss';
5
5
 
6
6
 
7
- export default template.factory<Attributes>(
7
+ export default template.factory(
8
8
  (attributes, content) => {
9
- let state = reactive({
9
+ let c = () => state.load && 'loader--load',
10
+ state = reactive({
10
11
  load: false,
11
12
  scale: false
12
13
  });
@@ -16,24 +17,21 @@ export default template.factory<Attributes>(
16
17
  }, 300);
17
18
 
18
19
  return html`
19
- <div class='loader ${() => state.load && 'loader--load'}'>
20
- <div class='loader ${() => state.load && 'loader--load'}'>
20
+ <div class='loader' ${{ class: c }}>
21
+ <div class='loader' ${{ class: c }}>
21
22
  <div class='loader-content'>
22
23
  <div
23
- class='
24
- ${() => state.scale && 'loader-logo--scale'}
25
- loader-logo
26
- text
27
- --flex-center
28
- --text-uppercase --text-600
29
- '
24
+ class='loader-logo text --flex-center --text-uppercase --text-600'
30
25
  style='color: var(--color-grey-500);'
31
- onanimationend='${({ animationName: name }: AnimationEvent) => {
32
- if (name === 'scale') {
33
- state.load = true;
34
- }
35
- }}'
36
26
  ${attributes}
27
+ ${{
28
+ class: () => state.scale && 'loader-logo--scale',
29
+ onanimationend: ({ animationName: name }) => {
30
+ if (name === 'scale') {
31
+ state.load = true;
32
+ }
33
+ }
34
+ }}
37
35
  >
38
36
  ${content}
39
37
  </div>
@@ -1,14 +1,9 @@
1
- import { toArray } from '@esportsplus/utilities';
2
1
  import scrollbar from '~/components/scrollbar';
3
- import template from '~/components/template';
4
2
  import './scss/index.scss';
5
3
 
6
4
 
7
- export default template.factory<Parameters<typeof scrollbar>[0]>(
8
- (attributes, content) => {
9
- attributes.class = toArray(attributes.class);
10
- attributes.class.push('overlay');
11
-
12
- return scrollbar(attributes, content);
5
+ export default scrollbar.bind({
6
+ attributes: {
7
+ class: 'overlay'
13
8
  }
14
- );
9
+ });
@@ -1,17 +1 @@
1
- import './scss/index.scss';
2
-
3
-
4
- const subtitle = {
5
- class: 'page-subtitle --margin-200 --text-crop-bottom'
6
- };
7
-
8
- const suptitle = {
9
- class: 'page-suptitle --text-bold-600 --text-crop --text-uppercase --text-300'
10
- };
11
-
12
- const title = {
13
- class: 'page-title --line-height-200 --margin-400 --text-crop'
14
- };
15
-
16
-
17
- export default { subtitle, suptitle, title };
1
+ import './scss/index.scss';
@@ -1,20 +1,19 @@
1
- let queue: (VoidFunction | (() => Promise<void>))[] = [];
1
+ import factory from '@esportsplus/queue';
2
2
 
3
3
 
4
- const onclick = async () => {
5
- if (queue.length === 0) {
6
- return;
7
- }
4
+ let queue = factory<VoidFunction | (() => Promise<void>)>(64);
8
5
 
6
+
7
+ const onclick = async () => {
9
8
  let item;
10
9
 
11
- while (item = queue.pop()) {
10
+ while (item = queue.next()) {
12
11
  await item();
13
12
  }
14
13
  };
15
14
 
16
15
  onclick.push = (fn: VoidFunction) => {
17
- queue.push(fn);
16
+ queue.add(fn);
18
17
  };
19
18
 
20
19
 
@@ -5,12 +5,18 @@ import template from '~/components/template';
5
5
  import './scss/index.scss';
6
6
 
7
7
 
8
+ type A = Attributes & { scrollbar?: Attributes, 'scrollbar-container-content'?: Attributes };
9
+
10
+
11
+ const OMIT = ['scrollbar', 'scrollbar-container-content'];
12
+
13
+
8
14
  let root = document.body,
9
15
  width: number | undefined;
10
16
 
11
17
 
12
- export default template.factory<Attributes & { scrollbar?: Attributes, 'scrollbar-container-content'?: Attributes }>(
13
- (attributes, content) => {
18
+ export default template.factory<A>(
19
+ function(attributes, content) {
14
20
  let state = reactive({
15
21
  height: 100,
16
22
  translate: 0
@@ -19,40 +25,45 @@ export default template.factory<Attributes & { scrollbar?: Attributes, 'scrollba
19
25
  return html`
20
26
  <div
21
27
  class='scrollbar-container'
22
- ${omit(attributes, ['scrollbar-container-content', 'scrollbar'])}
28
+ ${omit(attributes, OMIT)}
29
+ ${this.attributes && omit(this.attributes, OMIT)}
23
30
  >
24
31
  <div
25
32
  class='scrollbar-container-content'
26
- onscroll='${function(this: HTMLElement) {
27
- if (width === undefined) {
28
- width = this.offsetWidth - this.clientWidth;
33
+ ${attributes['scrollbar-container-content']}
34
+ ${this.attributes?.['scrollbar-container-content']}
35
+ ${{
36
+ onscroll: function() {
37
+ if (width === undefined) {
38
+ width = this.offsetWidth - this.clientWidth;
29
39
 
30
- if (width && width !== 17) {
31
- root.style.setProperty('--scrollbar-width', `${width}px`);
40
+ if (width && width !== 17) {
41
+ root.style.setProperty('--scrollbar-width', `${width}px`);
42
+ }
32
43
  }
33
- }
34
44
 
35
- state.height = (this.clientHeight / this.scrollHeight) * 100;
36
- state.translate = (this.scrollTop / this.clientHeight) * 100;
37
- }}'
38
- ${attributes['scrollbar-container-content']}
45
+ state.height = (this.clientHeight / this.scrollHeight) * 100;
46
+ state.translate = (this.scrollTop / this.clientHeight) * 100;
47
+ }
48
+ }}
39
49
  >
40
50
  ${content}
41
51
  </div>
42
52
 
43
53
  <div
44
- class='
45
- ${() => state.height >= 100 && 'scrollbar--hidden'}
46
- scrollbar
47
- '
48
- style='${() => `
49
- --translate: translate3d(0, ${state.translate}%, 0);
50
- --height: ${state.height}%;
51
- `}'
52
- ${attributes.scrollbar}
54
+ class='scrollbar'
55
+ ${this.attributes?.scrollbar}
56
+ ${{
57
+ class: () => state.height >= 100 && 'scrollbar--hidden',
58
+ style: () => `
59
+ --translate: translate3d(0, ${state.translate}%, 0);
60
+ --height: ${state.height}%;
61
+ `
62
+ }}
53
63
  >
54
64
  </div>
55
65
  </div>
56
66
  `;
57
67
  }
58
- );
68
+ );
69
+ export type { A as Attributes }
@@ -1,14 +1,9 @@
1
- import { toArray } from '@esportsplus/utilities';
2
1
  import scrollbar from '~/components/scrollbar';
3
- import template from '~/components/template';
4
2
  import './scss/index.scss';
5
3
 
6
4
 
7
- export default template.factory<Parameters<typeof scrollbar>[0]>(
8
- (attributes, content) => {
9
- attributes.class = toArray(attributes.class);
10
- attributes.class.push('sidebar');
11
-
12
- return scrollbar(attributes, content);
5
+ export default scrollbar.bind({
6
+ attributes: {
7
+ class: 'sidebar'
13
8
  }
14
- );
9
+ });
@@ -1,19 +1,11 @@
1
- import { toArray } from '@esportsplus/utilities';
2
1
  import { onclick } from '~/components/root';
3
2
  import scrollbar from '~/components/scrollbar';
4
- import template from '~/components/template';
5
3
  import './scss/index.scss';
6
4
 
7
5
 
8
- export default template.factory<Parameters<typeof scrollbar>[0]>(
9
- (attributes, content) => {
10
- attributes.class = toArray(attributes.class);
11
- attributes.class.push('site');
12
-
13
- attributes.onclick = onclick;
14
-
15
- attributes.style ??= '--background-default: var(--color-black-400);';
16
-
17
- return scrollbar(attributes, content);
6
+ export default scrollbar.bind({
7
+ attributes: {
8
+ class: 'site',
9
+ onclick
18
10
  }
19
- );
11
+ });
@@ -1,25 +1,33 @@
1
- import { Renderable } from '@esportsplus/template';
1
+ import { Attributes, Renderable } from '@esportsplus/template';
2
+ import { EMPTY_OBJECT } from '@esportsplus/utilities';
2
3
 
3
4
 
4
- const factory = <A extends Record<string, unknown>, C = unknown>(template: (attributes: A, content: C) => Renderable) => {
5
- function factory(content: C): Renderable;
6
- function factory(attributes: A, content: C): Renderable;
7
- function factory(one: A | C, two?: C): Renderable {
8
- let content: C,
9
- attributes: A = {} as A;
5
+ const factory = <
6
+ A extends Attributes,
7
+ C = Renderable<unknown>,
8
+ Context = { attributes?: A, content?: C }
9
+ >(
10
+ template: (this: Context, attributes: Readonly<A>, content: C) => Renderable<unknown>
11
+ ) => {
12
+ function factory(): Renderable<unknown>;
13
+ function factory(content: C): Renderable<unknown>;
14
+ function factory(attributes: A, content: C): Renderable<unknown>;
15
+ function factory(this: Context, one?: A | C, two?: C): Renderable<unknown> {
16
+ let attributes: A = {} as A,
17
+ content: C;
10
18
 
11
19
  if (two === undefined) {
12
20
  content = one as C;
13
21
  }
14
22
  else {
15
- content = two;
16
23
  attributes = one as A;
24
+ content = two;
17
25
  }
18
26
 
19
- return template(attributes, content);
27
+ return template.call(this, attributes, content);
20
28
  }
21
29
 
22
- return factory;
30
+ return factory.bind(EMPTY_OBJECT);
23
31
  };
24
32
 
25
33