init component

This commit is contained in:
Robin COuret
2026-02-16 17:28:37 +01:00
parent 460c7a25e0
commit e0e50af706
4557 changed files with 666911 additions and 8 deletions

View File

@@ -0,0 +1,5 @@
import { ComputedRef } from 'vue';
import { BTableColumn, BTableRow } from '../shared';
export declare function toSet(rows: BTableRow[]): Set<unknown>;
export declare function provideVisibleColumns(visibleColumns: ComputedRef<BTableColumn[]>): void;
export declare function useInjectedVisibleColumns(): ComputedRef<BTableColumn[]>;

View File

@@ -0,0 +1,16 @@
import { provide, inject, computed } from 'vue';
import { constEmptyArray } from '../../../utils/helpers';
export function toSet(rows) {
const set = new Set();
rows.forEach(row => set.add(row.id));
return set;
}
const COLUMNS_INJECTION_SYMBOL = Symbol();
export function provideVisibleColumns(visibleColumns) {
provide(COLUMNS_INJECTION_SYMBOL, visibleColumns);
}
const DEFAULT_VISIBLE_COLUMNS = computed(constEmptyArray);
export function useInjectedVisibleColumns() {
return inject(COLUMNS_INJECTION_SYMBOL, DEFAULT_VISIBLE_COLUMNS);
}
//# sourceMappingURL=shared.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/components/table/composables/shared.ts"],"names":[],"mappings":"AAAA,SAAsB,OAAtB,EAA+B,MAA/B,EAAuC,QAAvC,QAAuD,KAAvD;AACA,SAAS,eAAT,QAAgC,wBAAhC;AAIA,OAAM,SAAU,KAAV,CAAgB,IAAhB,EAAiC;AACrC,QAAM,GAAG,GAAG,IAAI,GAAJ,EAAZ;AACA,EAAA,IAAI,CAAC,OAAL,CAAa,GAAG,IAAI,GAAG,CAAC,GAAJ,CAAQ,GAAG,CAAC,EAAZ,CAApB;AACA,SAAO,GAAP;AACD;AAED,MAAM,wBAAwB,GAAG,MAAM,EAAvC;AAEA,OAAM,SAAU,qBAAV,CAAgC,cAAhC,EAA2E;AAC/E,EAAA,OAAO,CAAC,wBAAD,EAA2B,cAA3B,CAAP;AACD;AAED,MAAM,uBAAuB,GAAG,QAAQ,CAAiB,eAAjB,CAAxC;AAEA,OAAM,SAAU,yBAAV,GAAmC;AACvC,SAAO,MAAM,CAAC,wBAAD,EAA2B,uBAA3B,CAAb;AACD","sourcesContent":["import { ComputedRef, provide, inject, computed } from 'vue';\r\nimport { constEmptyArray } from '../../../utils/helpers';\r\n\r\nimport { BTableColumn, BTableRow } from '../shared';\r\n\r\nexport function toSet(rows: BTableRow[]): Set<unknown> {\r\n const set = new Set<unknown>();\r\n rows.forEach(row => set.add(row.id));\r\n return set;\r\n}\r\n\r\nconst COLUMNS_INJECTION_SYMBOL = Symbol();\r\n\r\nexport function provideVisibleColumns(visibleColumns: ComputedRef<BTableColumn[]>) {\r\n provide(COLUMNS_INJECTION_SYMBOL, visibleColumns);\r\n}\r\n\r\nconst DEFAULT_VISIBLE_COLUMNS = computed<BTableColumn[]>(constEmptyArray);\r\n\r\nexport function useInjectedVisibleColumns(): ComputedRef<BTableColumn[]> {\r\n return inject(COLUMNS_INJECTION_SYMBOL, DEFAULT_VISIBLE_COLUMNS);\r\n}\r\n"],"sourceRoot":"","file":"shared.js"}

View File

