@flux-ui/components 3.0.0-next.61 → 3.0.0-next.64

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 (125) hide show
  1. package/dist/component/FluxActionStack.vue.d.ts +25 -19
  2. package/dist/component/FluxAspectRatio.vue.d.ts +4 -3
  3. package/dist/component/FluxBorderShine.vue.d.ts +1 -1
  4. package/dist/component/FluxCalendar.vue.d.ts +2 -6
  5. package/dist/component/FluxContainer.vue.d.ts +3 -2
  6. package/dist/component/FluxFilter.vue.d.ts +6 -7
  7. package/dist/component/FluxFilterBar.vue.d.ts +5 -4
  8. package/dist/component/FluxFilterBase.vue.d.ts +14 -11
  9. package/dist/component/FluxFilterDate.vue.d.ts +3 -6
  10. package/dist/component/FluxFilterDateRange.vue.d.ts +3 -6
  11. package/dist/component/FluxFilterOption.vue.d.ts +3 -6
  12. package/dist/component/FluxFilterOptionAsync.vue.d.ts +3 -6
  13. package/dist/component/FluxFilterOptions.vue.d.ts +3 -6
  14. package/dist/component/FluxFilterOptionsAsync.vue.d.ts +3 -6
  15. package/dist/component/FluxFilterRange.vue.d.ts +3 -7
  16. package/dist/component/FluxFilterWindow.vue.d.ts +3 -8
  17. package/dist/component/FluxFlex.vue.d.ts +30 -0
  18. package/dist/component/{FluxRow.vue.d.ts → FluxFlexItem.vue.d.ts} +5 -3
  19. package/dist/component/FluxGrid.vue.d.ts +3 -2
  20. package/dist/component/FluxGridColumn.vue.d.ts +3 -2
  21. package/dist/component/FluxKanbanColumn.vue.d.ts +3 -0
  22. package/dist/component/FluxScroller.vue.d.ts +32 -0
  23. package/dist/component/{FluxStack.vue.d.ts → FluxSplitView.vue.d.ts} +7 -6
  24. package/dist/component/{FluxColumn.vue.d.ts → FluxSplitViewPane.vue.d.ts} +4 -1
  25. package/dist/component/FluxSticky.vue.d.ts +34 -0
  26. package/dist/component/index.d.ts +6 -3
  27. package/dist/component/primitive/FilterBadge.vue.d.ts +2 -2
  28. package/dist/component/primitive/FilterItem.vue.d.ts +3 -2
  29. package/dist/component/primitive/SelectBase.vue.d.ts +4 -4
  30. package/dist/composable/private/index.d.ts +1 -0
  31. package/dist/composable/private/useSplitView.d.ts +23 -0
  32. package/dist/data/di.d.ts +19 -2
  33. package/dist/data/index.d.ts +0 -1
  34. package/dist/index.css +778 -526
  35. package/dist/index.d.ts +2 -0
  36. package/dist/index.js +10381 -9732
  37. package/dist/index.js.map +1 -1
  38. package/dist/util/defineFilter.d.ts +3 -0
  39. package/dist/util/filter.d.ts +7 -0
  40. package/dist/util/index.d.ts +2 -0
  41. package/dist/vite/defineFilterMacro.d.ts +3 -0
  42. package/dist/vite/index.d.ts +1 -0
  43. package/dist/vite.js +217 -0
  44. package/dist/vite.js.map +1 -0
  45. package/package.json +11 -7
  46. package/src/component/FluxActionBar.vue +3 -4
  47. package/src/component/FluxActionStack.vue +3 -3
  48. package/src/component/FluxAspectRatio.vue +5 -3
  49. package/src/component/FluxBadgeStack.vue +4 -4
  50. package/src/component/FluxButtonStack.vue +6 -4
  51. package/src/component/FluxCalendar.vue +160 -157
  52. package/src/component/FluxContainer.vue +4 -2
  53. package/src/component/FluxFilter.vue +10 -11
  54. package/src/component/FluxFilterBar.vue +71 -15
  55. package/src/component/FluxFilterBase.vue +65 -51
  56. package/src/component/FluxFilterDate.vue +24 -8
  57. package/src/component/FluxFilterDateRange.vue +27 -9
  58. package/src/component/FluxFilterOption.vue +20 -10
  59. package/src/component/FluxFilterOptionAsync.vue +19 -11
  60. package/src/component/FluxFilterOptions.vue +26 -11
  61. package/src/component/FluxFilterOptionsAsync.vue +28 -12
  62. package/src/component/FluxFilterRange.vue +25 -11
  63. package/src/component/FluxFilterWindow.vue +25 -11
  64. package/src/component/FluxFlex.vue +53 -0
  65. package/src/component/FluxFlexItem.vue +40 -0
  66. package/src/component/FluxFormDateTimeInput.vue +3 -4
  67. package/src/component/FluxGrid.vue +4 -2
  68. package/src/component/FluxGridColumn.vue +4 -2
  69. package/src/component/FluxInfoStack.vue +3 -3
  70. package/src/component/FluxItemStack.vue +4 -4
  71. package/src/component/FluxKanbanColumn.vue +16 -3
  72. package/src/component/FluxNoticeStack.vue +3 -3
  73. package/src/component/FluxPane.vue +10 -7
  74. package/src/component/FluxProgressBar.vue +4 -3
  75. package/src/component/FluxScroller.vue +63 -0
  76. package/src/component/FluxSplitView.vue +101 -0
  77. package/src/component/FluxSplitViewPane.vue +23 -0
  78. package/src/component/FluxSticky.vue +67 -0
  79. package/src/component/FluxTagStack.vue +4 -4
  80. package/src/component/FluxToolbar.vue +3 -4
  81. package/src/component/FluxToolbarGroup.vue +3 -4
  82. package/src/component/FluxTooltipProvider.vue +56 -25
  83. package/src/component/index.ts +6 -3
  84. package/src/component/primitive/FilterBadge.vue +2 -2
  85. package/src/component/primitive/FilterItem.vue +4 -2
  86. package/src/component/primitive/FilterMenuRenderer.ts +10 -5
  87. package/src/component/primitive/FilterOptionBase.vue +1 -1
  88. package/src/composable/private/index.ts +1 -0
  89. package/src/composable/private/useAsyncFilterOptions.ts +1 -1
  90. package/src/composable/private/useFilterOption.ts +1 -1
  91. package/src/composable/private/useSplitView.ts +249 -0
  92. package/src/composable/useFilterInjection.ts +3 -1
  93. package/src/css/component/Calendar.module.scss +11 -17
  94. package/src/css/component/Comment.module.scss +3 -11
  95. package/src/css/component/Filter.module.scss +6 -2
  96. package/src/css/component/Flex.module.scss +84 -0
  97. package/src/css/component/Flyout.module.scss +1 -0
  98. package/src/css/component/Kanban.module.scss +31 -28
  99. package/src/css/component/LayerPane.module.scss +5 -0
  100. package/src/css/component/Layout.module.scss +0 -41
  101. package/src/css/component/Legend.module.scss +3 -4
  102. package/src/css/component/Menu.module.scss +1 -0
  103. package/src/css/component/Notice.module.scss +1 -1
  104. package/src/css/component/Pagination.module.scss +1 -1
  105. package/src/css/component/Pane.module.scss +1 -1
  106. package/src/css/component/Progress.module.scss +2 -2
  107. package/src/css/component/Scroller.module.scss +109 -0
  108. package/src/css/component/SplitView.module.scss +78 -0
  109. package/src/css/component/Sticky.module.scss +35 -0
  110. package/src/css/component/Tab.module.scss +1 -0
  111. package/src/css/component/Table.module.scss +1 -0
  112. package/src/css/component/Tooltip.module.scss +14 -0
  113. package/src/data/di.ts +22 -2
  114. package/src/data/index.ts +0 -1
  115. package/src/index.ts +11 -0
  116. package/src/util/defineFilter.ts +10 -0
  117. package/src/util/filter.ts +63 -0
  118. package/src/util/index.ts +2 -0
  119. package/src/vite/defineFilterMacro.ts +335 -0
  120. package/src/vite/index.ts +1 -0
  121. package/dist/data/filter.d.ts +0 -7
  122. package/src/component/FluxColumn.vue +0 -24
  123. package/src/component/FluxRow.vue +0 -24
  124. package/src/component/FluxStack.vue +0 -41
  125. package/src/data/filter.ts +0 -165
