jb-grid 0.3.1 → 0.3.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +3 -1
- package/web-component/dist/cell/cell.d.ts +9 -0
- package/web-component/dist/cell/cell.d.ts.map +1 -0
- package/web-component/dist/cell/render.d.ts +2 -0
- package/web-component/dist/cell/render.d.ts.map +1 -0
- package/web-component/dist/cell/types.d.ts +2 -0
- package/web-component/dist/cell/types.d.ts.map +1 -0
- package/web-component/dist/index.cjs.js +2 -0
- package/web-component/dist/index.cjs.js.br +0 -0
- package/web-component/dist/index.cjs.js.gz +0 -0
- package/web-component/dist/index.cjs.js.map +1 -0
- package/web-component/dist/index.d.ts +5 -0
- package/web-component/dist/index.d.ts.map +1 -0
- package/web-component/dist/index.js +2 -0
- package/web-component/dist/index.js.br +0 -0
- package/web-component/dist/index.js.gz +0 -0
- package/web-component/dist/index.js.map +1 -0
- package/web-component/dist/index.umd.js +2 -0
- package/web-component/dist/index.umd.js.br +0 -0
- package/web-component/dist/index.umd.js.gz +0 -0
- package/web-component/dist/index.umd.js.map +1 -0
- package/web-component/dist/pagination/pagination.d.ts +13 -0
- package/web-component/dist/pagination/pagination.d.ts.map +1 -0
- package/web-component/dist/pagination/render.d.ts +2 -0
- package/web-component/dist/pagination/render.d.ts.map +1 -0
- package/web-component/dist/pagination/types.d.ts +18 -0
- package/web-component/dist/pagination/types.d.ts.map +1 -0
- package/web-component/dist/row/render.d.ts +2 -0
- package/web-component/dist/row/render.d.ts.map +1 -0
- package/web-component/dist/row/row.d.ts +12 -0
- package/web-component/dist/row/row.d.ts.map +1 -0
- package/web-component/dist/row/types.d.ts +9 -0
- package/web-component/dist/row/types.d.ts.map +1 -0
- package/web-component/dist/row/utils.d.ts +3 -0
- package/web-component/dist/row/utils.d.ts.map +1 -0
- package/web-component/dist/toggle/expand-toggle.d.ts +7 -0
- package/web-component/dist/toggle/expand-toggle.d.ts.map +1 -0
- package/web-component/dist/toggle/render.d.ts +2 -0
- package/web-component/dist/toggle/render.d.ts.map +1 -0
- package/web-component/dist/toggle/types.d.ts +1 -0
- package/web-component/dist/toggle/types.d.ts.map +1 -0
- package/web-component/lib/cell/cell.ts +50 -0
- package/web-component/lib/cell/render.ts +5 -0
- package/web-component/lib/cell/style.css +16 -0
- package/web-component/lib/cell/types.ts +3 -0
- package/web-component/lib/global.d.ts +15 -0
- package/web-component/lib/index.ts +4 -0
- package/web-component/lib/pagination/pagination.ts +211 -0
- package/web-component/lib/pagination/render.ts +22 -0
- package/web-component/lib/pagination/style.css +86 -0
- package/web-component/lib/pagination/types.ts +15 -0
- package/web-component/lib/row/render.ts +12 -0
- package/web-component/lib/row/row.ts +61 -0
- package/web-component/lib/row/style.css +55 -0
- package/web-component/lib/row/types.ts +8 -0
- package/web-component/lib/row/utils.ts +40 -0
- package/web-component/lib/toggle/expand-toggle.ts +53 -0
- package/web-component/lib/toggle/render.ts +13 -0
- package/web-component/lib/toggle/style.css +25 -0
- package/web-component/tsconfig.json +17 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/toggle/types.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { renderHTML } from './render.js';
|
|
2
|
+
import CSS from './style.css';
|
|
3
|
+
import { registerDefaultVariables } from 'jb-core/theme';
|
|
4
|
+
import type {JBCellElements} from './types.js';
|
|
5
|
+
|
|
6
|
+
export * from "./types.js";
|
|
7
|
+
export class JBCellWebComponent extends HTMLElement {
|
|
8
|
+
#elements!: JBCellElements;
|
|
9
|
+
#templateSheet = new CSSStyleSheet();
|
|
10
|
+
get name(){
|
|
11
|
+
return this.getAttribute("name")||""
|
|
12
|
+
}
|
|
13
|
+
set name(value:string){
|
|
14
|
+
this.setAttribute("name",value);
|
|
15
|
+
this.#templateSheet.replace(`
|
|
16
|
+
:host{ grid-area:${value?value:"none"}}
|
|
17
|
+
@container (style(--jb-row-grid-mode: auto)) {
|
|
18
|
+
:host{ grid-area:auto }
|
|
19
|
+
}
|
|
20
|
+
`);
|
|
21
|
+
}
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
this.#init();
|
|
25
|
+
}
|
|
26
|
+
#init() {
|
|
27
|
+
const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true, clonable:true, serializable:true });
|
|
28
|
+
shadowRoot.adoptedStyleSheets = [this.#templateSheet];
|
|
29
|
+
registerDefaultVariables();
|
|
30
|
+
this.#render();
|
|
31
|
+
this.#elements = {
|
|
32
|
+
}
|
|
33
|
+
this.#registerEventListener();
|
|
34
|
+
}
|
|
35
|
+
#render() {
|
|
36
|
+
const html = `<style>${CSS}</style>\n${renderHTML()}`;
|
|
37
|
+
const element = document.createElement("template");
|
|
38
|
+
element.innerHTML = html;
|
|
39
|
+
this.shadowRoot!.appendChild(element.content.cloneNode(true));
|
|
40
|
+
}
|
|
41
|
+
connectedCallback() {
|
|
42
|
+
}
|
|
43
|
+
#registerEventListener() {
|
|
44
|
+
// this.#elements.nav.next.addEventListener('click', ()=>this.#goToNextPage(true));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
const myElementNotExists = !customElements.get('jb-cell');
|
|
48
|
+
if (myElementNotExists) {
|
|
49
|
+
window.customElements.define('jb-cell', JBCellWebComponent);
|
|
50
|
+
}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
@custom-media --tablet-until (max-width: 768px);
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
width: 100%;
|
|
5
|
+
height: 100%;
|
|
6
|
+
display: grid;
|
|
7
|
+
grid-template-columns: auto;
|
|
8
|
+
grid-template-rows: auto;
|
|
9
|
+
grid-auto-flow: column;
|
|
10
|
+
grid-auto-columns: max-content;
|
|
11
|
+
padding: 0.25rem 1rem;
|
|
12
|
+
box-sizing: border-box;
|
|
13
|
+
align-items: center;
|
|
14
|
+
justify-content: start;
|
|
15
|
+
gap:0.5rem;
|
|
16
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
type FileStringModules = {
|
|
2
|
+
readonly default: string;
|
|
3
|
+
}
|
|
4
|
+
declare module '*.css' {
|
|
5
|
+
const value: FileStringModules;
|
|
6
|
+
export default value;
|
|
7
|
+
}
|
|
8
|
+
declare module '*.html' {
|
|
9
|
+
const value: FileStringModules;
|
|
10
|
+
export default value.default;
|
|
11
|
+
}
|
|
12
|
+
declare module '*.svg' {
|
|
13
|
+
const value: string;
|
|
14
|
+
export default value;
|
|
15
|
+
}
|
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { renderHTML } from './render';
|
|
2
|
+
import CSS from './style.css';
|
|
3
|
+
import { registerDefaultVariables } from 'jb-core/theme';
|
|
4
|
+
import type { JBPaginationElements, PageIndexDom } from './types.js';
|
|
5
|
+
import { i18n } from "jb-core/i18n";
|
|
6
|
+
import {enToFaDigits} from 'jb-core';
|
|
7
|
+
export class JBPaginationWebComponent extends HTMLElement {
|
|
8
|
+
#elements!: JBPaginationElements;
|
|
9
|
+
#pageIndex: number = 1;
|
|
10
|
+
#min = 1;
|
|
11
|
+
#max = Infinity;
|
|
12
|
+
//how many number in display
|
|
13
|
+
#DisplayIndexCount = 3;
|
|
14
|
+
showPersianNumber = i18n.locale.numberingSystem == "arabext";
|
|
15
|
+
|
|
16
|
+
//how many number item we have in dom
|
|
17
|
+
get #indexButtonCount (){
|
|
18
|
+
return this.#DisplayIndexCount + 2; /* for 2 hidden button in start and end of the list */
|
|
19
|
+
}
|
|
20
|
+
get pageIndex(){
|
|
21
|
+
return this.#pageIndex;
|
|
22
|
+
}
|
|
23
|
+
set pageIndex(value:number){
|
|
24
|
+
this.#goToPage(value,false);
|
|
25
|
+
}
|
|
26
|
+
get max() {
|
|
27
|
+
return this.#max;
|
|
28
|
+
}
|
|
29
|
+
set max(value: number) {
|
|
30
|
+
this.#max = value;
|
|
31
|
+
if (this.pageIndex > value) {
|
|
32
|
+
this.#updatePageIndex(value,false);
|
|
33
|
+
}
|
|
34
|
+
this.#elements.nav.last.disabled = this.#max == Infinity;
|
|
35
|
+
}
|
|
36
|
+
get min() {
|
|
37
|
+
return this.#min;
|
|
38
|
+
}
|
|
39
|
+
set min(value: number) {
|
|
40
|
+
this.#min = value;
|
|
41
|
+
if (this.#pageIndex < value) {
|
|
42
|
+
this.#updatePageIndex(value, false);
|
|
43
|
+
}
|
|
44
|
+
this.#elements.nav.first.disabled = this.#min == Infinity;
|
|
45
|
+
}
|
|
46
|
+
constructor() {
|
|
47
|
+
super();
|
|
48
|
+
this.#init();
|
|
49
|
+
}
|
|
50
|
+
#init() {
|
|
51
|
+
const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true, clonable:true, serializable:true });
|
|
52
|
+
registerDefaultVariables();
|
|
53
|
+
this.#render();
|
|
54
|
+
this.#elements = {
|
|
55
|
+
nav: {
|
|
56
|
+
wrapper: shadowRoot.querySelector('.page-navigator') as HTMLDivElement,
|
|
57
|
+
first: shadowRoot.querySelector('.first-page') as HTMLButtonElement,
|
|
58
|
+
last: shadowRoot.querySelector('.last-page') as HTMLButtonElement,
|
|
59
|
+
next: shadowRoot.querySelector('.next-page') as HTMLButtonElement,
|
|
60
|
+
prev: shadowRoot.querySelector('.prev-page') as HTMLButtonElement,
|
|
61
|
+
},
|
|
62
|
+
index: {
|
|
63
|
+
wrapper: shadowRoot.querySelector('.page-index-wrapper') as HTMLDivElement,
|
|
64
|
+
list: []
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
this.#registerEventListener();
|
|
68
|
+
//TODO: do it after pageSize determined
|
|
69
|
+
this.#initPageIndexes();
|
|
70
|
+
// To retrigger setter effects
|
|
71
|
+
this.max = Infinity;
|
|
72
|
+
this.min = 1;
|
|
73
|
+
}
|
|
74
|
+
#render() {
|
|
75
|
+
const html = `<style>${CSS}</style>\n${renderHTML()}`;
|
|
76
|
+
const element = document.createElement("template");
|
|
77
|
+
element.innerHTML = html;
|
|
78
|
+
this.shadowRoot!.appendChild(element.content.cloneNode(true));
|
|
79
|
+
}
|
|
80
|
+
connectedCallback() {
|
|
81
|
+
}
|
|
82
|
+
#registerEventListener() {
|
|
83
|
+
this.#elements.nav.next.addEventListener('click', ()=>this.#goToNextPage(true));
|
|
84
|
+
this.#elements.nav.prev.addEventListener('click', ()=>this.#goToPrevPage(true));
|
|
85
|
+
this.#elements.nav.last.addEventListener('click', ()=>{this.#goToPage(this.#max,true)});
|
|
86
|
+
this.#elements.nav.first.addEventListener('click', ()=>{this.#goToPage(this.#min,true)});
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
#goToNextPage(shouldDispatch:boolean) {
|
|
90
|
+
if (this.#pageIndex > this.#max - 1) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
const newIndex = this.#pageIndex + 1
|
|
94
|
+
const indexDom = this.#createPageIndexElement(newIndex + 2)
|
|
95
|
+
this.#elements.index.list.shift()?.remove();
|
|
96
|
+
this.#elements.index.wrapper.append(indexDom);
|
|
97
|
+
this.#elements.index.list.push(indexDom);
|
|
98
|
+
this.#updatePageIndex(newIndex, shouldDispatch)
|
|
99
|
+
}
|
|
100
|
+
#goToPrevPage(shouldDispatch:boolean) {
|
|
101
|
+
if (this.#pageIndex < this.#min + 1) {
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
const newIndex = this.#pageIndex - 1
|
|
105
|
+
const indexDom = this.#createPageIndexElement(newIndex - 2)
|
|
106
|
+
this.#elements.index.list.pop()?.remove();
|
|
107
|
+
this.#elements.index.list.unshift(indexDom);
|
|
108
|
+
this.#elements.index.wrapper.prepend(indexDom);
|
|
109
|
+
this.#updatePageIndex(newIndex,shouldDispatch)
|
|
110
|
+
}
|
|
111
|
+
#goToPage(newPageIndex: number,shouldDispatch:boolean) {
|
|
112
|
+
if(this.#pageIndex == newPageIndex){
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const diff = newPageIndex - this.#pageIndex;
|
|
116
|
+
if(Math.abs(diff)>1){
|
|
117
|
+
this.#updatePageIndex(newPageIndex,shouldDispatch);
|
|
118
|
+
this.#initPageIndexes();
|
|
119
|
+
}else{
|
|
120
|
+
//play with animation
|
|
121
|
+
diff>0?this.#goToNextPage(shouldDispatch):this.#goToPrevPage(shouldDispatch);
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* place pageIndex element in position in data and dom structure
|
|
126
|
+
*/
|
|
127
|
+
#putPageIndexElement(element: PageIndexDom) {
|
|
128
|
+
if(this.#elements.index.list.find(x=>x.pageIndex == element.pageIndex)){
|
|
129
|
+
//already exist
|
|
130
|
+
return;
|
|
131
|
+
}
|
|
132
|
+
let removePosition:'end'|'start' = 'end';
|
|
133
|
+
if (this.#elements.index.list.length == 0 || this.#elements.index.list[this.#elements.index.list.length - 1]?.pageIndex < element.pageIndex) {
|
|
134
|
+
//put in last
|
|
135
|
+
this.#elements.index.list.push(element);
|
|
136
|
+
this.#elements.index.wrapper.append(element);
|
|
137
|
+
//remove first item to keep array in size
|
|
138
|
+
removePosition = 'start';
|
|
139
|
+
} else if (this.#elements.index.list[0]?.pageIndex > element.pageIndex) {
|
|
140
|
+
// put in first
|
|
141
|
+
this.#elements.index.list.unshift(element)
|
|
142
|
+
this.#elements.index.wrapper.prepend(element);
|
|
143
|
+
} else {
|
|
144
|
+
// in rare situation when element in the middle of the list
|
|
145
|
+
const index = this.#elements.index.list.findIndex((x) => x?.pageIndex > element.pageIndex);
|
|
146
|
+
this.#elements.index.wrapper.insertBefore(element, this.#elements.index.list[index]);
|
|
147
|
+
this.#elements.index.list.splice(index, 0, element);
|
|
148
|
+
}
|
|
149
|
+
if(this.#elements.index.list.length>this.#indexButtonCount){
|
|
150
|
+
//remove redundant elements
|
|
151
|
+
removePosition == 'end'?this.#elements.index.list.pop()?.remove():this.#elements.index.list.shift()?.remove();
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
#createPageIndexElement(newIndex: number): PageIndexDom {
|
|
155
|
+
//when we are out of bound we create empty page index
|
|
156
|
+
const isEmpty = this.#min > newIndex || this.#max < newIndex;
|
|
157
|
+
const elem = document.createElement('div') as PageIndexDom;
|
|
158
|
+
elem.classList.add('page-index', isEmpty?'empty':'not-empty');
|
|
159
|
+
elem.dataset.index = `${newIndex}`;
|
|
160
|
+
elem.pageIndex = newIndex;
|
|
161
|
+
elem.addEventListener("click", (e) => {
|
|
162
|
+
this.#onPageIndexClick(elem);
|
|
163
|
+
});
|
|
164
|
+
if (isEmpty) {
|
|
165
|
+
elem.isEmpty = true;
|
|
166
|
+
} else {
|
|
167
|
+
elem.isEmpty = false;
|
|
168
|
+
elem.innerHTML = `${this.showPersianNumber?enToFaDigits(newIndex):newIndex}`;
|
|
169
|
+
}
|
|
170
|
+
return elem;
|
|
171
|
+
}
|
|
172
|
+
#onPageIndexClick(item: PageIndexDom) {
|
|
173
|
+
if (item.isEmpty) {
|
|
174
|
+
return;
|
|
175
|
+
}
|
|
176
|
+
this.#goToPage(item.pageIndex,true);
|
|
177
|
+
}
|
|
178
|
+
/**
|
|
179
|
+
* this event must call when we update pageindex inside of component by user interaction and not programmer
|
|
180
|
+
*/
|
|
181
|
+
#updatePageIndex(newIndex: number,shouldDispatch:boolean) {
|
|
182
|
+
this.#pageIndex = newIndex;
|
|
183
|
+
this.#updateActiveIndex(newIndex);
|
|
184
|
+
shouldDispatch && this.#dispatchChangeEvent();
|
|
185
|
+
}
|
|
186
|
+
#updateActiveIndex(newIndex: number) {
|
|
187
|
+
this.#elements.index.wrapper.querySelector(".current")?.classList.remove('current');
|
|
188
|
+
this.#elements.index.list.forEach(x => {
|
|
189
|
+
if (x.pageIndex == newIndex) {
|
|
190
|
+
x.classList.add('current')
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
}
|
|
194
|
+
#dispatchChangeEvent() {
|
|
195
|
+
const event = new Event('change', { cancelable: false, composed: true, bubbles: true })
|
|
196
|
+
this.dispatchEvent(event);
|
|
197
|
+
}
|
|
198
|
+
#initPageIndexes() {
|
|
199
|
+
this.#putPageIndexElement(this.#createPageIndexElement(this.#pageIndex - 2));
|
|
200
|
+
this.#putPageIndexElement(this.#createPageIndexElement(this.#pageIndex - 1));
|
|
201
|
+
this.#putPageIndexElement(this.#createPageIndexElement(this.#pageIndex));
|
|
202
|
+
this.#putPageIndexElement(this.#createPageIndexElement(this.#pageIndex + 1));
|
|
203
|
+
this.#putPageIndexElement(this.#createPageIndexElement(this.#pageIndex + 2));
|
|
204
|
+
this.#updateActiveIndex(this.#pageIndex);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
const myElementNotExists = !customElements.get('jb-pagination');
|
|
209
|
+
if (myElementNotExists) {
|
|
210
|
+
window.customElements.define('jb-pagination', JBPaginationWebComponent);
|
|
211
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
export function renderHTML(): string {
|
|
2
|
+
return /* html */ `
|
|
3
|
+
<div class="jb-pagination-web-component">
|
|
4
|
+
<section class="page-navigator">
|
|
5
|
+
<button class="first-page arrow-btn">
|
|
6
|
+
<svg width="100%" height="100%" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet"><title>first page</title><path d="M7 6 v12 h2 v-12 h-2z M17.41 7.41L16 6l-6 6 6 6 1.41-1.41L12.83 12z"></path></svg>
|
|
7
|
+
</button>
|
|
8
|
+
<button class="prev-page arrow-btn">
|
|
9
|
+
<svg width="100%" height="100%" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet"><title>prev page</title><path d="M15.41 7.41L14 6l-6 6 6 6 1.41-1.41L10.83 12z"></path></svg>
|
|
10
|
+
</button>
|
|
11
|
+
<div class="page-index-wrapper">
|
|
12
|
+
</div>
|
|
13
|
+
<button class="next-page arrow-btn">
|
|
14
|
+
<svg width="100%" height="100%" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet"><title>previous page</title><path d="M10 6L8.59 7.41 13.17 12l-4.58 4.59L10 18l6-6z"></path></svg>
|
|
15
|
+
</button>
|
|
16
|
+
<button class="last-page arrow-btn">
|
|
17
|
+
<svg width="100%" height="100%" viewBox="0 0 24 24" preserveAspectRatio="xMidYMid meet"><title>last page</title><path d="M15 6 v12 h2 v-12 h-2z M8 6L6.59 7.41 11.17 12l-4.58 4.59L8 18l6-6z"></path></svg>
|
|
18
|
+
</button>
|
|
19
|
+
</section>
|
|
20
|
+
</div>
|
|
21
|
+
`;
|
|
22
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
:host {
|
|
2
|
+
/*width of each page index number button*/
|
|
3
|
+
--jb-pagination-index-width: 3rem;
|
|
4
|
+
}
|
|
5
|
+
|
|
6
|
+
.jb-pagination-web-component {
|
|
7
|
+
display: flex;
|
|
8
|
+
gap: 1rem;
|
|
9
|
+
direction:ltr;
|
|
10
|
+
.page-navigator {
|
|
11
|
+
display: grid;
|
|
12
|
+
grid-template-columns: 4rem 4rem max-content 4rem 4rem;
|
|
13
|
+
grid-template-rows: 3rem;
|
|
14
|
+
justify-items: center;
|
|
15
|
+
align-items: center;
|
|
16
|
+
|
|
17
|
+
.arrow-btn {
|
|
18
|
+
all: unset;
|
|
19
|
+
cursor: pointer;
|
|
20
|
+
height: 3rem;
|
|
21
|
+
width: 3rem;
|
|
22
|
+
fill: var(--jb-neutral-2);
|
|
23
|
+
&:disabled {
|
|
24
|
+
fill: var(--jb-neutral-7);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
.page-index-wrapper {
|
|
29
|
+
position: relative;
|
|
30
|
+
width: calc(var(--jb-pagination-index-width) * 3);
|
|
31
|
+
overflow: hidden;
|
|
32
|
+
height: 100%;
|
|
33
|
+
|
|
34
|
+
.page-index {
|
|
35
|
+
font-size: 1rem;
|
|
36
|
+
color: var(--jb-neutral-6);
|
|
37
|
+
position: absolute;
|
|
38
|
+
width: var(--jb-pagination-index-width);
|
|
39
|
+
height: 3rem;
|
|
40
|
+
display: flex;
|
|
41
|
+
justify-content: center;
|
|
42
|
+
align-items: center;
|
|
43
|
+
text-box-trim: trim-both;
|
|
44
|
+
text-box-edge: ex alphabetic;
|
|
45
|
+
transition: all 0.3s 0s ease;
|
|
46
|
+
cursor: pointer;
|
|
47
|
+
|
|
48
|
+
&.current {
|
|
49
|
+
color: var(--jb-primary);
|
|
50
|
+
transform: scale(120%);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
&.empty {
|
|
54
|
+
cursor: default;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
.page-index:nth-child(1) {
|
|
59
|
+
top: 0;
|
|
60
|
+
left: calc(var(--jb-pagination-index-width) * -1);
|
|
61
|
+
transform: scale(10%);
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
.page-index:nth-child(2) {
|
|
65
|
+
top: 0;
|
|
66
|
+
left: 0;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
.page-index:nth-child(3) {
|
|
70
|
+
top: 0;
|
|
71
|
+
left: calc(var(--jb-pagination-index-width));
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
.page-index:nth-child(4) {
|
|
75
|
+
top: 0;
|
|
76
|
+
left: calc(var(--jb-pagination-index-width) * 2);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
.page-index:nth-child(5) {
|
|
80
|
+
top: 0;
|
|
81
|
+
left: calc(var(--jb-pagination-index-width) * 3);
|
|
82
|
+
transform: scale(10%);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export type JBPaginationElements = {
|
|
2
|
+
nav:{
|
|
3
|
+
wrapper:HTMLDivElement,
|
|
4
|
+
first:HTMLButtonElement,
|
|
5
|
+
prev:HTMLButtonElement,
|
|
6
|
+
next:HTMLButtonElement,
|
|
7
|
+
last:HTMLButtonElement,
|
|
8
|
+
},
|
|
9
|
+
index:{
|
|
10
|
+
wrapper:HTMLDivElement,
|
|
11
|
+
list:PageIndexDom[],
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export type PageIndexDom = HTMLDivElement & {pageIndex:number,isEmpty:boolean};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export function renderHTML(): string {
|
|
2
|
+
return /* html */ `
|
|
3
|
+
<div class="jb-row-web-component">
|
|
4
|
+
<div class="grid-row" part="row">
|
|
5
|
+
<slot name="cell"></slot>
|
|
6
|
+
</div>
|
|
7
|
+
<div class="expand-wrapper --hidden">
|
|
8
|
+
<slot name="expand"></slot>
|
|
9
|
+
</div>
|
|
10
|
+
</div>
|
|
11
|
+
`;
|
|
12
|
+
}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { renderHTML } from './render.js';
|
|
2
|
+
import CSS from './style.css';
|
|
3
|
+
import { registerDefaultVariables } from 'jb-core/theme';
|
|
4
|
+
import type { JBRowElements, RowTemplate} from './types.js';
|
|
5
|
+
import { createTemplateStylesheet } from './utils.js';
|
|
6
|
+
|
|
7
|
+
export * from "./types.js";
|
|
8
|
+
export class JBRowWebComponent extends HTMLElement {
|
|
9
|
+
#elements!: JBRowElements;
|
|
10
|
+
#templateSheet = new CSSStyleSheet();
|
|
11
|
+
#RowTemplate:RowTemplate = []
|
|
12
|
+
#isOpen = false;
|
|
13
|
+
get isOpen(){
|
|
14
|
+
return this.#isOpen;
|
|
15
|
+
}
|
|
16
|
+
set isOpen(value:boolean){
|
|
17
|
+
this.#isOpen = value;
|
|
18
|
+
if(value){
|
|
19
|
+
this.#elements.expandWrapper.classList.remove('--hidden');
|
|
20
|
+
}else{
|
|
21
|
+
this.#elements.expandWrapper.classList.add('--hidden');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
get rowTemplate(){
|
|
25
|
+
return this.#RowTemplate
|
|
26
|
+
}
|
|
27
|
+
set rowTemplate(value:RowTemplate){
|
|
28
|
+
this.#RowTemplate = value;
|
|
29
|
+
createTemplateStylesheet(this.#templateSheet,value);
|
|
30
|
+
}
|
|
31
|
+
constructor() {
|
|
32
|
+
super();
|
|
33
|
+
this.#init();
|
|
34
|
+
}
|
|
35
|
+
#init() {
|
|
36
|
+
const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true, clonable:true, serializable:true });
|
|
37
|
+
shadowRoot.adoptedStyleSheets = [this.#templateSheet];
|
|
38
|
+
registerDefaultVariables();
|
|
39
|
+
this.#render();
|
|
40
|
+
this.#elements = {
|
|
41
|
+
expandWrapper: shadowRoot.querySelector(".expand-wrapper")!
|
|
42
|
+
}
|
|
43
|
+
createTemplateStylesheet(this.#templateSheet,null);
|
|
44
|
+
this.#registerEventListener();
|
|
45
|
+
}
|
|
46
|
+
#render() {
|
|
47
|
+
const html = `<style>${CSS}</style>\n${renderHTML()}`;
|
|
48
|
+
const element = document.createElement("template");
|
|
49
|
+
element.innerHTML = html;
|
|
50
|
+
this.shadowRoot!.appendChild(element.content.cloneNode(true));
|
|
51
|
+
}
|
|
52
|
+
connectedCallback() {
|
|
53
|
+
}
|
|
54
|
+
#registerEventListener() {
|
|
55
|
+
// this.#elements.nav.next.addEventListener('click', ()=>this.#goToNextPage(true));
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
const myElementNotExists = !customElements.get('jb-row');
|
|
59
|
+
if (myElementNotExists) {
|
|
60
|
+
window.customElements.define('jb-row', JBRowWebComponent);
|
|
61
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
@custom-media --tablet-until (max-width: 768px);
|
|
2
|
+
|
|
3
|
+
:host {
|
|
4
|
+
width: 100%;
|
|
5
|
+
background-color: var(--jb-white);
|
|
6
|
+
display: block;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
:host(:nth-of-type(even)) {
|
|
10
|
+
background: var(--jb-neutral-10);
|
|
11
|
+
|
|
12
|
+
@media(--tablet-until) {
|
|
13
|
+
background: var(--jb-white);
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
.jb-row-web-component {
|
|
18
|
+
.grid-row {
|
|
19
|
+
width: 100%;
|
|
20
|
+
box-sizing: border-box;
|
|
21
|
+
grid-auto-rows: minmax(3rem, auto);
|
|
22
|
+
|
|
23
|
+
@media(--tablet-until) {
|
|
24
|
+
grid-template-columns: auto !important;
|
|
25
|
+
grid-template-rows: auto;
|
|
26
|
+
border-radius: var(--jb-radius);
|
|
27
|
+
box-shadow: 0px 0px 1px 0px #d8d8d8;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
.expand-wrapper {
|
|
32
|
+
interpolate-size: allow-keywords;
|
|
33
|
+
transition: all 0.3s 0s ease;
|
|
34
|
+
height: auto;
|
|
35
|
+
overflow: clip;
|
|
36
|
+
opacity: 1;
|
|
37
|
+
&.--hidden {
|
|
38
|
+
height: 0;
|
|
39
|
+
min-height: 0;
|
|
40
|
+
padding-block: 0;
|
|
41
|
+
opacity: 0;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
slot[name="expand"]::slotted(*) {
|
|
45
|
+
width: 100%;
|
|
46
|
+
min-height: 4rem;
|
|
47
|
+
padding-block: 1rem;
|
|
48
|
+
padding-inline: 2rem;
|
|
49
|
+
border-bottom: 1px solid #ebebeb;
|
|
50
|
+
box-sizing: border-box;
|
|
51
|
+
overflow: auto;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type { RowTemplate } from "./types";
|
|
2
|
+
|
|
3
|
+
export function createTemplateStylesheet(sheet: CSSStyleSheet, template: RowTemplate | null) {
|
|
4
|
+
if (template === null) {
|
|
5
|
+
const css = /* css */ `
|
|
6
|
+
.grid-row{
|
|
7
|
+
display:grid;
|
|
8
|
+
grid-auto-columns: 1fr;
|
|
9
|
+
grid-auto-flow: column;
|
|
10
|
+
grid-template-rows: 1fr;
|
|
11
|
+
--jb-row-grid-mode: auto;
|
|
12
|
+
}
|
|
13
|
+
`
|
|
14
|
+
sheet.replaceSync(css);
|
|
15
|
+
return sheet;
|
|
16
|
+
}
|
|
17
|
+
let gridTemplateColumns = "";
|
|
18
|
+
const gridTemplateAreas = template.map(t => `${t.name}`).join(" ");
|
|
19
|
+
template.forEach((item) => {
|
|
20
|
+
if (item.size != null || item.size != undefined) {
|
|
21
|
+
if (typeof item.size == "number") {
|
|
22
|
+
gridTemplateColumns += ` ${item.size}px`;
|
|
23
|
+
} else {
|
|
24
|
+
gridTemplateColumns += ` ${item.size}`;
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
} else {
|
|
28
|
+
gridTemplateColumns += " 1fr";
|
|
29
|
+
}
|
|
30
|
+
});
|
|
31
|
+
const css = /* css */ `
|
|
32
|
+
.grid-row{
|
|
33
|
+
display:grid;
|
|
34
|
+
grid-template-columns: ${gridTemplateColumns};
|
|
35
|
+
grid-template-areas: "${gridTemplateAreas}"
|
|
36
|
+
}
|
|
37
|
+
`
|
|
38
|
+
sheet.replaceSync(css);
|
|
39
|
+
return sheet;
|
|
40
|
+
}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { renderHTML } from './render.js';
|
|
2
|
+
import CSS from './style.css';
|
|
3
|
+
import { registerDefaultVariables } from 'jb-core/theme';
|
|
4
|
+
import { JBRowWebComponent } from '../row/row.js';
|
|
5
|
+
export class JBExpandToggleWebComponent extends HTMLElement {
|
|
6
|
+
constructor() {
|
|
7
|
+
super();
|
|
8
|
+
this.#init();
|
|
9
|
+
}
|
|
10
|
+
#init() {
|
|
11
|
+
const shadowRoot = this.attachShadow({ mode: 'open', delegatesFocus: true, clonable:true, serializable:true });
|
|
12
|
+
registerDefaultVariables();
|
|
13
|
+
this.#render();
|
|
14
|
+
this.#registerEventListener();
|
|
15
|
+
}
|
|
16
|
+
#render() {
|
|
17
|
+
const html = `<style>${CSS}</style>\n${renderHTML()}`;
|
|
18
|
+
const element = document.createElement("template");
|
|
19
|
+
element.innerHTML = html;
|
|
20
|
+
this.shadowRoot!.appendChild(element.content.cloneNode(true));
|
|
21
|
+
}
|
|
22
|
+
#parentRow:JBRowWebComponent|null = null;
|
|
23
|
+
connectedCallback() {
|
|
24
|
+
this.#parentRow = this.#findParentRow(this);
|
|
25
|
+
if(this.#parentRow?.isOpen){
|
|
26
|
+
this.setAttribute('open','');
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
#findParentRow(element:Element|null):JBRowWebComponent|null{
|
|
30
|
+
if(!element || !element.parentElement){
|
|
31
|
+
return null;
|
|
32
|
+
}
|
|
33
|
+
if(element.parentElement instanceof JBRowWebComponent){
|
|
34
|
+
return element.parentElement
|
|
35
|
+
}else{
|
|
36
|
+
return this.#findParentRow(this.parentElement!);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
#registerEventListener() {
|
|
40
|
+
this.addEventListener('click', ()=>this.toggle());
|
|
41
|
+
}
|
|
42
|
+
toggle(){
|
|
43
|
+
if(this.#parentRow){
|
|
44
|
+
const value = !this.#parentRow?.isOpen;
|
|
45
|
+
this.#parentRow.isOpen = value
|
|
46
|
+
value?this.setAttribute('open',''):this.removeAttribute('open');
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
const myElementNotExists = !customElements.get('jb-expand-toggle');
|
|
51
|
+
if (myElementNotExists) {
|
|
52
|
+
window.customElements.define('jb-expand-toggle', JBExpandToggleWebComponent);
|
|
53
|
+
}
|