vueless 0.0.661 → 0.0.662

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vueless",
3
- "version": "0.0.661",
3
+ "version": "0.0.662",
4
4
  "license": "MIT",
5
5
  "description": "Vue Styleless UI Component Library, powered by Tailwind CSS.",
6
6
  "keywords": [
@@ -38,7 +38,7 @@ import {
38
38
  import { COMPONENT_NAME } from "./constants.ts";
39
39
 
40
40
  import type { Cell, Row, RowId, UTableProps, UTableRowAttrs, Config } from "./types.ts";
41
- import type { Ref, RendererElement, ComputedRef } from "vue";
41
+ import type { Ref, ComputedRef, VNode } from "vue";
42
42
 
43
43
  defineOptions({ inheritAttrs: false });
44
44
 
@@ -68,6 +68,18 @@ const emit = defineEmits([
68
68
  */
69
69
  "clickCell",
70
70
 
71
+ /**
72
+ * Tirggers when row expanded.
73
+ * @property {object} row
74
+ */
75
+ "row-expand",
76
+
77
+ /**
78
+ * Tirggers when row collapsed.
79
+ * @property {object} row
80
+ */
81
+ "row-collapse",
82
+
71
83
  /**
72
84
  * Triggers when table rows are selected (updated).
73
85
  * @property {array} tableRows
@@ -136,7 +148,7 @@ const isFooterSticky = computed(() => {
136
148
  const normalizedColumns = computed(() => normalizeColumns(props.columns));
137
149
 
138
150
  const visibleColumns = computed(() => {
139
- return normalizedColumns.value.filter((column) => !column.isHidden);
151
+ return normalizedColumns.value.filter((column) => column.isShown !== false);
140
152
  });
141
153
 
142
154
  const colsCount = computed(() => {
@@ -177,18 +189,16 @@ const hasSlotContentBeforeFirstRow = computed(() => {
177
189
  hasSlotContent(slots["before-first-row"]) &&
178
190
  typeof slots["before-first-row"] === "function"
179
191
  ) {
180
- return slots["before-first-row"]()?.some((item) =>
181
- Boolean((item.type as RendererElement)?.render),
182
- );
192
+ return (slots["before-first-row"]({}) as VNode[])?.some((item) => Boolean(item.type));
183
193
  }
184
194
 
185
195
  return false;
186
196
  });
187
197
 
188
- const isSelectedAllRows = computed(() => {
189
- const rows = getFlatRows(tableRows.value);
198
+ const flatTableRows = computed(() => getFlatRows(tableRows.value));
190
199
 
191
- return selectedRows.value.length === rows.length;
200
+ const isSelectedAllRows = computed(() => {
201
+ return selectedRows.value.length === flatTableRows.value.length;
192
202
  });
193
203
 
194
204
  const tableRowAttrs = computed(() => ({
@@ -354,7 +364,7 @@ function onClickCell(cell: Cell, row: Row, key: string | number) {
354
364
 
355
365
  function onChangeSelectAll(selectAll: boolean) {
356
366
  if (selectAll && canSelectAll.value) {
357
- selectedRows.value = getFlatRows(tableRows.value).map((row) => row.id);
367
+ selectedRows.value = flatTableRows.value.map((row) => row.id);
358
368
 
359
369
  tableRows.value = tableRows.value.map((row) => switchRowCheck({ ...row }, true));
360
370
  } else if (!selectAll) {
@@ -386,6 +396,14 @@ function onToggleRowVisibility(rowId: string | number) {
386
396
  tableRows.value = tableRows.value.map((row) => toggleRowVisibility({ ...row }, rowId));
387
397
  }
388
398
 
399
+ function onToggleExpand(row: Row, expanded: boolean) {
400
+ if (expanded) {
401
+ emit("row-expand", row);
402
+ } else {
403
+ emit("row-collapse", row);
404
+ }
405
+ }
406
+
389
407
  defineExpose({
390
408
  /**
391
409
  * Allows to clear selected rows.
@@ -669,6 +687,7 @@ const {
669
687
  @click="onClickRow"
670
688
  @dblclick="onDoubleClickRow"
671
689
  @click-cell="onClickCell"
690
+ @toggle-expand="onToggleExpand"
672
691
  @toggle-row-visibility="onToggleRowVisibility"
673
692
  >
674
693
  <template
@@ -677,7 +696,7 @@ const {
677
696
  #[`cell-${key}`]="slotValues"
678
697
  >
679
698
  <!--
680
- @slot Use it to customise needed table cell.
699
+ @slot Use it to customize needed table cell.
681
700
  @binding {string} value
682
701
  @binding {object} row
683
702
  @binding {number} index
@@ -689,6 +708,16 @@ const {
689
708
  :index="index"
690
709
  />
691
710
  </template>
711
+
712
+ <template #expand="{ row: expandedRow, expanded }">
713
+ <!--
714
+ @slot Use it to customize row expand icon.
715
+ @binding {object} row
716
+ @binding {boolean} expanded
717
+ -->
718
+ <slot name="expand" :row="expandedRow" :expanded="expanded" />
719
+ </template>
720
+
692
721
  <template #nested-content>
693
722
  <!--
694
723
  @slot Use it to add nested content inside a row.
@@ -11,7 +11,14 @@ import { useMutationObserver } from "../composables/useMutationObserver.ts";
11
11
  import UIcon from "../ui.image-icon/UIcon.vue";
12
12
  import UCheckbox from "../ui.form-checkbox/UCheckbox.vue";
13
13
 
14
- import type { Cell, CellObject, Row, RowScopedProps, UTableRowProps } from "./types.ts";
14
+ import type {
15
+ Cell,
16
+ CellObject,
17
+ Row,
18
+ RowScopedExpandProps,
19
+ RowScopedProps,
20
+ UTableRowProps,
21
+ } from "./types.ts";
15
22
 
16
23
  const NESTED_ROW_SHIFT_REM = 1;
17
24
  const LAST_NESTED_ROW_SHIFT_REM = 1.1;
@@ -20,7 +27,7 @@ defineOptions({ internal: true });
20
27
 
21
28
  const props = defineProps<UTableRowProps>();
22
29
 
23
- const emit = defineEmits(["toggleRowVisibility", "click", "dblclick", "clickCell"]);
30
+ const emit = defineEmits(["toggleRowVisibility", "click", "dblclick", "clickCell", "toggleExpand"]);
24
31
 
25
32
  const selectedRows = defineModel("selectedRows", { type: Array, default: () => [] });
26
33
 
@@ -37,17 +44,17 @@ useMutationObserver(cellRef, setCellTitle, {
37
44
 
38
45
  const toggleIconConfig = computed(() => {
39
46
  const nestedRow = props.row?.row;
40
- let isHidden = false;
47
+ let isShown = false;
41
48
 
42
49
  if (Array.isArray(nestedRow)) {
43
- isHidden = nestedRow.some((row) => row.isHidden);
50
+ isShown = nestedRow.some((row) => row.isShown);
44
51
  } else {
45
- isHidden = Boolean(nestedRow?.isHidden);
52
+ isShown = Boolean(nestedRow?.isShown);
46
53
  }
47
54
 
48
- return isHidden
49
- ? props.attrs.bodyCellNestedExpandIconAttrs.value
50
- : props.attrs.bodyCellNestedCollapseIconAttrs.value;
55
+ return isShown
56
+ ? props.attrs.bodyCellNestedCollapseIconAttrs.value
57
+ : props.attrs.bodyCellNestedExpandIconAttrs.value;
51
58
  });
52
59
 
53
60
  const isSingleNestedRow = computed(() => !Array.isArray(props.row.row));
@@ -82,14 +89,18 @@ onMounted(() => {
82
89
  }
83
90
  });
84
91
 
85
- function getToggleIconName(row: Row) {
86
- const isHiddenNestedRow = Array.isArray(row.row)
87
- ? row.row.some((nestedRow) => nestedRow.isHidden)
88
- : row.row?.isHidden;
92
+ function isExpanded(row: Row) {
93
+ const isShownNestedRow = Array.isArray(row.row)
94
+ ? row.row.some((nestedRow) => nestedRow.isShown)
95
+ : row.row?.isShown;
89
96
 
90
- const isHidden = isHiddenNestedRow || row.nestedData?.isHidden;
97
+ return Boolean(isShownNestedRow || row.nestedData?.isShown);
98
+ }
91
99
 
92
- return isHidden ? props.config?.defaults?.expandIcon : props.config?.defaults?.collapseIcon;
100
+ function getToggleIconName(row: Row) {
101
+ return isExpanded(row)
102
+ ? props.config?.defaults?.collapseIcon
103
+ : props.config?.defaults?.expandIcon;
93
104
  }
94
105
 
95
106
  function getIconWidth() {
@@ -221,6 +232,10 @@ function getRowAttrs(rowId: string | number) {
221
232
  ? props.attrs.bodyRowCheckedAttrs.value
222
233
  : props.attrs.bodyRowAttrs.value;
223
234
  }
235
+
236
+ function onToggleExpand(row: Row, expanded?: boolean) {
237
+ emit("toggleExpand", row, expanded || isExpanded(row));
238
+ }
224
239
  </script>
225
240
 
226
241
  <template>
@@ -259,22 +274,26 @@ function getRowAttrs(rowId: string | number) {
259
274
  v-bind="attrs.bodyCellNestedAttrs.value"
260
275
  >
261
276
  <div
262
- v-show="isShownToggleIcon"
263
- ref="toggle-wrapper"
264
- v-bind="attrs.bodyCellNestedExpandIconWrapperAttrs.value"
265
- :style="{ width: getIconWidth() }"
277
+ :data-row-toggle-icon="row.id"
278
+ @click.stop="() => (onClickToggleIcon(), onToggleExpand(row))"
266
279
  >
267
- <UIcon
268
- v-if="isShownToggleIcon"
269
- size="xs"
270
- internal
271
- interactive
272
- :data-row-toggle-icon="row.id"
273
- :name="getToggleIconName(row)"
274
- color="brand"
275
- v-bind="toggleIconConfig"
276
- @click.stop="onClickToggleIcon"
277
- />
280
+ <slot name="expand" :row="row" :expanded="isExpanded(row)">
281
+ <div
282
+ v-show="isShownToggleIcon"
283
+ ref="toggle-wrapper"
284
+ v-bind="attrs.bodyCellNestedExpandIconWrapperAttrs.value"
285
+ :style="{ width: getIconWidth() }"
286
+ >
287
+ <UIcon
288
+ size="xs"
289
+ internal
290
+ interactive
291
+ :name="getToggleIconName(row)"
292
+ color="brand"
293
+ v-bind="toggleIconConfig"
294
+ />
295
+ </div>
296
+ </slot>
278
297
  </div>
279
298
  <slot :name="`cell-${key}`" :value="value" :row="row" :index="index">
280
299
  <div
@@ -309,7 +328,7 @@ function getRowAttrs(rowId: string | number) {
309
328
  </tr>
310
329
 
311
330
  <template
312
- v-if="row.nestedData && !row.nestedData.isHidden && hasSlotContent($slots['nested-content'])"
331
+ v-if="row.nestedData && row.nestedData.isShown && hasSlotContent($slots['nested-content'])"
313
332
  >
314
333
  <tr :class="row.nestedData.class">
315
334
  <td :colspan="columns.length + (selectable ? 1 : 0)">
@@ -321,7 +340,7 @@ function getRowAttrs(rowId: string | number) {
321
340
  </template>
322
341
 
323
342
  <UTableRow
324
- v-if="isSingleNestedRow && singleNestedRow && !singleNestedRow.isHidden && !row.nestedData"
343
+ v-if="isSingleNestedRow && singleNestedRow && singleNestedRow.isShown && !row.nestedData"
325
344
  v-bind="{
326
345
  ...$attrs,
327
346
  ...getRowAttrs(singleNestedRow.id),
@@ -336,6 +355,7 @@ function getRowAttrs(rowId: string | number) {
336
355
  :config="config"
337
356
  :selectable="selectable"
338
357
  :empty-cell-label="emptyCellLabel"
358
+ @toggle-expand="onToggleExpand"
339
359
  @toggle-row-visibility="onClickToggleRowChild"
340
360
  @click="onClick"
341
361
  @dblclick="onDoubleClick"
@@ -347,12 +367,16 @@ function getRowAttrs(rowId: string | number) {
347
367
  >
348
368
  <slot :name="`cell-${key}`" :value="slotValues.value" :row="slotValues.row" :index="index" />
349
369
  </template>
370
+
371
+ <template #expand="slotValues: RowScopedExpandProps">
372
+ <slot name="expand" :row="slotValues.row" :expanded="slotValues.expanded" />
373
+ </template>
350
374
  </UTableRow>
351
375
 
352
376
  <template v-if="!isSingleNestedRow && nestedRows.length && !row.nestedData">
353
377
  <template v-for="nestedRow in nestedRows" :key="nestedRow.id">
354
378
  <UTableRow
355
- v-if="!nestedRow.isHidden"
379
+ v-if="nestedRow.isShown"
356
380
  v-bind="{
357
381
  ...$attrs,
358
382
  ...getRowAttrs(nestedRow.id),
@@ -367,6 +391,7 @@ function getRowAttrs(rowId: string | number) {
367
391
  :config="config"
368
392
  :selectable="selectable"
369
393
  :empty-cell-label="emptyCellLabel"
394
+ @toggle-expand="onToggleExpand"
370
395
  @toggle-row-visibility="onClickToggleRowChild"
371
396
  @click="onClick"
372
397
  @dblclick="onDoubleClick"
@@ -384,6 +409,9 @@ function getRowAttrs(rowId: string | number) {
384
409
  :index="index"
385
410
  />
386
411
  </template>
412
+ <template #expand="slotValues: RowScopedExpandProps">
413
+ <slot name="expand" :row="slotValues.row" :expanded="slotValues.expanded" />
414
+ </template>
387
415
  </UTableRow>
388
416
  </template>
389
417
  </template>
@@ -20,13 +20,13 @@ Keys you have/may to provide to component in row object.
20
20
 
21
21
  <Markdown>
22
22
  {`
23
- | Key name | Description | Type | Required |
24
- | ------------------| ---------------------------------- | ---------------| ------------ |
25
- | id | A unique identifier for row | String, Number | true |
26
- | content | Content to be rendered in the cell | Any | false |
27
- | isChecked | Indicates if row checked | Boolean | false |
28
- | isHidden | Indicated if nested row hidden | Boolean | false |
29
- | rowDate | Row date for date divider | String, Date | false |
23
+ | Key name | Description | Type |
24
+ | ------------------| ---------------------------------- | ---------------|
25
+ | id | A unique identifier for row | String, Number |
26
+ | content | Content to be rendered in the cell | Any |
27
+ | isChecked | Indicates if row checked | Boolean |
28
+ | isShown | Indicated if nested row shown | Boolean |
29
+ | rowDate | Row date for date divider | String, Date |
30
30
  `}
31
31
  </Markdown>
32
32
 
@@ -88,7 +88,7 @@ function getNestedRow() {
88
88
  {
89
89
  id: getRandomId(),
90
90
  isChecked: false,
91
- isHidden: true,
91
+ isShown: false,
92
92
  key_1: "Nesting",
93
93
  key_2: "Nesting",
94
94
  key_3: "Nesting",
@@ -96,7 +96,7 @@ function getNestedRow() {
96
96
  row: {
97
97
  id: getRandomId(),
98
98
  isChecked: false,
99
- isHidden: true,
99
+ isShown: false,
100
100
  key_1: "Second level nesting",
101
101
  key_2: "Second level nesting",
102
102
  key_3: "Second level nesting",
@@ -106,7 +106,7 @@ function getNestedRow() {
106
106
  {
107
107
  id: getRandomId(),
108
108
  isChecked: false,
109
- isHidden: true,
109
+ isShown: false,
110
110
  key_1: "Nesting",
111
111
  key_2: "Nesting",
112
112
  key_3: "Nesting",
@@ -114,7 +114,7 @@ function getNestedRow() {
114
114
  row: {
115
115
  id: getRandomId(),
116
116
  isChecked: false,
117
- isHidden: true,
117
+ isShown: false,
118
118
  key_1: "Second level nesting",
119
119
  key_2: "Second level nesting",
120
120
  key_3: "Second level nesting",
@@ -122,7 +122,7 @@ function getNestedRow() {
122
122
  row: {
123
123
  id: getRandomId(),
124
124
  isChecked: false,
125
- isHidden: true,
125
+ isShown: false,
126
126
  key_1: "Third level nesting",
127
127
  key_2: "Third level nesting",
128
128
  key_3: "Third level nesting",
@@ -155,7 +155,7 @@ function getNestedContentRow(index: number) {
155
155
  key_3: "More info",
156
156
  nestedData: {
157
157
  isChecked: false,
158
- isHidden: true,
158
+ isShown: false,
159
159
  rows: [
160
160
  {
161
161
  id: getRandomId(),
@@ -346,6 +346,21 @@ SlotDefault.args = {
346
346
  `,
347
347
  };
348
348
 
349
+ export const SlotExpand = DefaultTemplate.bind({});
350
+ SlotExpand.args = {
351
+ row: getNestedRow,
352
+ slotTemplate: `
353
+ <template #expand="{ row, isExpanded }">
354
+ <div v-if="isExpanded">
355
+ 🔼
356
+ </div>
357
+ <div v-if="!isExpanded">
358
+ 🔽
359
+ </div>
360
+ </template>
361
+ `,
362
+ };
363
+
349
364
  export const SlotHeaderActions = DefaultTemplate.bind({});
350
365
  SlotHeaderActions.parameters = SHORT_STORY_PARAMETERS;
351
366
  SlotHeaderActions.args = {
@@ -440,7 +455,7 @@ CellSlots.args = {
440
455
  row: [
441
456
  {
442
457
  id: getRandomId(),
443
- isHidden: false,
458
+ isShown: true,
444
459
  link: "some link",
445
460
  money: {
446
461
  sum: 10,
@@ -454,7 +469,7 @@ CellSlots.args = {
454
469
  },
455
470
  {
456
471
  id: getRandomId(),
457
- isHidden: false,
472
+ isShown: true,
458
473
  link: "some link",
459
474
  money: {
460
475
  sum: 10,
@@ -28,7 +28,7 @@ export interface DateDivider {
28
28
  export interface Row {
29
29
  id: RowId;
30
30
  isChecked?: boolean;
31
- isHidden?: boolean;
31
+ isShown?: boolean;
32
32
  rowDate?: string | Date;
33
33
  row?: Row | Row[];
34
34
  nestedData?: Row;
@@ -39,7 +39,7 @@ export interface Row {
39
39
  export interface ColumnObject {
40
40
  key: string;
41
41
  label?: string;
42
- isHidden?: string;
42
+ isShown?: boolean;
43
43
  class?: string | ((value: unknown | string, row: Row) => string);
44
44
  tdClass?: string;
45
45
  thClass?: string;
@@ -52,6 +52,11 @@ export interface RowScopedProps {
52
52
  row: Row;
53
53
  }
54
54
 
55
+ export interface RowScopedExpandProps {
56
+ expanded: boolean;
57
+ row: Row;
58
+ }
59
+
55
60
  export interface UTableProps {
56
61
  /**
57
62
  * Table columns (headers).
@@ -10,7 +10,7 @@ export function normalizeColumns(columns: Column[]): ColumnObject[] {
10
10
 
11
11
  export function mapRowColumns(row: Row, columns: ColumnObject[]): RowData {
12
12
  const filteredRow = Object.entries(row).filter((item) => {
13
- return columns.some((column) => column.key === item[0] && !column.isHidden);
13
+ return columns.some((column) => column.key === item[0] && column.isShown !== false);
14
14
  });
15
15
 
16
16
  return Object.fromEntries(filteredRow) as RowData;
@@ -44,10 +44,10 @@ export function addRowId(row: Row) {
44
44
 
45
45
  export function toggleRowVisibility(row: Row, targetRowId: string | number) {
46
46
  if (row.id === targetRowId) {
47
- if (row.hasOwnProperty("isHidden")) {
48
- row.isHidden = !row.isHidden;
49
- } else if (row.nestedData && row.nestedData.hasOwnProperty("isHidden")) {
50
- row.nestedData.isHidden = !row.nestedData.isHidden;
47
+ if (row.hasOwnProperty("isShown")) {
48
+ row.isShown = !row.isShown;
49
+ } else if (row.nestedData && row.nestedData.hasOwnProperty("isShown")) {
50
+ row.nestedData.isShown = !row.nestedData.isShown;
51
51
  }
52
52
 
53
53
  return row;
@@ -177,13 +177,14 @@ async function findAndCopyIcons(files) {
177
177
  }
178
178
 
179
179
  /* Vueless components props */
180
- const uComponentIconNamePattern = `\\b\\w*(name|icon)\\w*\\s*=\\s*(['"])(.*?)\\2`;
180
+ const iconPropsPattern = `\\b\\w*(name|icon)\\w*\\s*=\\s*(['"])(.*?)\\2`;
181
+ const uComponentIconNamePattern = /<U\w+\s+.*?\b\w*(name|icon)\w*\s*[:=]\s*(['"])(.*?)\2.*?>/;
181
182
  const uComponentIconNameArray = fileContents.match(new RegExp(uComponentIconNamePattern, "g"));
182
183
 
183
184
  if (!uComponentIconNameArray) return;
184
185
 
185
186
  for (const match of uComponentIconNameArray) {
186
- const groupMatch = match.match(new RegExp(uComponentIconNamePattern));
187
+ const groupMatch = match.match(new RegExp(iconPropsPattern));
187
188
  const iconName = groupMatch ? groupMatch[3] : null;
188
189
 
189
190
  try {
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M181.91-182.15h44.24l459.81-458.81-43.76-44-460.29 459.05v43.76Zm-67.89 68.13V-253.5l574.52-573.76q8.24-8.48 19.81-13.22 11.56-4.74 24.11-4.74 11.47 0 22.95 4.74 11.48 4.74 21.2 12.98l51.89 51.17q9.24 9.72 13.48 21.32t4.24 23.31q0 11.72-4.74 23.7-4.74 11.98-12.98 20.46L253.74-114.02H114.02ZM775.17-732.7l-41.24-41.47 41.24 41.47ZM664.2-663.2l-22-21.76 43.76 44-21.76-22.24Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M846.22-480 674.83-237.89q-14.2 19.67-33.86 31.77-19.67 12.1-43.36 12.1H182.15q-28.1 0-48.12-20.01-20.01-20.02-20.01-48.12v-435.7q0-28.2 20.01-48.28 20.02-20.09 48.12-20.09h415.46q23.69 0 43.36 12.34 19.67 12.34 33.86 31.77L846.22-480Zm-85.29 0L608.56-697.85H182.15v435.7h426.46L760.93-480Zm-578.78 0v217.85-435.7V-480Z"/></svg>
@@ -1 +0,0 @@
1
- <svg xmlns="http://www.w3.org/2000/svg" width="48" height="48" viewBox="0 -960 960 960"><path d="M425.93-154.02v-544.07H194.02v-108.13h572.2v108.13H534.3v544.07H425.93Z"/></svg>