@@ -21,6 +21,7 @@
21
21
  const {tooltip} = useFluxStore();
22
22
 
23
23
  const elementRef = ref<HTMLElement | null>(null);
24
+ const hostRef = ref<HTMLElement | null>(null);
24
25
  const position = ref<PositionData | null>(null);
25
26
 
26
27
  const content = computed(() => unref(tooltip) ? unref(tooltip)!.contentSlot?.() ?? [unref(tooltip)!.content] : null);
@@ -66,34 +67,64 @@
66
67
 
67
68
  watch(content, () => requestAnimationFrame(calculate));
68
69
 
69
- return () => h(FluxTooltipTransition, {}, {
70
- default: () => {
71
- if (!unref(has)) {
72
- return;
73
- }
70
+ watch(has, isVisible => {
71
+ if (!isVisible) {
72
+ return;
73
+ }
74
74
 
75
- const pos = unref(position);
76
-
77
- return h('div', {
78
- ref: elementRef,
79
- class: pos
80
- ? clsx(
81
- pos.transition === 'above' && $style.tooltipAbove,
82
- pos.transition === 'below' && $style.tooltipBelow,
83
- pos.transition === 'end' && $style.tooltipEnd,
84
- pos.transition === 'start' && $style.tooltipStart
85
- )
86
- : $style.tooltip,
87
- style: {
88
- '--x': pos?.x ?? undefined,
89
- '--y': pos?.y ?? undefined,
90
- '--arrowAngle': pos?.arrowAngle ?? undefined,
91
- '--arrowX': pos?.arrowX ?? undefined,
92
- '--arrowY': pos?.arrowY ?? undefined
93
- }
94
- }, unref(content));
75
+ const host = unrefTemplateElement(hostRef);
76
+
77
+ if (host && !host.matches(':popover-open')) {
78
+ host.showPopover();
95
79
  }
96
80
  });
81
+
82
+ return () => h('div', {
83
+ ref: hostRef,
84
+ popover: 'manual',
85
+ class: $style.tooltipHost
86
+ }, [
87
+ h(FluxTooltipTransition, {
88
+ onAfterLeave: () => {
89
+ if (unref(has)) {
90
+ return;
91
+ }
92
+
93
+ const host = unrefTemplateElement(hostRef);
94
+
95
+ if (host && host.matches(':popover-open')) {
96
+ host.hidePopover();
97
+ }
98
+ }
99
+ }, {
100
+ default: () => {
101
+ if (!unref(has)) {
102
+ return;
103
+ }
104
+
105
+ const pos = unref(position);
106
+
107
+ return h('div', {
108
+ ref: elementRef,
109
+ class: pos
110
+ ? clsx(
111
+ pos.transition === 'above' && $style.tooltipAbove,
112
+ pos.transition === 'below' && $style.tooltipBelow,
113
+ pos.transition === 'end' && $style.tooltipEnd,
114
+ pos.transition === 'start' && $style.tooltipStart
115
+ )
116
+ : $style.tooltip,
117
+ style: {
118
+ '--x': pos?.x ?? undefined,
119
+ '--y': pos?.y ?? undefined,
120
+ '--arrowAngle': pos?.arrowAngle ?? undefined,
121
+ '--arrowX': pos?.arrowX ?? undefined,
122
+ '--arrowY': pos?.arrowY ?? undefined
123
+ }
124
+ }, unref(content));
125
+ }
126
+ })
127
+ ]);
97
128
  });
98
129
 
99
130
  function calculateHorizontalPosition(top: number, left: number, width: number, height: number, originWidth: number, originHeight: number, margin: number, safeZone: number): PositionData {
@@ -25,7 +25,6 @@ export { default as FluxCommandPaletteItem } from './FluxCommandPaletteItem.vue'
25
25
  export { default as FluxComment } from './FluxComment.vue';
26
26
  export { default as FluxColorPicker } from './FluxColorPicker.vue';
27
27
  export { default as FluxColorSelect } from './FluxColorSelect.vue';
28
- export { default as FluxColumn } from './FluxColumn.vue';
29
28
  export { default as FluxContainer } from './FluxContainer.vue';
30
29
  export { default as FluxDataTable } from './FluxDataTable.vue';
31
30
  export { default as FluxDatePicker } from './FluxDatePicker.vue';
@@ -48,6 +47,8 @@ export { default as FluxFilterOptionAsync } from './FluxFilterOptionAsync.vue';
48
47
  export { default as FluxFilterOptions } from './FluxFilterOptions.vue';
49
48
  export { default as FluxFilterOptionsAsync } from './FluxFilterOptionsAsync.vue';
50
49
  export { default as FluxFilterRange } from './FluxFilterRange.vue';
50
+ export { default as FluxFlex } from './FluxFlex.vue';
51
+ export { default as FluxFlexItem } from './FluxFlexItem.vue';
51
52
  export { default as FluxFlickeringGrid } from './FluxFlickeringGrid.vue';
52
53
  export { default as FluxFlyout } from './FluxFlyout.vue';
53
54
  export { default as FluxFocalPointEditor } from './FluxFocalPointEditor.vue';
@@ -125,7 +126,7 @@ export { default as FluxPublishButton } from './FluxPublishButton.vue';
125
126
  export { default as FluxQuantitySelector } from './FluxQuantitySelector.vue';
126
127
  export { default as FluxRemove } from './FluxRemove.vue';
127
128
  export { default as FluxRoot } from './FluxRoot.vue';
128
- export { default as FluxRow } from './FluxRow.vue';
129
+ export { default as FluxScroller } from './FluxScroller.vue';
129
130
  export { default as FluxSecondaryButton } from './FluxSecondaryButton.vue';
130
131
  export { default as FluxSecondaryLinkButton } from './FluxSecondaryLinkButton.vue';
131
132
  export { default as FluxSegmentedControl } from './FluxSegmentedControl.vue';
@@ -138,11 +139,13 @@ export { default as FluxSpacer } from './FluxSpacer.vue';
138
139
  export { default as FluxSpacing } from './FluxSpacing.vue';
139
140
  export { default as FluxSpinner } from './FluxSpinner.vue';
140
141
  export { default as FluxSplitButton } from './FluxSplitButton.vue';
141
- export { default as FluxStack } from './FluxStack.vue';
142
+ export { default as FluxSplitView } from './FluxSplitView.vue';
143
+ export { default as FluxSplitViewPane } from './FluxSplitViewPane.vue';
142
144
  export { default as FluxStatistic } from './FluxStatistic.vue';
143
145
  export { default as FluxStepper } from './FluxStepper.vue';
144
146
  export { default as FluxStepperStep } from './FluxStepperStep.vue';
145
147
  export { default as FluxStepperSteps } from './FluxStepperSteps.vue';
148
+ export { default as FluxSticky } from './FluxSticky.vue';
146
149
  export { default as FluxTab } from './FluxTab.vue';
147
150
  export { default as FluxTabBar } from './FluxTabBar.vue';
148
151
  export { default as FluxTabBarItem } from './FluxTabBarItem.vue';
@@ -11,7 +11,7 @@
11
11
  lang="ts"
12
12
  setup>
13
13
  import { useLoaded } from '@basmilius/common';
14
- import type { FluxFilterItem, FluxFilterValue } from '@flux-ui/types';
14
+ import type { FluxFilterDefinition, FluxFilterValue } from '@flux-ui/types';
15
15
  import { computed, ref, unref, watch } from 'vue';
16
16
  import FluxBadge from '../FluxBadge.vue';
17
17
  import $style from '~flux/components/css/component/Filter.module.scss';
@@ -24,7 +24,7 @@
24
24
  item,
25
25
  value
26
26
  } = defineProps<{
27
- readonly item: FluxFilterItem;
27
+ readonly item: FluxFilterDefinition;
28
28
  readonly value: FluxFilterValue;
29
29
  }>();
30
30
 
@@ -3,6 +3,7 @@
3
3
  :command="valueLabel"
4
4
  command-icon="angle-right"
5
5
  :command-loading="isLoading"
6
+ :disabled="disabled"
6
7
  :icon-leading="item.icon"
7
8
  :label="item.label"
8
9
  type="button"
@@ -13,7 +14,7 @@
13
14
  lang="ts"
14
15
  setup>
15
16
  import { useLoaded } from '@basmilius/common';
16
- import type { FluxFilterItem, FluxFilterValue } from '@flux-ui/types';
17
+ import type { FluxFilterDefinition, FluxFilterValue } from '@flux-ui/types';
17
18
  import { computed, ref, unref, watch } from 'vue';
18
19
  import FluxMenuItem from '../FluxMenuItem.vue';
19
20
 
@@ -25,8 +26,9 @@
25
26
  item,
26
27
  value
27
28
  } = defineProps<{
28
- readonly item: FluxFilterItem;
29
+ readonly item: FluxFilterDefinition;
29
30
  readonly value: FluxFilterValue;
31
+ readonly disabled?: boolean;
30
32
  }>();
