@katlux/preset-modern 0.1.1-alpha.97 → 0.1.1-alpha.98

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/dist/module.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@katlux/preset-modern",
3
3
  "configKey": "katluxTemplateModern",
4
- "version": "0.1.1-alpha.97",
4
+ "version": "0.1.1-alpha.98",
5
5
  "builder": {
6
6
  "@nuxt/module-builder": "1.0.2",
7
7
  "unbuild": "3.6.1"
@@ -106,6 +106,7 @@
106
106
  --input-focus-border-color: var(--primary-500);
107
107
  --input-focus-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
108
108
  --input-height: 48px;
109
+ --input-min-width: 140px;
109
110
  --table-header-bg: var(--neutral-100);
110
111
  --table-header-color: var(--neutral-600);
111
112
  --table-border-color: var(--neutral-200);
@@ -106,6 +106,7 @@
106
106
  --input-focus-border-color: var(--primary-500);
107
107
  --input-focus-shadow: 0 0 0 3px rgba(139, 92, 246, 0.2);
108
108
  --input-height: 48px;
109
+ --input-min-width: 140px;
109
110
  --table-header-bg: var(--neutral-100);
110
111
  --table-header-color: var(--neutral-600);
111
112
  --table-border-color: var(--neutral-200);
@@ -8,14 +8,14 @@
8
8
  v-model="internalSelected"
9
9
  labelField="label"
10
10
  closeOnSelect
11
- :disabled="selectedRows.length === 0"
11
+ :disabled="!selectAll && selectedRows.length === 0"
12
12
  :placeholder="t('Select an action')"
13
13
  class="action-select"
14
14
  )
15
15
  KButton(
16
16
  @click="doAction(internalSelected)"
17
17
  size="small"
18
- :disabled="selectedRows.length === 0 || internalSelected == undefined"
18
+ :disabled="(!selectAll && selectedRows.length === 0) || internalSelected == undefined"
19
19
  class="execute-btn"
20
20
  ) {{ t('Apply') }}
21
21
 
@@ -29,7 +29,7 @@
29
29
  size="small"
30
30
  :type="action.type || 'default'"
31
31
  :iconOnly="action.iconOnly"
32
- :disabled="selectedRows.length === 0"
32
+ :disabled="!selectAll && selectedRows.length === 0"
33
33
  class="action-btn"
34
34
  )
35
35
  template(#icon v-if="action.icon")
@@ -5,8 +5,8 @@
5
5
  role="region"
6
6
  :aria-label="t('Data Table')"
7
7
  )
8
- .header(v-if="props.bulkActions && props.bulkActions.length > 0 && selectedRows.length > 0")
9
- .selected-count {{ t('{count} items selected').replace('{count}', (selectedRows?.length || 0).toString()) }}
8
+ .header(v-if="props.bulkActions && props.bulkActions.length > 0 && (selectedRows.length > 0 || selectAll)")
9
+ .selected-count {{ selectAll ? t('All items selected') : t('{count} items selected').replace('{count}', (selectedRows?.length || 0).toString()) }}
10
10
  KBulkActions.bulk-actions(:bulkActions="props.bulkActions" :selectedRows="selectedRows" :selectAll="selectAll")
11
11
 
12
12
  .k-datatable-wrapper(
@@ -45,7 +45,7 @@
45
45
  :class="{ 'selected': isRowSelected(row), 'active-focus': focusedIndex === (props.virtualScroll ? startIndex + index : index) }"
46
46
  )
47
47
  td.check-cell(v-if="props.bulkActions && props.bulkActions.length > 0")
48
- KCheckbox(:value="row" v-model="selectedRows")
48
+ KCheckbox(:model-value="isRowSelected(row)" @update:model-value="toggleRow(row)")
49
49
  td(v-for="visibleField in visibleFields || props.dataProvider.fields" :key="visibleField" :data-field="visibleField" :style="getColumnStyle(visibleField)")
50
50
  component(v-if="getCellSlot(visibleField)" :is="getCellSlot(visibleField)" :row="row" :field="visibleField" :value="row[visibleField]")
51
51
  span(v-else) {{ row[visibleField] }}
@@ -130,10 +130,43 @@ const getRowKey = (row, index) => {
130
130
  }
131
131
  return index;
132
132
  };