@@ -0,0 +1,53 @@
import { IO } from 'fp-ts/lib/IO';
import { ExtractPropTypes, Ref, ComputedRef } from 'vue';
import { FunctionN } from 'fp-ts/lib/function';
import { PropType } from 'vue';
import { ColorVariant } from '../../../types/ColorVariants';
import { BTableRow } from '../shared';
export declare const BTableCheckPropsDefinition: {
isCheckable: {
type: PropType<boolean>;
default: boolean;
};
checkedRows: {
type: PropType<BTableRow[]>;
default: never[];
};
'onUpdate:checkedRows': {
type: PropType<FunctionN<[BTableRow[]], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
checkboxVariant: {
type: PropType<ColorVariant>;
default: "is-primary";
};
canCheckAllRows: {
type: PropType<boolean>;
default: boolean;
};
onCheckRow: {
type: PropType<FunctionN<[BTableRow], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onUncheckRow: {
type: PropType<FunctionN<[BTableRow], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
};
export interface BTableCheckProps extends ExtractPropTypes<typeof BTableCheckPropsDefinition> {
}
export declare function useCheckableTable(props: BTableCheckProps, rows: Ref<BTableRow[]>): UseCheckableTable;
export interface UseCheckableTable {
isCheckable: ComputedRef<boolean>;
variant: ComputedRef<ColorVariant>;
checkedRowIds: ComputedRef<Set<unknown>>;
toggleAllRows: IO<void>;
checkAllRows: IO<void>;
uncheckAllRows: IO<void>;
allRowsChecked: ComputedRef<boolean>;
toggleRow: FunctionN<[BTableRow], void>;
allRowsUncheckable: ComputedRef<boolean>;
hasCheckableRows: ComputedRef<boolean>;
allRowsUnchecked: ComputedRef<boolean>;
}
export declare function useInjectedCheckableTable(): UseCheckableTable;

View File

@@ -0,0 +1,119 @@
import { computed, provide, inject, shallowRef, watch } from 'vue';
import { constant, constFalse, constTrue, constVoid } from 'fp-ts/lib/function';
import { constEmptyArray } from '../../../utils/helpers';
import { toggleBTableRow } from '../shared';
import { toSet } from './shared';
export const BTableCheckPropsDefinition = {
isCheckable: {
type: Boolean,
default: false
},
checkedRows: {
type: Array,
default: constEmptyArray()
},
'onUpdate:checkedRows': {
type: Function,
default: constant(constVoid)
},
checkboxVariant: {
type: String,
default: 'is-primary'
},
canCheckAllRows: {
type: Boolean,
default: true
},
onCheckRow: {
type: Function,
default: constant(constVoid)
},
onUncheckRow: {
type: Function,
default: constant(constVoid)
}
};
const USE_CHECKABLE_TABLE_INJECTION_SYMBOL = Symbol();
export function useCheckableTable(props, rows) {
const checkableRows = computed(() => props.isCheckable ? rows.value.filter(row => row.isCheckable ?? true) : []);
const propCheckedRows = computed(() => props.isCheckable ? props.checkedRows : []);
const newCheckedRows = shallowRef(propCheckedRows.value);
watch(propCheckedRows, newValue => {
newCheckedRows.value = newValue;
});
const checkedRowIds = computed(() => toSet(newCheckedRows.value));
const allRowsChecked = computed(() => {
const ids = checkedRowIds.value;
return checkableRows.value.length > 0 && checkableRows.value.every(row => ids.has(row.id));
});
const allRowsUncheckable = computed(() => rows.value.every(row => !row.isCheckable));
function checkAllRows() {
const cRows = checkableRows.value;
newCheckedRows.value = cRows;
props['onUpdate:checkedRows'](cRows);
}
function toggleRow(row) {
if (row.isCheckable) {
const ids = checkedRowIds.value;
if (ids.has(row.id)) {
props.onUncheckRow(row);
} else {
props.onCheckRow(row);
}
const cRows = toggleBTableRow(row, newCheckedRows.value);
newCheckedRows.value = cRows;
props['onUpdate:checkedRows'](cRows);
}
}
function uncheckAllRows() {
newCheckedRows.value = [];
props['onUpdate:checkedRows']([]);
}
function toggleAllRows() {
allRowsChecked.value ? uncheckAllRows() : checkAllRows();
}
const hasCheckableRows = computed(() => checkableRows.value.length > 0);
const state = {
isCheckable: computed(() => props.isCheckable),
variant: computed(() => props.checkboxVariant),
checkedRowIds,
toggleAllRows,
checkAllRows,
uncheckAllRows,
allRowsChecked,
toggleRow,
allRowsUncheckable,
hasCheckableRows,
allRowsUnchecked: computed(() => hasCheckableRows.value && checkedRowIds.value.size === 0)
};
provide(USE_CHECKABLE_TABLE_INJECTION_SYMBOL, state);
return state;
}
function useDefaultCheckableTableState() {
return {
isCheckable: computed(constFalse),
variant: computed(() => 'is-primary'),
checkedRowIds: computed(() => new Set()),
toggleAllRows: constVoid,
checkAllRows: constVoid,
uncheckAllRows: constVoid,
toggleRow: constVoid,
allRowsChecked: computed(constFalse),
allRowsUncheckable: computed(constFalse),
hasCheckableRows: computed(constFalse),
allRowsUnchecked: computed(constTrue)
};
}
export function useInjectedCheckableTable() {
return inject(USE_CHECKABLE_TABLE_INJECTION_SYMBOL, useDefaultCheckableTableState, true);
}
//# sourceMappingURL=useCheckableTable.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,53 @@
import { Option } from 'fp-ts/lib/Option';
import { ExtractPropTypes } from 'vue';
import { FunctionN } from 'fp-ts/lib/function';
import { PropType, Ref } from 'vue';
import { BTableRow } from '../shared';
declare type DropEffect = 'none' | 'copy' | 'link' | 'move';
declare type DragHandler = FunctionN<[DragEvent], void>;
declare type OnDragEffect = FunctionN<[BTableRow, DragEvent, number], void>;
export declare const BTableDraggablePropsDefinition: {
isDraggable: {
type: BooleanConstructor;
default: boolean;
};
dropEffect: {
type: PropType<DropEffect>;
default: "move";
};
onDragstart: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onDragenter: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onDragover: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onDragleave: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onDragend: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onDrop: {
type: PropType<OnDragEffect>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
};
export interface BTableDraggableProps extends ExtractPropTypes<typeof BTableDraggablePropsDefinition> {
}
export interface UseDraggableTable {
isDraggable: Ref<boolean>;
isActive: Ref<boolean>;
target: Ref<Option<BTableRow>>;
useRowDragListeners: FunctionN<[BTableRow, number], Record<string, DragHandler>>;
}
export declare function useDraggableTable(props: BTableDraggableProps): UseDraggableTable;
export declare function useInjectedDraggableTable(): UseDraggableTable;
export {};

View File

@@ -0,0 +1,155 @@
import { isNone, isSome, none, some } from 'fp-ts/lib/Option';
import { shallowRef, toRef, computed } from 'vue';
import { constant, constVoid } from 'fp-ts/lib/function';
import { provide, inject } from 'vue';
import { eqBTableRowData } from '../shared';
export const BTableDraggablePropsDefinition = {
isDraggable: {
type: Boolean,
default: false
},
dropEffect: {
type: String,
default: 'move'
},
onDragstart: {
type: Function,
default: constant(constVoid)
},
onDragenter: {
type: Function,
default: constant(constVoid)
},
onDragover: {
type: Function,
default: constant(constVoid)
},
onDragleave: {
type: Function,
default: constant(constVoid)
},
onDragend: {
type: Function,
default: constant(constVoid)
},
onDrop: {
type: Function,
default: constant(constVoid)
}
};
const USE_DRAGGABLE_TABLE_INJECTION_SYMBOL = Symbol();
export function useDraggableTable(props) {
const dropTarget = shallowRef(none);
const dragIsActive = computed(() => props.isDraggable && isSome(dropTarget.value));
function getOnDragStartListener(row, index) {
return e => {
if (e.dataTransfer) {
e.dataTransfer.setData('text/plain', String(index));
e.dataTransfer.dropEffect = props.dropEffect;
}
dropTarget.value = some(row);
props.onDragstart(row, e, index);
};
}
function getOnDropListener(row, index) {
return e => {
if (row.isDroppable) {
e.preventDefault();
props.onDrop(row, e, index);
}
dropTarget.value = none;
};
}
function getOnDragEnterListener(row, index) {
return e => {
if (row.isDroppable) {
e.preventDefault();
dropTarget.value = some(row);
props.onDragenter(row, e, index);
}
};
}
function getOnDragOverListener(row, index) {
return e => {
if (row.isDroppable) {
e.preventDefault();
const target = dropTarget.value;
if (isNone(target) || isSome(target) && !eqBTableRowData.equals(target.value, row)) {
dropTarget.value = some(row);
}
props.onDragover(row, e, index);
}
};
}
function getOnDragLeaveListener(row, index) {
return e => {
if (row.isDroppable) {
e.preventDefault();
const target = dropTarget.value;
if (isSome(target) && eqBTableRowData.equals(target.value, row)) {
dropTarget.value = none;
}
props.onDragleave(row, e, index);
}
};
}
function getOnDragEndListener(row, index) {
return e => {
props.onDragend(row, e, index);
if (isSome(dropTarget.value)) {
dropTarget.value = none;
}
};
}
function useRowDragListeners(row, index) {
if (props.isDraggable && !!row.isDraggable) {
return {
onDragstart: getOnDragStartListener(row, index),
onDrop: getOnDropListener(row, index),
onDragenter: getOnDragEnterListener(row, index),
onDragleave: getOnDragLeaveListener(row, index),
onDragover: getOnDragOverListener(row, index),
onDragend: getOnDragEndListener(row, index)
};
} else {
return {};
}
}
const draggableTable = {
isDraggable: toRef(props, 'isDraggable'),
useRowDragListeners,
isActive: dragIsActive,
target: dropTarget
};
provide(USE_DRAGGABLE_TABLE_INJECTION_SYMBOL, draggableTable);
return draggableTable;
}
function useDefaultDraggableTable() {
return {
isDraggable: shallowRef(false),
useRowDragListeners: constant({}),
isActive: shallowRef(false),
target: shallowRef(none)
};
}
export function useInjectedDraggableTable() {
return inject(USE_DRAGGABLE_TABLE_INJECTION_SYMBOL, useDefaultDraggableTable, true);
}
//# sourceMappingURL=useDraggableTable.js.map

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,34 @@
import { FunctionN } from 'fp-ts/lib/function';
import { ExtractPropTypes, PropType, ComputedRef, Ref } from 'vue';
import { BTableRow } from '../shared';
export declare const BTableSelectablePropsDefinition: {
isSelectable: {
type: PropType<boolean>;
default: boolean;
};
selectedRows: {
type: PropType<BTableRow[]>;
default: import("fp-ts/lib/function").Lazy<never[]>;
};
'onUpdate:selectedRows': {
type: PropType<FunctionN<[BTableRow[]], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onSelectRow: {
type: PropType<FunctionN<[BTableRow], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
onUnselectRow: {
type: PropType<FunctionN<[BTableRow], void>>;
default: import("fp-ts/lib/function").Lazy<() => void>;
};
};
export interface BTableSelectableProps extends ExtractPropTypes<typeof BTableSelectablePropsDefinition> {
}
export declare function useSelectableTable(props: BTableSelectableProps): UseSelectableTableState;
export interface UseSelectableTableState {
isSelectable: Ref<boolean>;
selectedRowIds: ComputedRef<Set<unknown>>;
toggleRowSelection: FunctionN<[BTableRow], void>;
}
export declare function useInjectedSelectableTable(): UseSelectableTableState;

View File

@@ -0,0 +1,64 @@
import { constant, constVoid } from 'fp-ts/lib/function';
import { computed, toRef, provide, inject, shallowRef } from 'vue';
import { useProxy } from '../../../composables/proxy/useProxy';
import { constEmptyArray } from '../../../utils/helpers';
import { toggleBTableRow } from '../shared';
import { toSet } from './shared';
export const BTableSelectablePropsDefinition = {
isSelectable: {
type: Boolean,
default: false
},
selectedRows: {
type: Array,
default: constEmptyArray
},
'onUpdate:selectedRows': {
type: Function,
default: constant(constVoid)
},
onSelectRow: {
type: Function,
default: constant(constVoid)
},
onUnselectRow: {
type: Function,
default: constant(constVoid)
}
};
const USE_SELECTABLE_TABLE_INJECTION_SYMBOL = Symbol();
export function useSelectableTable(props) {
const {
value: selectedRows
} = useProxy(computed(() => props.isSelectable ? props.selectedRows : []), toRef(props, 'onUpdate:selectedRows'));
const selectedRowIds = computed(() => toSet(selectedRows.value));
function toggleRowSelection(row) {
if (row.isSelectable ?? props.isSelectable) {
const ids = selectedRowIds.value;
ids.has(row.id) ? props.onUnselectRow(row) : props.onSelectRow(row);
selectedRows.value = toggleBTableRow(row, selectedRows.value);
}
}
const state = {
isSelectable: toRef(props, 'isSelectable'),
selectedRowIds,
toggleRowSelection
};
provide(USE_SELECTABLE_TABLE_INJECTION_SYMBOL, state);
return state;
}
function useDefaultSelectableTableState() {
return {
isSelectable: shallowRef(false),
selectedRowIds: computed(() => new Set()),
toggleRowSelection: constVoid
};
}
export function useInjectedSelectableTable() {
return inject(USE_SELECTABLE_TABLE_INJECTION_SYMBOL, useDefaultSelectableTableState, true);
}
//# sourceMappingURL=useSelectableTable.js.map

View File

@@ -0,0 +1 @@
{"version":3,"sources":["../../../../src/components/table/composables/useSelectableTable.ts"],"names":[],"mappings":"AAAA,SAAS,QAAT,EAAmB,SAAnB,QAA+C,oBAA/C;AACA,SAAS,QAAT,EAA+C,KAA/C,EAAsD,OAAtD,EAA+D,MAA/D,EAAyF,UAAzF,QAA2G,KAA3G;AACA,SAAS,QAAT,QAAyB,qCAAzB;AACA,SAAS,eAAT,QAAgC,wBAAhC;AACA,SAAoB,eAApB,QAA2C,WAA3C;AACA,SAAS,KAAT,QAAsB,UAAtB;AAEA,OAAO,MAAM,+BAA+B,GAAG;AAC7C,EAAA,YAAY,EAAE;AACZ,IAAA,IAAI,EAAE,OADM;AAEZ,IAAA,OAAO,EAAE;AAFG,GAD+B;AAK7C,EAAA,YAAY,EAAE;AACZ,IAAA,IAAI,EAAE,KADM;AAEZ,IAAA,OAAO,EAAE;AAFG,GAL+B;AAS7C,2BAAyB;AACvB,IAAA,IAAI,EAAE,QADiB;AAEvB,IAAA,OAAO,EAAE,QAAQ,CAAC,SAAD;AAFM,GAToB;AAa7C,EAAA,WAAW,EAAE;AACX,IAAA,IAAI,EAAE,QADK;AAEX,IAAA,OAAO,EAAE,QAAQ,CAAC,SAAD;AAFN,GAbgC;AAiB7C,EAAA,aAAa,EAAE;AACb,IAAA,IAAI,EAAE,QADO;AAEb,IAAA,OAAO,EAAE,QAAQ,CAAC,SAAD;AAFJ;AAjB8B,CAAxC;AAyBP,MAAM,qCAAqC,GAAG,MAAM,EAApD;AAEA,OAAM,SAAU,kBAAV,CAA6B,KAA7B,EAAyD;AAC7D,QAAM;AAAE,IAAA,KAAK,EAAE;AAAT,MAA0B,QAAQ,CACtC,QAAQ,CAAC,MAAO,KAAK,CAAC,YAAN,GAAqB,KAAK,CAAC,YAA3B,GAA0C,EAAlD,CAD8B,EAEtC,KAAK,CAAC,KAAD,EAAQ,uBAAR,CAFiC,CAAxC;AAKA,QAAM,cAAc,GAAG,QAAQ,CAAC,MAAM,KAAK,CAAC,YAAY,CAAC,KAAd,CAAZ,CAA/B;;AAEA,WAAS,kBAAT,CAA4B,GAA5B,EAA0C;AACxC,QAAI,GAAG,CAAC,YAAJ,IAAoB,KAAK,CAAC,YAA9B,EAA4C;AAC1C,YAAM,GAAG,GAAG,cAAc,CAAC,KAA3B;AACA,MAAA,GAAG,CAAC,GAAJ,CAAQ,GAAG,CAAC,EAAZ,IAAkB,KAAK,CAAC,aAAN,CAAoB,GAApB,CAAlB,GAA6C,KAAK,CAAC,WAAN,CAAkB,GAAlB,CAA7C;AACA,MAAA,YAAY,CAAC,KAAb,GAAqB,eAAe,CAAC,GAAD,EAAM,YAAY,CAAC,KAAnB,CAApC;AACD;AACF;;AAED,QAAM,KAAK,GAA4B;AACrC,IAAA,YAAY,EAAE,KAAK,CAAC,KAAD,EAAQ,cAAR,CADkB;AAErC,IAAA,cAFqC;AAGrC,IAAA;AAHqC,GAAvC;AAMA,EAAA,OAAO,CAAC,qCAAD,EAAwC,KAAxC,CAAP;AAEA,SAAO,KAAP;AACD;;AAQD,SAAS,8BAAT,GAAuC;AACrC,SAAO;AACL,IAAA,YAAY,EAAE,UAAU,CAAC,KAAD,CADnB;AAEL,IAAA,cAAc,EAAE,QAAQ,CAAC,MAAM,IAAI,GAAJ,EAAP,CAFnB;AAGL,IAAA,kBAAkB,EAAE;AAHf,GAAP;AAKD;;AAED,OAAM,SAAU,0BAAV,GAAoC;AACxC,SAAO,MAAM,CAAC,qCAAD,EAAwC,8BAAxC,EAAwE,IAAxE,CAAb;AACD","sourcesContent":["import { constant, constVoid, FunctionN } from 'fp-ts/lib/function';\nimport { computed, ExtractPropTypes, PropType, toRef, provide, inject, ComputedRef, Ref, shallowRef } from 'vue';\nimport { useProxy } from '../../../composables/proxy/useProxy';\nimport { constEmptyArray } from '../../../utils/helpers';\nimport { BTableRow, toggleBTableRow } from '../shared';\nimport { toSet } from './shared';\n\nexport const BTableSelectablePropsDefinition = {\n isSelectable: {\n type: Boolean as PropType<boolean>,\n default: false\n },\n selectedRows: {\n type: Array as PropType<BTableRow[]>,\n default: constEmptyArray\n },\n 'onUpdate:selectedRows': {\n type: Function as PropType<FunctionN<[BTableRow[]], void>>,\n default: constant(constVoid)\n },\n onSelectRow: {\n type: Function as PropType<FunctionN<[BTableRow], void>>,\n default: constant(constVoid)\n },\n onUnselectRow: {\n type: Function as PropType<FunctionN<[BTableRow], void>>,\n default: constant(constVoid)\n }\n};\n\nexport interface BTableSelectableProps extends ExtractPropTypes<typeof BTableSelectablePropsDefinition> {}\n\nconst USE_SELECTABLE_TABLE_INJECTION_SYMBOL = Symbol();\n\nexport function useSelectableTable(props: BTableSelectableProps) {\n const { value: selectedRows } = useProxy<BTableRow[]>(\n computed(() => (props.isSelectable ? props.selectedRows : [])),\n toRef(props, 'onUpdate:selectedRows')\n );\n\n const selectedRowIds = computed(() => toSet(selectedRows.value));\n\n function toggleRowSelection(row: BTableRow) {\n if (row.isSelectable ?? props.isSelectable) {\n const ids = selectedRowIds.value;\n ids.has(row.id) ? props.onUnselectRow(row) : props.onSelectRow(row);\n selectedRows.value = toggleBTableRow(row, selectedRows.value);\n }\n }\n\n const state: UseSelectableTableState = {\n isSelectable: toRef(props, 'isSelectable'),\n selectedRowIds,\n toggleRowSelection\n };\n\n provide(USE_SELECTABLE_TABLE_INJECTION_SYMBOL, state);\n\n return state;\n}\n\nexport interface UseSelectableTableState {\n isSelectable: Ref<boolean>;\n selectedRowIds: ComputedRef<Set<unknown>>;\n toggleRowSelection: FunctionN<[BTableRow], void>;\n}\n\nfunction useDefaultSelectableTableState(): UseSelectableTableState {\n return {\n isSelectable: shallowRef(false),\n selectedRowIds: computed(() => new Set()),\n toggleRowSelection: constVoid\n };\n}\n\nexport function useInjectedSelectableTable(): UseSelectableTableState {\n return inject(USE_SELECTABLE_TABLE_INJECTION_SYMBOL, useDefaultSelectableTableState, true);\n}\n"],"sourceRoot":"","file":"useSelectableTable.js"}

View File

@@ -0,0 +1,39 @@
import { ExtractPropTypes, Ref, ComputedRef } from 'vue';
import { FunctionN } from 'fp-ts/lib/function';
import { PropType } from 'vue';
import { BTableColumn, BTableRow, SortType } from '../shared';
export declare const BTableSortingPropsDefinition: {
rows: {
type: PropType<BTableRow[]>;
required: true;
};
sortBy: {
type: PropType<BTableColumn<BTableRow> | BTableColumn<BTableRow>[]>;
};
'onUpdate:sortBy': {
type: PropType<FunctionN<[BTableColumn<BTableRow> | BTableColumn<BTableRow>[]], void>>;
};
sortType: {
type: PropType<SortType>;
default: "Descending";
};
'onUpdate:sortType': {
type: PropType<FunctionN<[SortType], void>>;
};
};
export interface BTableSortingProps extends ExtractPropTypes<typeof BTableSortingPropsDefinition> {
}
export interface UseSortableTable {
sortBy: Ref<BTableColumn[]>;
sortType: Ref<SortType>;
isMultiple: ComputedRef<boolean>;
sortByMap: ComputedRef<Map<string, BTableColumn & {
sortIndex: number;
}>>;
updateSortColumn: FunctionN<[string], void>;
updateSortDirection: (columnLabel?: string) => void;
sortableColumns: ComputedRef<BTableColumn[]>;
hasSortableColumns: ComputedRef<boolean>;
}
export declare function useSortableTable(props: BTableSortingProps, rows: Ref<BTableRow[]>, columns: Ref<BTableColumn[]>): UseSortableTable;
export declare function useInjectedSortableTable(): UseSortableTable;

View File

@@ -0,0 +1,181 @@
import { findFirst, isEmpty, isNonEmpty, reverse, snoc, sortBy as sortBy_ } from 'fp-ts/lib/Array';
import { fromCompare } from 'fp-ts/lib/Ord';
import { alt, isNone, isSome, none } from 'fp-ts/Option';
import { toRef, computed, watch, shallowRef, provide, inject } from 'vue';
import { constFalse, constVoid, pipe } from 'fp-ts/lib/function';
import { useProxy } from '../../../composables/proxy/useProxy';
import { constEmptyArray, isBoolean } from '../../../utils/helpers';
import { toggleBTableColumn } from '../shared';
export const BTableSortingPropsDefinition = {
rows: {
type: Array,
required: true
},
sortBy: {
type: [Object, Array]
},
'onUpdate:sortBy': {
type: Function
},
sortType: {
type: String,
default: 'Descending'
},
'onUpdate:sortType': {
type: Function
}
};
function useSortType(sortType, columnSortType, invert) {
if (invert) {
return (columnSortType ?? sortType) === 'Ascending' ? 'Descending' : 'Ascending';
} else {
return columnSortType ?? sortType;
}
}
function useSortColumn(sortType, column, invert) {
return { ...column,
sort: isBoolean(column.sort) ? column.sort : column.sort === undefined ? undefined : { ...column.sort,
sortType: useSortType(sortType, column.sort?.sortType, invert)
}
};
}
const USE_SORTABLE_TABLE_INJECTION_SYMBOL = Symbol();
function toMap(columns) {
return new Map(columns.map((c, sortIndex) => [c.label, { ...c,
sortIndex
}]));
}
export function useSortableTable(props, rows, columns) {
const initialSortType = props.sortType;
const {
value: sortType
} = useProxy(toRef(props, 'sortType'), toRef(props, 'onUpdate:sortType'));
/*
fp-ts sorts in ascending order so we need to reverse the ords if the initial sort type is 'Descending'
Future sortType changes just reverse the array so we don't need to readjust the ords
*/
const isMultiple = computed(() => Array.isArray(props.sortBy));
const internalSortBy = shallowRef(Array.isArray(props.sortBy) ? props.sortBy : props.sortBy ? [props.sortBy] : []);
watch(() => props.sortBy, newVal => {
internalSortBy.value = Array.isArray(newVal) ? newVal : newVal ? [newVal] : [];
});
const sortBy = computed({
get() {
return internalSortBy.value;
},
set(columns) {
internalSortBy.value = columns;
if (!props['onUpdate:sortBy']) {
return;
}
if (Array.isArray(props.sortBy)) {
props['onUpdate:sortBy'](columns);
} else if (isNonEmpty(columns)) {
props['onUpdate:sortBy'](columns[0]);
}
}
});
const sortByMap = computed(() => toMap(sortBy.value));
const ords = computed(() => {
const ords = [];
sortBy.value.forEach(c => {
const sort = c.sort;
if (sort && !isBoolean(sort)) {
ords.push(sort.sortType === 'Ascending' || sort.sortType === undefined && initialSortType === 'Ascending' ? sort.ord : fromCompare((x, y) => {
return sort.ord.compare(x, y) * -1;
}));
}
});
return ords;
});
function sort() {
if (!isEmpty(ords.value) && !isEmpty(rows.value)) {
rows.value = sortBy_(ords.value)(rows.value);
}
}
watch(sortType, () => {
if (Array.isArray(sortBy.value) && sortBy.value.length > 1) {
sort();
} else {
rows.value = reverse(rows.value);
}
});
watch(() => [props.rows, sortBy.value], sort, {
immediate: true
});
const sortableColumns = computed(() => columns.value.filter(column => !!column.sort));
function updateSortColumn(label) {
const column = pipe(sortBy.value, findFirst(c => c.label === label), alt(() => pipe(sortableColumns.value, findFirst(c => c.label === label))));
if (isNone(column)) return;
if (isMultiple.value) {
sortBy.value = toggleBTableColumn(useSortColumn(sortType.value, column.value, false), sortBy.value);
} else {
sortBy.value = [column.value];
}
}
function updateSortDirection(columnLabel) {
const column = columnLabel ? pipe(sortBy.value, findFirst(c => c.label === columnLabel), alt(() => pipe(sortableColumns.value, findFirst(c => c.label === columnLabel)))) : none;
if (isMultiple.value && columnLabel && isSome(column)) {
const index = sortBy.value.findIndex(c => c.label === columnLabel);
const newColumn = useSortColumn(sortType.value, column.value, true);
if (index > -1) {
const newVal = sortBy.value.slice();
newVal.splice(index, 1, newColumn);
sortBy.value = newVal;
} else {
sortBy.value = snoc(sortBy.value, newColumn);
}
} else {
sortType.value = sortType.value === 'Ascending' ? 'Descending' : 'Ascending';
}
}
const sortableTable = {
sortBy,
sortType,
isMultiple,
sortByMap,
updateSortDirection,
updateSortColumn,
sortableColumns,
hasSortableColumns: computed(() => isNonEmpty(sortableColumns.value))
};
provide(USE_SORTABLE_TABLE_INJECTION_SYMBOL, sortableTable);
return sortableTable;
}
function useDefaultSortableTable() {
return {
sortBy: shallowRef([]),
sortType: shallowRef('Ascending'),
updateSortColumn: constVoid,
updateSortDirection: constVoid,
sortableColumns: computed(constEmptyArray),
hasSortableColumns: computed(constFalse),
isMultiple: computed(constFalse),
sortByMap: computed(() => new Map())
};
}
export function useInjectedSortableTable() {
return inject(USE_SORTABLE_TABLE_INJECTION_SYMBOL, useDefaultSortableTable, true);
}
//# sourceMappingURL=useSortableTable.js.map

File diff suppressed because one or more lines are too long