31
33
 
32
34
  const {isLoading, loaded} = useLoaded();
@@ -1,4 +1,4 @@
1
- import type { FluxFilterItem, FluxFilterValue } from '@flux-ui/types';
1
+ import type { FluxFilterDefinition, FluxFilterValue } from '@flux-ui/types';
2
2
  import { defineComponent, h, isVNode, type VNode, unref } from 'vue';
3
3
  import { useFilterInjection } from '~flux/components/composable';
4
4
  import FluxMenuGroup from '../FluxMenuGroup.vue';
@@ -14,11 +14,11 @@ export const FilterMenuRenderer = defineComponent({
14
14
  setup(props) {
15
15
  const {state} = useFilterInjection();
16
16
 
17
- return () => props.menuItems.map((group, index) => renderFilterGroup(group as (FluxFilterItem | VNode)[], index, props.navigate, unref(state) as Record<string, FluxFilterValue>));
17
+ return () => props.menuItems.map((group, index) => renderFilterGroup(group as (FluxFilterDefinition | VNode)[], index, props.navigate, unref(state) as Record<string, FluxFilterValue>));
18
18
  }
19
19
  });
20
20
 
21
- function renderFilterGroup(group: (FluxFilterItem | VNode)[], index: number, navigate: Function, state: Record<string, FluxFilterValue>): VNode[] {
21
+ function renderFilterGroup(group: (FluxFilterDefinition | VNode)[], index: number, navigate: Function, state: Record<string, FluxFilterValue>): VNode[] {
22
22
  const slot: VNode[] = [];
23
23
 
24
24
  if (index > 0) {
@@ -32,7 +32,7 @@ function renderFilterGroup(group: (FluxFilterItem | VNode)[], index: number, nav
32
32
  return slot;
33
33
  }
34
34
 
35
- function renderFilterItem(item: FluxFilterItem | VNode, navigate: Function, state: Record<string, FluxFilterValue>): VNode {
35
+ function renderFilterItem(item: FluxFilterDefinition | VNode, navigate: Function, state: Record<string, FluxFilterValue>): VNode {
36
36
  if (isVNode(item)) {
37
37
  return item;
38
38
  }
@@ -40,6 +40,11 @@ function renderFilterItem(item: FluxFilterItem | VNode, navigate: Function, stat
40
40
  return h(FilterItem, {
41
41
  item,
42
42
  value: state[item.name] ?? null,
43
- onClick: () => navigate(item.name)
43
+ disabled: item.disabled,
44
+ onClick: () => {
45
+ if (!item.disabled) {
46
+ navigate(item.name);
47
+ }
48
+ }
44
49
  });
45
50
  }
@@ -38,7 +38,7 @@
38
38
  lang="ts"
39
39
  setup>
40
40
  import type { FluxFilterOptionItem, FluxFilterOptionRow, FluxFilterValueSingle } from '@flux-ui/types';
41
- import { isFluxFilterOptionHeader, isFluxFilterOptionItem } from '~flux/components/data';
41
+ import { isFluxFilterOptionHeader, isFluxFilterOptionItem } from '~flux/components/util';
42
42
  import FluxFormInput from '../FluxFormInput.vue';
43
43
  import FluxMenuGroup from '../FluxMenuGroup.vue';
44
44
  import FluxMenuItem from '../FluxMenuItem.vue';
@@ -3,6 +3,7 @@ export { default as useDateFlyout } from './useDateFlyout';
3
3
  export { default as useDropdownPopup, type UseDropdownPopupOptions, type UseDropdownPopupReturn } from './useDropdownPopup';
4
4
  export { default as useFormSelect } from './useFormSelect';
5
5
  export { useKanban } from './useKanban';
6
+ export { useSplitView, type SplitViewPane, type UseSplitViewOptions, type UseSplitViewReturn } from './useSplitView';
6
7
  export { default as useTranslate } from './useTranslate';
7
8
  export { useCommandPalette, type CommandPaletteGroup, type CommandPaletteResultItem } from './useCommandPalette';
8
9
  export { useFilterOptionMulti, useFilterOptionSingle, type FilterOptionMulti, type FilterOptionSingle } from './useFilterOption';
@@ -1,7 +1,7 @@
1
1
  import { useDebouncedRef, useLoaded } from '@basmilius/common';
2
2
  import type { FluxFilterOptionRow, FluxFilterValue } from '@flux-ui/types';
3
3
  import { computed, ref, unref, watch, type ComputedRef, type ModelRef, type Ref } from 'vue';
4
- import { isFluxFilterOptionItem } from '~flux/components/data';
4
+ import { isFluxFilterOptionItem } from '~flux/components/util';
5
5
 
6
6
  type UseAsyncFilterOptionsParams = {
7
7
  readonly currentValueIds: ComputedRef<FluxFilterValue[]>;
@@ -52,7 +52,7 @@ export function useFilterOptionMulti(name: string): FilterOptionMulti {
52
52
  values.push(value);
53
53
  }
54
54
 
55
- setValue(name, values);
55
+ setValue(name, values.length > 0 ? values : null);
56
56
  }
57
57
 
58
58
  return {currentValue, onSelect};
@@ -0,0 +1,249 @@
1
+ import { useRemembered } from '@flux-ui/internals';
2
+ import type { FluxDirection } from '@flux-ui/types';
3
+ import { computed, type ComputedRef, nextTick, onMounted, ref, type Ref, watch } from 'vue';
4
+
5
+ export type SplitViewPane = {
6
+ readonly id: number;
7
+ readonly defaultSize: number | string | undefined;
8
+ readonly minSize: number;
9
+ readonly maxSize: number | undefined;
10
+ readonly isResizable: boolean;
11
+ };
12
+
13
+ export type UseSplitViewOptions = {
14
+ readonly containerRef: Readonly<Ref<HTMLElement | null>>;
15
+ readonly direction: Readonly<Ref<FluxDirection>>;
16
+ readonly panes: Readonly<Ref<readonly SplitViewPane[]>>;
17
+ readonly rememberKey: string | undefined;
18
+ };
19
+
20
+ export type UseSplitViewReturn = {
21
+ readonly sizes: Readonly<Ref<readonly number[]>>;
22
+ readonly templateStyle: ComputedRef<Record<string, string>>;
23
+ readonly isDragging: Readonly<Ref<boolean>>;
24
+
25
+ onHandleKeyDown(evt: KeyboardEvent, handleIndex: number): void;
26
+ onHandlePointerDown(evt: PointerEvent, handleIndex: number): void;
27
+ };
28
+
29
+ const HANDLE_SIZE = 6;
30
+ const KEY_STEP = 16;
31
+ const KEY_STEP_LARGE = 64;
32
+
33
+ export function useSplitView(options: UseSplitViewOptions): UseSplitViewReturn {
34
+ const sizes = ref<number[]>([]);
35
+ const isDragging = ref(false);
36
+ const persisted = options.rememberKey
37
+ ? useRemembered<number[] | null>(`split-view/${options.rememberKey}`, null)
38
+ : null;
39
+
40
+ const containerSize = (): number => {
41
+ const el = options.containerRef.value;
42
+
43
+ if (!el) {
44
+ return 0;
45
+ }
46
+
47
+ return options.direction.value === 'horizontal' ? el.clientWidth : el.clientHeight;
48
+ };
49
+
50
+ const computeInitialSizes = (): number[] => {
51
+ const persistedValue = persisted?.value;
52
+
53
+ if (persistedValue && persistedValue.length === options.panes.value.length) {
54
+ return [...persistedValue];
55
+ }
56
+
57
+ const total = containerSize();
58
+ const handleSpace = Math.max(0, options.panes.value.length - 1) * HANDLE_SIZE;
59
+ const available = Math.max(0, total - handleSpace);
60
+ const result: number[] = [];
61
+
62
+ let claimed = 0;
63
+ let flexCount = 0;
64
+
65
+ for (const pane of options.panes.value) {
66
+ if (typeof pane.defaultSize === 'number') {
67
+ result.push(pane.defaultSize);
68
+ claimed += pane.defaultSize;
69
+ } else if (typeof pane.defaultSize === 'string' && pane.defaultSize.endsWith('%')) {
70
+ const percentage = parseFloat(pane.defaultSize) / 100;
71
+ const size = available * percentage;
72
+ result.push(size);
73
+ claimed += size;
74
+ } else {
75
+ result.push(-1);
76
+ flexCount++;
77
+ }
78
+ }
79
+
80
+ const flexShare = flexCount > 0 ? Math.max(0, (available - claimed) / flexCount) : 0;
81
+
82
+ return result.map(size => size === -1 ? flexShare : size);
83
+ };
84
+
85
+ const clampSizes = (next: number[]): number[] => {
86
+ return next.map((size, i) => {
87
+ const pane = options.panes.value[i];
88
+ const min = pane.minSize;
89
+ const max = pane.maxSize ?? Infinity;
90
+ return Math.min(Math.max(size, min), max);
91
+ });
92
+ };
93
+
94
+ onMounted(async () => {
95
+ await nextTick();
96
+ sizes.value = computeInitialSizes();
97
+ });
98
+
99
+ watch(() => options.panes.value.length, () => {
100
+ sizes.value = computeInitialSizes();
101
+ });
102
+
103
+ watch(sizes, value => {
104
+ if (persisted && !isDragging.value) {
105
+ persisted.value = [...value];
106
+ }
107
+ }, {deep: true});
108
+
109
+ const templateStyle = computed(() => {
110
+ const direction = options.direction.value;
111
+ const property = direction === 'horizontal' ? 'gridTemplateColumns' : 'gridTemplateRows';
112
+ const tracks: string[] = [];
113
+
114
+ for (let i = 0; i < sizes.value.length; i++) {
115
+ tracks.push(`${sizes.value[i]}px`);
116
+
117
+ if (i < sizes.value.length - 1) {
118
+ tracks.push(`${HANDLE_SIZE}px`);
119
+ }
120
+ }
121
+
122
+ return {[property]: tracks.join(' ')};
123
+ });
124
+
125
+ function applyDelta(handleIndex: number, delta: number): void {
126
+ const next = [...sizes.value];
127
+ const leftIndex = handleIndex;
128
+ const rightIndex = handleIndex + 1;
129
+ const leftPane = options.panes.value[leftIndex];
130
+ const rightPane = options.panes.value[rightIndex];
131
+
132
+ const leftMin = leftPane.minSize;
133
+ const leftMax = leftPane.maxSize ?? Infinity;
134
+ const rightMin = rightPane.minSize;
135
+ const rightMax = rightPane.maxSize ?? Infinity;
136
+
137
+ let newLeft = next[leftIndex] + delta;
138
+ let newRight = next[rightIndex] - delta;
139
+
140
+ if (newLeft < leftMin) {
141
+ const overshoot = leftMin - newLeft;
142
+ newLeft = leftMin;
143
+ newRight -= overshoot;
144
+ } else if (newLeft > leftMax) {
145
+ const overshoot = newLeft - leftMax;
146
+ newLeft = leftMax;
147
+ newRight += overshoot;
148
+ }
149
+
150
+ if (newRight < rightMin) {
151
+ const overshoot = rightMin - newRight;
152
+ newRight = rightMin;
153
+ newLeft -= overshoot;
154
+ } else if (newRight > rightMax) {
155
+ const overshoot = newRight - rightMax;
156
+ newRight = rightMax;
157
+ newLeft += overshoot;
158
+ }
159
+
160
+ next[leftIndex] = newLeft;
161
+ next[rightIndex] = newRight;
162
+
163
+ sizes.value = clampSizes(next);
164
+ }
165
+
166
+ function onHandlePointerDown(evt: PointerEvent, handleIndex: number): void {
167
+ if (evt.button !== 0) {
168
+ return;
169
+ }
170
+
171
+ evt.preventDefault();
172
+ const target = evt.currentTarget as HTMLElement;
173
+ target.setPointerCapture(evt.pointerId);
174
+
175
+ isDragging.value = true;
176
+
177
+ const isHorizontal = options.direction.value === 'horizontal';
178
+ const startCoord = isHorizontal ? evt.clientX : evt.clientY;
179
+ const startSizes = [...sizes.value];
180
+
181
+ const onMove = (moveEvt: PointerEvent): void => {
182
+ const currentCoord = isHorizontal ? moveEvt.clientX : moveEvt.clientY;
183
+ const delta = currentCoord - startCoord;
184
+
185
+ sizes.value = clampSizes(startSizes.map((size, i) => {
186
+ if (i === handleIndex) {
187
+ return size + delta;
188
+ }
189
+
190
+ if (i === handleIndex + 1) {
191
+ return size - delta;
192
+ }
193
+
194
+ return size;
195
+ }));
196
+ };
197
+
198
+ const onUp = (upEvt: PointerEvent): void => {
199
+ target.releasePointerCapture(upEvt.pointerId);
200
+ target.removeEventListener('pointermove', onMove);
201
+ target.removeEventListener('pointerup', onUp);
202
+ target.removeEventListener('pointercancel', onUp);
203
+
204
+ isDragging.value = false;
205
+
206
+ if (persisted) {
207
+ persisted.value = [...sizes.value];
208
+ }
209
+ };
210
+
211
+ target.addEventListener('pointermove', onMove);
212
+ target.addEventListener('pointerup', onUp);
213
+ target.addEventListener('pointercancel', onUp);
214
+ }
215
+
216
+ function onHandleKeyDown(evt: KeyboardEvent, handleIndex: number): void {
217
+ const isHorizontal = options.direction.value === 'horizontal';
218
+ const decreaseKey = isHorizontal ? 'ArrowLeft' : 'ArrowUp';
219
+ const increaseKey = isHorizontal ? 'ArrowRight' : 'ArrowDown';
220
+ const step = evt.shiftKey ? KEY_STEP_LARGE : KEY_STEP;
221
+
222
+ if (evt.key === decreaseKey) {
223
+ evt.preventDefault();
224
+ applyDelta(handleIndex, -step);
225
+ } else if (evt.key === increaseKey) {
226
+ evt.preventDefault();
227
+ applyDelta(handleIndex, step);
228
+ } else if (evt.key === 'Home') {
229
+ evt.preventDefault();
230
+ const leftPane = options.panes.value[handleIndex];
231
+ const delta = leftPane.minSize - sizes.value[handleIndex];
232
+ applyDelta(handleIndex, delta);
233
+ } else if (evt.key === 'End') {
234
+ evt.preventDefault();
235
+ const leftPane = options.panes.value[handleIndex];
236
+ const max = leftPane.maxSize ?? sizes.value[handleIndex] + sizes.value[handleIndex + 1] - options.panes.value[handleIndex + 1].minSize;
237
+ const delta = max - sizes.value[handleIndex];
238
+ applyDelta(handleIndex, delta);
239
+ }
240
+ }
241
+
242
+ return {
243
+ sizes,
244
+ templateStyle,
245
+ isDragging,
246
+ onHandleKeyDown,
247
+ onHandlePointerDown
248
+ };
249
+ }
@@ -7,9 +7,11 @@ export default function () {
7
7
  // Vue, so that explains the empty getter and function below.
8
8
  state: ref({}),
9
9
  back: () => void 0,
10
- reset: () => void 0,
10
+ clear: () => void 0,
11
+ getDefinition: () => undefined,
11
12
  getValue: () => void 0,
12
13
  hasValue: () => false,
14
+ reset: () => void 0,
13
15
  setValue: () => void 0
14
16
  });
15
17
  }
@@ -1,13 +1,15 @@
1
1
  @use '~flux/components/css/mixin';
2
2
 
3
3
  .calendar {
4
- composes: basePaneStructure from './base/Pane.module.scss';
4
+ flex-grow: 1;
5
+ }
6
+
7
+ .calendarView {
8
+ contain: paint;
5
9
 
6
10
  display: flex;
7
11
  flex-flow: column;
8
12
  flex-grow: 1;
9
- box-shadow: var(--shadow-sm);
10
- contain: paint;
11
13
  }
12
14
 
13
15
  .calendarItemRegistry {
@@ -90,16 +92,14 @@
90
92
  }
91
93
  }
92
94
 
93
- /* region Month view */
94
-
95
95
  .calendarCells {
96
96
  display: grid;
97
97
  flex-grow: 1;
98
98
  gap: 1px;
99
99
  grid-template-columns: repeat(7, minmax(180px, 1fr));
100
- grid-auto-rows: auto;
101
- overflow-x: auto;
100
+ grid-template-rows: min-content repeat(6, auto);
102
101
  background: var(--gray-100);
102
+ overflow-x: auto;
103
103
  }
104
104
 
105
105
  .calendarCell {
@@ -113,9 +113,9 @@
113
113
  padding-left: 0;
114
114
  padding-right: 0;
115
115
  color: var(--foreground-secondary);
116
- font-size: 12px;
117
- font-weight: 400;
118
- line-height: 1em;
116
+ font-size: 13px;
117
+ font-weight: 500;
118
+ line-height: 30px;
119
119
  text-align: center;
120
120
  text-transform: capitalize;
121
121
  }
@@ -127,7 +127,7 @@
127
127
  min-height: 90px;
128
128
  padding-top: 33px;
129
129
  outline: 2px dashed transparent;
130
- outline-offset: 2px;
130
+ outline-offset: -2px;
131
131
  transition: 210ms var(--swift-out);
132
132
  transition-property: background, outline-color, z-index;
133
133
  z-index: 0;
@@ -181,10 +181,6 @@
181
181
  gap: 3px;
182
182
  }
183
183
 
184
- /* endregion */
185
-
186
- /* region Time-grid view */
187
-
188
184
  .timeGrid {
189
185
  display: flex;
190
186
  flex-flow: column;
@@ -393,5 +389,3 @@
393
389
  z-index: 5;
394
390
  pointer-events: none;
395
391
  }
396
-
397
- /* endregion */
@@ -41,8 +41,8 @@
41
41
  .commentContent {
42
42
  min-width: 0;
43
43
  padding: 12px 18px;
44
- background: linear-gradient(to bottom, var(--gray-25), var(--gray-50));
45
- border: 1px solid var(--gray-200);
44
+ background: var(--primary-50);
45
+ border: 1px solid var(--primary-200);
46
46
  border-radius: calc(var(--radius) * 2);
47
47
  box-shadow: var(--shadow-xs);
48
48
  }
@@ -52,7 +52,7 @@
52
52
  }