133
+ const selectedRowIds = computed(() => {
134
+ const idKey = props.dataProvider?.idKey || "id";
135
+ const set = /* @__PURE__ */ new Set();
136
+ for (const r of selectedRows.value || []) {
137
+ const id = r?.[idKey] ?? r?.id ?? r?._id ?? r;
138
+ set.add(id);
139
+ set.add(r);
140
+ }
141
+ return set;
142
+ });
133
143
  const isRowSelected = (row) => {
144
+ if (selectAll.value) return true;
134
145
  const idKey = props.dataProvider?.idKey || "id";
135
146
  const rowId = row?.[idKey] ?? row?.id ?? row?._id ?? row;
136
- return (selectedRows.value || []).some((r) => (r?.[idKey] ?? r?.id ?? r?._id ?? r) === rowId || r === row);
147
+ return selectedRowIds.value.has(rowId) || selectedRowIds.value.has(row);
148
+ };
149
+ const toggleRow = (row) => {
150
+ const idKey = props.dataProvider?.idKey || "id";
151
+ const rowId = row?.[idKey] ?? row?.id ?? row?._id ?? row;
152
+ if (selectAll.value) {
153
+ selectAll.value = false;
154
+ const activeRows = displayRows.value || pageRows.value;
155
+ selectedRows.value = activeRows.filter((r) => {
156
+ const rId = r?.[idKey] ?? r?.id ?? r?._id ?? r;
157
+ return rId !== rowId && r !== row;
158
+ });
159
+ } else {
160
+ const isSelected = isRowSelected(row);
161
+ if (isSelected) {
162
+ selectedRows.value = (selectedRows.value || []).filter((r) => {
163
+ const rId = r?.[idKey] ?? r?.id ?? r?._id ?? r;
164
+ return rId !== rowId && r !== row;
165
+ });
166
+ } else {
167
+ selectedRows.value = [...selectedRows.value || [], row];
168
+ }
169
+ }
137
170
  };
138
171
  const getCellSlot = (fieldName) => {
139
172
  const slotName = "cell-" + fieldName;
@@ -148,7 +181,7 @@ const getColumnStyle = (field) => {
148
181
  if (!w) return void 0;
149
182
  return { width: w, whiteSpace: "nowrap" };
150
183
  };
151
- const { pageData, filter: dpFilter, loading: dpLoading, initialLoad: dpInitialLoad, pageSize: dpPageSize } = useDataProvider(props.dataProvider);
184
+ const { pageData, virtualRows, filter: dpFilter, loading: dpLoading, initialLoad: dpInitialLoad, pageSize: dpPageSize } = useDataProvider(props.dataProvider);
152
185
  const pageRows = computed(() => pageData.value || []);
153
186
  const isLoading = computed(() => {
154
187
  return dpLoading.value || dpInitialLoad.value || false;
@@ -157,6 +190,9 @@ const datatableItems = computed(() => {
157
190
  const currentRows = pageRows.value;
158
191
  const dp = props.dataProvider;
159
192
  if (props.virtualScroll) {
193
+ if (Array.isArray(dp?.rowMap)) return dp.rowMap;
194
+ if (Array.isArray(dp?.rowMap?.value)) return dp.rowMap.value;
195
+ if (Array.isArray(virtualRows?.value) && virtualRows.value.length > 0) return virtualRows.value;
160
196
  if (Array.isArray(dp?.allVisibleRows)) return dp.allVisibleRows;
161
197
  if (Array.isArray(dp?.allVisibleRows?.value)) return dp.allVisibleRows.value;
162
198
  if (Array.isArray(dp?.allVisibleNodes)) return dp.allVisibleNodes;
@@ -266,7 +302,8 @@ const handleKeyDown = (e) => {
266
302
  border-radius: var(--border-radius-lg);
267
303
  box-shadow: var(--shadow-md);
268
304
  background: var(--background-color);
269
- overflow: hidden;
305
+ overflow-x: auto;
306
+ -webkit-overflow-scrolling: touch;
270
307
  border: 1px solid var(--table-border-color);
271
308
  }
272
309
  .modern-datatable .k-datatable-wrapper .loading-overlay {
@@ -328,6 +365,7 @@ const handleKeyDown = (e) => {
328
365
  border-bottom: 1px solid var(--table-border-color);
329
366
  color: var(--table-row-text-color);
330
367
  font-size: var(--font-size-md);
368
+ white-space: nowrap;
331
369
  }
332
370
  .modern-datatable table tbody tr td.check-cell {
333
371
  text-align: center;
@@ -344,6 +382,7 @@ const handleKeyDown = (e) => {
344
382
  text-align: center;
345
383
  padding: var(--gap-xl);
346
384
  color: var(--font-color-secondary);
385
+ white-space: normal;
347
386
  }
348
387
  .modern-datatable table tbody tr:last-child td {
349
388
  border-bottom: none;
@@ -352,8 +391,21 @@ const handleKeyDown = (e) => {
352
391
  display: flex;
353
392
  justify-content: flex-end;
354
393
  align-items: center;
394
+ gap: var(--gap-md);
395
+ margin-top: var(--gap-sm);
396
+ }
397
+ @media (max-width: 768px) {
398
+ .modern-datatable .footer {
399
+ flex-direction: column;
400
+ align-items: stretch;
401
+ gap: var(--gap-sm);
402
+ }
403
+ .modern-datatable .footer .pagination {
404
+ width: 100%;
405
+ }
355
406
  }
356
407
  .modern-datatable.is-virtual-scroll .k-datatable-wrapper {
408
+ overflow-x: auto;
357
409
  overflow-y: auto;
358
410
  max-height: var(--k-datatable-viewport-height, 500px);
359
411
  outline: none;
@@ -1,7 +1,7 @@
1
1
  <template lang="pug">
2
2
  nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigation')")
3
3
  ul.pagination-list
4
- li(v-if="showPrevButton")
4
+ li.nav-prev(v-if="showPrevButton")
5
5
  KButton.nav-btn(
6
6
  @click="goToPrev"
7
7
  :disabled="!showPrevButton"
@@ -11,7 +11,7 @@ nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigat
11
11
  :aria-label="t('Previous Page')"
12
12
  ) ‹
13
13
 
14
- li(v-if="showFirstEllipsis")
14
+ li.nav-first(v-if="showFirstEllipsis")
15
15
  KButton.page-btn(
16
16
  @click="goToFirst"
17
17
  :href="getPageHref(1)"
@@ -20,10 +20,10 @@ nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigat
20
20
  :aria-label="t('Go to Page 1')"
21
21
  ) 1
22
22
 
23
- li(v-if="showFirstEllipsis")
23
+ li.nav-ellipsis.first-ellipsis(v-if="showFirstEllipsis")
24
24
  span.ellipsis ...
25
25
 
26
- li(v-for="item in visiblePages" :key="item")
26
+ li.nav-page(v-for="item in visiblePages" :key="item" :class="{ 'is-active': item === currentPage }")
27
27
  KButton.page-btn(
28
28
  @click="() => pageClicked(item)"
29
29
  :href="getPageHref(item)"
@@ -33,10 +33,10 @@ nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigat
33
33
  :aria-label="t('Page') + ' ' + item"
34
34
  ) {{ item }}
35
35
 
36
- li(v-if="showLastEllipsis")
36
+ li.nav-ellipsis.last-ellipsis(v-if="showLastEllipsis")
37
37
  span.ellipsis ...
38
38
 
39
- li(v-if="showLastEllipsis")
39
+ li.nav-last(v-if="showLastEllipsis")
40
40
  KButton.page-btn(
41
41
  @click="goToLast"
42
42
  :href="getPageHref(totalPages)"
@@ -45,7 +45,7 @@ nav.k-pagination-modern(v-if="totalPages > 1" :aria-label="t('Pagination Navigat
45
45
  :aria-label="t('Go to Page') + ' ' + totalPages"
46
46
  ) {{ totalPages }}
47
47
 
48
- li(v-if="showNextButton")
48
+ li.nav-next(v-if="showNextButton")
49
49
  KButton.nav-btn(
50
50
  @click="goToNext"
51
51
  :disabled="!showNextButton"
@@ -90,6 +90,7 @@ defineProps({
90
90
  padding: 0;
91
91
  margin: 0;
92
92
  align-items: center;
93
+ flex-wrap: wrap;
93
94
  }
94
95
  .k-pagination-modern .pagination-list li {
95
96
  display: flex;
@@ -100,4 +101,19 @@ defineProps({
100
101
  color: var(--neutral-400);
101
102
  font-size: var(--font-size-sm);
102
103
  }
104
+ @media (max-width: 640px) {
105
+ .k-pagination-modern {
106
+ justify-content: center;
107
+ }
108
+ .k-pagination-modern .pagination-list {
109
+ justify-content: center;
110
+ }
111
+ }
112
+ @media (max-width: 480px) {
113
+ .k-pagination-modern .pagination-list li.nav-first,
114
+ .k-pagination-modern .pagination-list li.nav-last,
115
+ .k-pagination-modern .pagination-list li.nav-ellipsis {
116
+ display: none;
117
+ }
118
+ }
103
119
  </style>
@@ -42,7 +42,7 @@ const inputAttrs = computed(() => {
42
42
  display: flex;
43
43
  flex-direction: column;
44
44
  flex: 1;
45
- min-width: 0;
45
+ min-width: var(--input-min-width, 140px);
46
46
  }
47
47
 
48
48
  .KTextbox.modern-textbox {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@katlux/preset-modern",
3
- "version": "0.1.1-alpha.97",
3
+ "version": "0.1.1-alpha.98",
4
4
  "description": "Modern default design preset and styling variables for Katlux components",
5
5
  "author": "Katlux",
6
6
  "license": "Apache-2.0",
@@ -20,7 +20,7 @@
20
20
  "./dist/runtime/assets/*": "./dist/runtime/assets/*"
21
21
  },
22
22
  "dependencies": {
23
- "@katlux/toolkit": "^0.1.1-alpha.120",
23
+ "@katlux/toolkit": "^0.1.1-alpha.121",
24
24
  "@nuxt/kit": "^3.12.0"
25
25
  },
26
26
  "files": [