53
53
 
54
54
  .comment.isReceived .commentContent {
55
- background: linear-gradient(to bottom, var(--gray-50), var(--gray-100));
55
+ background: var(--gray-50);
56
56
  border-color: var(--gray-200);
57
57
  border-bottom-left-radius: var(--radius);
58
58
  }
@@ -87,14 +87,6 @@
87
87
  }
88
88
  }
89
89
 
90
- [dark] .commentContent {
91
- background: linear-gradient(to bottom, var(--gray-50), var(--gray-25));
92
- }
93
-
94
- [dark] .comment.isReceived .commentContent {
95
- background: linear-gradient(to bottom, var(--gray-100), var(--gray-50));
96
- }
97
-
98
90
  @keyframes commentTyping {
99
91
  0%,
100
92
  80%,
@@ -2,7 +2,7 @@
2
2
  max-height: 50dvh;
3
3
  max-width: 100%;
4
4
  padding: 9px;
5
- width: 270px;
5
+ width: 300px;
6
6
  overflow: auto;
7
7
  scrollbar-width: none;
8
8
  transition: height 150ms var(--deceleration-curve);
@@ -85,11 +85,15 @@
85
85
  flex-grow: 1;
86
86
  }
87
87
 
88
- .filterReset {
88
+ .filterAction {
89
89
  width: 42px;
90
90
  justify-content: center;
91
91
  }
92
92
 
93
+ .filterHeaderActions {
94
+ justify-content: flex-end;
95
+ }
96
+
93
97
  .filterDatePicker {
94
98
  margin: -9px;
95
99
  }