@agnos-ui/core 0.1.1 → 0.2.0
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/components/accordion/accordion.d.ts +25 -21
- package/components/accordion/accordion.js +8 -11
- package/components/alert/alert.d.ts +2 -2
- package/components/pagination/pagination.d.ts +55 -5
- package/components/pagination/pagination.js +59 -13
- package/components/progressbar/progressbar.d.ts +2 -2
- package/components/progressbar/progressbar.js +1 -1
- package/components/rating/rating.js +8 -9
- package/components/select/select.d.ts +32 -26
- package/components/select/select.js +55 -24
- package/components/slider/slider.d.ts +70 -6
- package/components/slider/slider.js +47 -42
- package/components/toast/index.d.ts +1 -0
- package/components/toast/index.js +1 -0
- package/components/toast/toast.d.ts +44 -0
- package/components/toast/toast.js +43 -0
- package/config.d.ts +5 -0
- package/index.d.ts +2 -0
- package/index.js +2 -0
- package/package.json +2 -4
- package/services/extendWidget.d.ts +9 -5
- package/services/hash.d.ts +2 -0
- package/services/hash.js +13 -0
- package/services/navManager.d.ts +22 -15
- package/services/navManager.js +9 -3
- package/services/resizeObserver.d.ts +14 -0
- package/services/resizeObserver.js +29 -0
- package/services/transitions/bootstrap/fade.js +2 -2
- package/utils/directive.d.ts +8 -0
- package/utils/directive.js +16 -0
- package/utils/internal/dom.d.ts +15 -0
- package/utils/internal/dom.js +21 -0
- package/utils/internal/isFocusable.js +3 -1
- package/utils/internal/textDirection.d.ts +1 -1
- package/utils/stores.d.ts +14 -3
- package/utils/stores.js +22 -5
|
@@ -1,9 +1,12 @@
|
|
|
1
|
-
import { asWritable, computed, writable } from '@amadeus-it-group/tansu';
|
|
1
|
+
import { asWritable, batch, computed, writable } from '@amadeus-it-group/tansu';
|
|
2
2
|
import { autoPlacement, offset, size } from '@floating-ui/dom';
|
|
3
3
|
import { createFloatingUI } from '../../services/floatingUI';
|
|
4
4
|
import { createHasFocus } from '../../services/focustrack';
|
|
5
|
+
import { createNavManager } from '../../services/navManager';
|
|
6
|
+
import { bindDirective } from '../../utils/directive';
|
|
7
|
+
import { generateId } from '../../utils/internal/dom';
|
|
5
8
|
import { noop } from '../../utils/internal/func';
|
|
6
|
-
import { bindableDerived, stateStores, writablesForProps } from '../../utils/stores';
|
|
9
|
+
import { bindableDerived, bindableProp, stateStores, writablesForProps } from '../../utils/stores';
|
|
7
10
|
const defaultItemId = (item) => '' + item;
|
|
8
11
|
export const defaultConfig = {
|
|
9
12
|
id: undefined,
|
|
@@ -14,6 +17,7 @@ export const defaultConfig = {
|
|
|
14
17
|
filterText: '',
|
|
15
18
|
loading: false,
|
|
16
19
|
selected: [],
|
|
20
|
+
navSelector: (node) => node.querySelectorAll('.au-select-badge,input'),
|
|
17
21
|
itemIdFn: defaultItemId,
|
|
18
22
|
onOpenChange: noop,
|
|
19
23
|
onFilterTextChange: noop,
|
|
@@ -40,9 +44,10 @@ export function getSelectDefaultConfig() {
|
|
|
40
44
|
*/
|
|
41
45
|
export function createSelect(config) {
|
|
42
46
|
// Props
|
|
43
|
-
const [{ open$: _dirtyOpen$, filterText$: _dirtyFilterText$, items$, itemIdFn$, onOpenChange$, onFilterTextChange$, onSelectedChange$, allowedPlacements$, ...stateProps }, patch,] = writablesForProps(defaultConfig, config);
|
|
47
|
+
const [{ id$: _dirtyId$, open$: _dirtyOpen$, filterText$: _dirtyFilterText$, items$, itemIdFn$, onOpenChange$, onFilterTextChange$, onSelectedChange$, allowedPlacements$, navSelector$, ...stateProps }, patch,] = writablesForProps(defaultConfig, config);
|
|
44
48
|
const { selected$ } = stateProps;
|
|
45
|
-
const
|
|
49
|
+
const id$ = computed(() => _dirtyId$() ?? generateId());
|
|
50
|
+
const filterText$ = bindableProp(_dirtyFilterText$, onFilterTextChange$);
|
|
46
51
|
const { hasFocus$, directive: hasFocusDirective } = createHasFocus();
|
|
47
52
|
const open$ = bindableDerived(onOpenChange$, [_dirtyOpen$, hasFocus$], ([_dirtyOpen, hasFocus]) => _dirtyOpen && hasFocus);
|
|
48
53
|
const selectedContextsMap$ = computed(() => {
|
|
@@ -112,8 +117,31 @@ export function createSelect(config) {
|
|
|
112
117
|
}))),
|
|
113
118
|
},
|
|
114
119
|
});
|
|
120
|
+
const { directive: navDirective, refreshElements, focusFirst, focusLast, focusLeft, focusRight } = createNavManager();
|
|
121
|
+
const navManagerConfig$ = computed(() => ({
|
|
122
|
+
keys: {
|
|
123
|
+
Home: focusFirst,
|
|
124
|
+
End: focusLast,
|
|
125
|
+
ArrowLeft: focusLeft,
|
|
126
|
+
ArrowRight: focusRight,
|
|
127
|
+
},
|
|
128
|
+
selector: navSelector$(),
|
|
129
|
+
}));
|
|
130
|
+
const onRemoveBadge = (event, item) => {
|
|
131
|
+
const referenceElement = event.target;
|
|
132
|
+
refreshElements();
|
|
133
|
+
widget.api.unselect(item);
|
|
134
|
+
// Waiting for refresh by the framework, to have the elements inside or outside the dom
|
|
135
|
+
if (referenceElement instanceof HTMLElement) {
|
|
136
|
+
setTimeout(() => {
|
|
137
|
+
focusLeft({ event, referenceElement }) || focusRight({ event, referenceElement });
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
event.preventDefault();
|
|
141
|
+
};
|
|
115
142
|
const widget = {
|
|
116
143
|
...stateStores({
|
|
144
|
+
id$,
|
|
117
145
|
visibleItems$,
|
|
118
146
|
highlighted$,
|
|
119
147
|
open$,
|
|
@@ -181,40 +209,29 @@ export function createSelect(config) {
|
|
|
181
209
|
highlightLast() {
|
|
182
210
|
highlightedIndex$.set(-1);
|
|
183
211
|
},
|
|
184
|
-
focus(item) {
|
|
185
|
-
// FIXME: not implemented yet!
|
|
186
|
-
},
|
|
187
|
-
focusFirst() {
|
|
188
|
-
// FIXME: not implemented yet!
|
|
189
|
-
},
|
|
190
|
-
focusPrevious() {
|
|
191
|
-
// FIXME: not implemented yet!
|
|
192
|
-
},
|
|
193
|
-
focusNext() {
|
|
194
|
-
// FIXME: not implemented yet!
|
|
195
|
-
},
|
|
196
|
-
focusLast() {
|
|
197
|
-
// FIXME: not implemented yet!
|
|
198
|
-
},
|
|
199
212
|
open: () => widget.api.toggle(true),
|
|
200
213
|
close: () => widget.api.toggle(false),
|
|
201
214
|
toggle(isOpen) {
|
|
202
|
-
|
|
215
|
+
open$.update((value) => (isOpen != null ? isOpen : !value));
|
|
203
216
|
},
|
|
204
217
|
},
|
|
205
218
|
directives: {
|
|
206
219
|
hasFocusDirective,
|
|
207
220
|
floatingDirective,
|
|
208
221
|
referenceDirective,
|
|
222
|
+
inputContainerDirective: bindDirective(navDirective, navManagerConfig$),
|
|
209
223
|
},
|
|
210
224
|
actions: {
|
|
211
225
|
onInput({ target }) {
|
|
212
226
|
const value = target.value;
|
|
213
|
-
|
|
214
|
-
open
|
|
215
|
-
filterText
|
|
227
|
+
batch(() => {
|
|
228
|
+
open$.set(value != null && value !== '');
|
|
229
|
+
filterText$.set(value);
|
|
216
230
|
});
|
|
217
231
|
},
|
|
232
|
+
onRemoveBadgeClick(event, item) {
|
|
233
|
+
onRemoveBadge(event, item);
|
|
234
|
+
},
|
|
218
235
|
onInputKeydown(e) {
|
|
219
236
|
const { ctrlKey, key } = e;
|
|
220
237
|
let keyManaged = true;
|
|
@@ -251,7 +268,7 @@ export function createSelect(config) {
|
|
|
251
268
|
break;
|
|
252
269
|
}
|
|
253
270
|
case 'Escape':
|
|
254
|
-
|
|
271
|
+
open$.set(false);
|
|
255
272
|
break;
|
|
256
273
|
default:
|
|
257
274
|
keyManaged = false;
|
|
@@ -260,6 +277,20 @@ export function createSelect(config) {
|
|
|
260
277
|
e.preventDefault();
|
|
261
278
|
}
|
|
262
279
|
},
|
|
280
|
+
onBadgeKeydown(event, item) {
|
|
281
|
+
let keyManaged = false;
|
|
282
|
+
switch (event.key) {
|
|
283
|
+
case 'Backspace':
|
|
284
|
+
case 'Delete': {
|
|
285
|
+
onRemoveBadge(event, item);
|
|
286
|
+
keyManaged = true;
|
|
287
|
+
break;
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
if (keyManaged) {
|
|
291
|
+
event.preventDefault();
|
|
292
|
+
}
|
|
293
|
+
},
|
|
263
294
|
},
|
|
264
295
|
};
|
|
265
296
|
return widget;
|
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { WidgetsCommonPropsAndState } from '../commonProps';
|
|
2
|
-
import type { Directive, PropsConfig, Widget } from '../../types';
|
|
2
|
+
import type { Directive, PropsConfig, SlotContent, Widget, WidgetSlotContext } from '../../types';
|
|
3
|
+
export type SliderContext = WidgetSlotContext<SliderWidget>;
|
|
4
|
+
export type SliderSlotLabelContext = SliderContext & {
|
|
5
|
+
value: number;
|
|
6
|
+
};
|
|
7
|
+
export type SliderSlotHandleContext = SliderContext & {
|
|
8
|
+
item: SliderHandle;
|
|
9
|
+
};
|
|
3
10
|
export interface ProgressDisplayOptions {
|
|
4
11
|
/**
|
|
5
12
|
* Right offset of the progress in %
|
|
@@ -36,6 +43,24 @@ export interface HandleDisplayOptions {
|
|
|
36
43
|
*/
|
|
37
44
|
top: number | null;
|
|
38
45
|
}
|
|
46
|
+
export interface SliderHandle {
|
|
47
|
+
/**
|
|
48
|
+
* Value of the handle
|
|
49
|
+
*/
|
|
50
|
+
value: number;
|
|
51
|
+
/**
|
|
52
|
+
* Handle id
|
|
53
|
+
*/
|
|
54
|
+
id: number;
|
|
55
|
+
/**
|
|
56
|
+
* ariaLabel of the handle
|
|
57
|
+
*/
|
|
58
|
+
ariaLabel: string;
|
|
59
|
+
/**
|
|
60
|
+
* ariaValueText of the handle
|
|
61
|
+
*/
|
|
62
|
+
ariaValueText: string;
|
|
63
|
+
}
|
|
39
64
|
export interface SliderCommonPropsAndState extends WidgetsCommonPropsAndState {
|
|
40
65
|
/**
|
|
41
66
|
* Minimum value that can be assigned to the slider
|
|
@@ -77,6 +102,18 @@ export interface SliderCommonPropsAndState extends WidgetsCommonPropsAndState {
|
|
|
77
102
|
* It `true` slider display is inversed
|
|
78
103
|
*/
|
|
79
104
|
rtl: boolean;
|
|
105
|
+
/**
|
|
106
|
+
* Slot to change the default display of the slider
|
|
107
|
+
*/
|
|
108
|
+
slotStructure: SlotContent<SliderContext>;
|
|
109
|
+
/**
|
|
110
|
+
* Slot to change the default labels of the slider
|
|
111
|
+
*/
|
|
112
|
+
slotLabel: SlotContent<SliderSlotLabelContext>;
|
|
113
|
+
/**
|
|
114
|
+
* Slot to change the handlers
|
|
115
|
+
*/
|
|
116
|
+
slotHandle: SlotContent<SliderSlotHandleContext>;
|
|
80
117
|
}
|
|
81
118
|
export interface SliderState extends SliderCommonPropsAndState {
|
|
82
119
|
/**
|
|
@@ -106,11 +143,7 @@ export interface SliderState extends SliderCommonPropsAndState {
|
|
|
106
143
|
/**
|
|
107
144
|
* Array of the sorted handles to display
|
|
108
145
|
*/
|
|
109
|
-
sortedHandles:
|
|
110
|
-
value: number;
|
|
111
|
-
id: number;
|
|
112
|
-
ariaLabel: string;
|
|
113
|
-
}[];
|
|
146
|
+
sortedHandles: SliderHandle[];
|
|
114
147
|
/**
|
|
115
148
|
* Array of objects representing progress display options
|
|
116
149
|
*/
|
|
@@ -119,6 +152,11 @@ export interface SliderState extends SliderCommonPropsAndState {
|
|
|
119
152
|
* Array of objects representing handle display options
|
|
120
153
|
*/
|
|
121
154
|
handleDisplayOptions: HandleDisplayOptions[];
|
|
155
|
+
/**
|
|
156
|
+
* Check if the slider is interactable, meaning it is not disabled or readonly
|
|
157
|
+
* TODO: rename to `interactive`, issue #510
|
|
158
|
+
*/
|
|
159
|
+
isInteractable: boolean;
|
|
122
160
|
}
|
|
123
161
|
export interface SliderProps extends SliderCommonPropsAndState {
|
|
124
162
|
/**
|
|
@@ -128,6 +166,13 @@ export interface SliderProps extends SliderCommonPropsAndState {
|
|
|
128
166
|
* @param index - index of the handle in the original list
|
|
129
167
|
*/
|
|
130
168
|
ariaLabelHandle: (value: number, sortedIndex: number, index: number) => string;
|
|
169
|
+
/**
|
|
170
|
+
* Return the value for the 'aria-valuetext' attribute for the handle
|
|
171
|
+
* @param value - value of the handle
|
|
172
|
+
* @param sortedIndex - index of the handle in the sorted list
|
|
173
|
+
* @param index - index of the handle in the original list
|
|
174
|
+
*/
|
|
175
|
+
ariaValueText: (value: number, sortedIndex: number, index: number) => string;
|
|
131
176
|
/**
|
|
132
177
|
* An event emitted when slider values are changed
|
|
133
178
|
*
|
|
@@ -189,6 +234,13 @@ export declare function getSliderDefaultConfig(): {
|
|
|
189
234
|
* @param index - index of the handle in the original list
|
|
190
235
|
*/
|
|
191
236
|
ariaLabelHandle: (value: number, sortedIndex: number, index: number) => string;
|
|
237
|
+
/**
|
|
238
|
+
* Return the value for the 'aria-valuetext' attribute for the handle
|
|
239
|
+
* @param value - value of the handle
|
|
240
|
+
* @param sortedIndex - index of the handle in the sorted list
|
|
241
|
+
* @param index - index of the handle in the original list
|
|
242
|
+
*/
|
|
243
|
+
ariaValueText: (value: number, sortedIndex: number, index: number) => string;
|
|
192
244
|
/**
|
|
193
245
|
* An event emitted when slider values are changed
|
|
194
246
|
*
|
|
@@ -235,6 +287,18 @@ export declare function getSliderDefaultConfig(): {
|
|
|
235
287
|
* It `true` slider display is inversed
|
|
236
288
|
*/
|
|
237
289
|
rtl: boolean;
|
|
290
|
+
/**
|
|
291
|
+
* Slot to change the default display of the slider
|
|
292
|
+
*/
|
|
293
|
+
slotStructure: SlotContent<SliderContext>;
|
|
294
|
+
/**
|
|
295
|
+
* Slot to change the default labels of the slider
|
|
296
|
+
*/
|
|
297
|
+
slotLabel: SlotContent<SliderSlotLabelContext>;
|
|
298
|
+
/**
|
|
299
|
+
* Slot to change the handlers
|
|
300
|
+
*/
|
|
301
|
+
slotHandle: SlotContent<SliderSlotHandleContext>;
|
|
238
302
|
className: string;
|
|
239
303
|
};
|
|
240
304
|
/**
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { computed,
|
|
2
|
-
import {
|
|
3
|
-
import { createStoreDirective, directiveSubscribe, mergeDirectives } from '../../utils/directive';
|
|
4
|
-
import { stateStores } from '../../utils/stores';
|
|
5
|
-
import { typeArray, typeBoolean, typeFunction, typeNumber, typeNumberInRangeFactory } from '../../utils/writables';
|
|
1
|
+
import { computed, writable } from '@amadeus-it-group/tansu';
|
|
2
|
+
import { createStoreDirective, mergeDirectives } from '../../utils/directive';
|
|
6
3
|
import { noop } from '../../utils/internal/func';
|
|
7
4
|
import { getDecimalPrecision } from '../../utils/internal/math';
|
|
5
|
+
import { bindableProp, stateStores, writablesForProps } from '../../utils/stores';
|
|
6
|
+
import { typeArray, typeBoolean, typeFunction, typeNumber, typeNumberInRangeFactory } from '../../utils/writables';
|
|
7
|
+
import { createResizeObserver } from '../../services/resizeObserver';
|
|
8
8
|
const defaultSliderConfig = {
|
|
9
9
|
min: 0,
|
|
10
10
|
max: 100,
|
|
@@ -13,12 +13,16 @@ const defaultSliderConfig = {
|
|
|
13
13
|
disabled: false,
|
|
14
14
|
vertical: false,
|
|
15
15
|
className: '',
|
|
16
|
-
ariaLabelHandle: (value
|
|
16
|
+
ariaLabelHandle: (value) => '' + value,
|
|
17
|
+
ariaValueText: (value) => '' + value,
|
|
17
18
|
onValuesChange: noop,
|
|
18
19
|
values: [0],
|
|
19
20
|
showValueLabels: true,
|
|
20
21
|
showMinMaxLabels: true,
|
|
21
22
|
rtl: false,
|
|
23
|
+
slotStructure: undefined,
|
|
24
|
+
slotLabel: ({ value }) => '' + value,
|
|
25
|
+
slotHandle: undefined,
|
|
22
26
|
};
|
|
23
27
|
/**
|
|
24
28
|
* Returns a shallow copy of the default slider config.
|
|
@@ -35,6 +39,7 @@ const configValidator = {
|
|
|
35
39
|
disabled: typeBoolean,
|
|
36
40
|
vertical: typeBoolean,
|
|
37
41
|
ariaLabelHandle: typeFunction,
|
|
42
|
+
ariaValueText: typeFunction,
|
|
38
43
|
onValuesChange: typeFunction,
|
|
39
44
|
values: typeArray,
|
|
40
45
|
showValueLabels: typeBoolean,
|
|
@@ -62,17 +67,16 @@ const computeCleanValue = (value, min, max, intStepSize, decimalPrecision) => {
|
|
|
62
67
|
return +(((((value - min) * magnitude) % intStepSize < intStepSize / 2 ? indexMin : indexMin + 1) * intStepSize) / magnitude + min).toFixed(decimalPrecision);
|
|
63
68
|
};
|
|
64
69
|
/**
|
|
65
|
-
* Method to update the
|
|
70
|
+
* Method to update the values for the slider keyboard navigation
|
|
66
71
|
* @param handleIndex - index of the handle to update
|
|
67
|
-
* @param
|
|
68
|
-
* @param values - slider values
|
|
72
|
+
* @param values$ - writable signal that contains values
|
|
69
73
|
* @param stepSize - slider step size
|
|
70
|
-
* @param updateDirection - if equals 1
|
|
74
|
+
* @param updateDirection - if equals 1 value is increased, if equals -1 value is decreased
|
|
71
75
|
*/
|
|
72
|
-
const
|
|
73
|
-
|
|
76
|
+
const updateValue = (handleIndex, values$, stepSize, updateDirection) => {
|
|
77
|
+
values$.update((value) => {
|
|
74
78
|
value = [...value];
|
|
75
|
-
value[handleIndex] =
|
|
79
|
+
value[handleIndex] = value[handleIndex] + stepSize * updateDirection;
|
|
76
80
|
return value;
|
|
77
81
|
});
|
|
78
82
|
};
|
|
@@ -99,7 +103,7 @@ const getUpdateDirection = (vertical, rtl, keysVertical) => {
|
|
|
99
103
|
export function createSlider(config) {
|
|
100
104
|
const [{
|
|
101
105
|
// dirty inputs that need adjustment:
|
|
102
|
-
min$: _dirtyMinimum$, max$: _dirtyMaximum$, stepSize$, rtl$, values$: _dirtyValues$, ariaLabelHandle$, onValuesChange$, showValueLabels$, showMinMaxLabels$, ...stateProps }, patch,] = writablesForProps(defaultSliderConfig, config, configValidator);
|
|
106
|
+
min$: _dirtyMinimum$, max$: _dirtyMaximum$, stepSize$, rtl$, values$: _dirtyValues$, ariaLabelHandle$, ariaValueText$, onValuesChange$, showValueLabels$, showMinMaxLabels$, ...stateProps }, patch,] = writablesForProps(defaultSliderConfig, config, configValidator);
|
|
103
107
|
const { vertical$, disabled$, readonly$ } = stateProps;
|
|
104
108
|
let _prevCoordinate = -1;
|
|
105
109
|
// clean inputs adjustment
|
|
@@ -119,39 +123,35 @@ export function createSlider(config) {
|
|
|
119
123
|
});
|
|
120
124
|
const _decimalPrecision$ = computed(() => Math.max(getDecimalPrecision(stepSize$()), getDecimalPrecision(min$()), getDecimalPrecision(max$())));
|
|
121
125
|
const _intStepSize$ = computed(() => stepSize$() * Math.pow(10, _decimalPrecision$()));
|
|
122
|
-
const values$ =
|
|
126
|
+
const values$ = bindableProp(_dirtyValues$, onValuesChange$, (dirtyValues) => {
|
|
127
|
+
const min = min$();
|
|
128
|
+
const max = max$();
|
|
129
|
+
const intStepSize = _intStepSize$();
|
|
130
|
+
const decimalPrecision = _decimalPrecision$();
|
|
131
|
+
return dirtyValues.map((dv) => computeCleanValue(dv, min, max, intStepSize, decimalPrecision));
|
|
132
|
+
}, typeArray.equal);
|
|
123
133
|
// computed
|
|
124
134
|
const { directive: sliderDirective, element$: sliderDom$ } = createStoreDirective();
|
|
125
135
|
const { directive: minLabelDirective, element$: minLabelDom$ } = createStoreDirective();
|
|
126
136
|
const { directive: maxLabelDirective, element$: maxLabelDom$ } = createStoreDirective();
|
|
127
|
-
const
|
|
128
|
-
if (!sliderDom) {
|
|
129
|
-
set({});
|
|
130
|
-
return;
|
|
131
|
-
}
|
|
132
|
-
const resizeObserver = new ResizeObserver(() => {
|
|
133
|
-
set({});
|
|
134
|
-
});
|
|
135
|
-
resizeObserver.observe(sliderDom);
|
|
136
|
-
return () => resizeObserver.disconnect();
|
|
137
|
-
}, {});
|
|
137
|
+
const { directive: resizeDirective, dimensions$ } = createResizeObserver();
|
|
138
138
|
const updateSliderSize$ = writable({});
|
|
139
139
|
const sliderDomRect$ = computed(() => {
|
|
140
|
-
|
|
140
|
+
dimensions$();
|
|
141
141
|
updateSliderSize$();
|
|
142
142
|
return sliderDom$()?.getBoundingClientRect() ?? {};
|
|
143
143
|
}, {
|
|
144
144
|
equal: Object.is,
|
|
145
145
|
});
|
|
146
146
|
const minLabelDomRect$ = computed(() => {
|
|
147
|
-
|
|
147
|
+
dimensions$();
|
|
148
148
|
updateSliderSize$();
|
|
149
149
|
return minLabelDom$()?.getBoundingClientRect() ?? {};
|
|
150
150
|
}, {
|
|
151
151
|
equal: (a, b) => Object.is(a, b),
|
|
152
152
|
});
|
|
153
153
|
const maxLabelDomRect$ = computed(() => {
|
|
154
|
-
|
|
154
|
+
dimensions$();
|
|
155
155
|
updateSliderSize$();
|
|
156
156
|
return maxLabelDom$()?.getBoundingClientRect() ?? {};
|
|
157
157
|
}, {
|
|
@@ -168,9 +168,13 @@ export function createSlider(config) {
|
|
|
168
168
|
.sort((a, b) => a.value - b.value);
|
|
169
169
|
});
|
|
170
170
|
const sortedHandles$ = computed(() => {
|
|
171
|
-
const ariaLabelHandle = ariaLabelHandle$();
|
|
171
|
+
const ariaLabelHandle = ariaLabelHandle$(), ariaValueText = ariaValueText$();
|
|
172
172
|
return _sortedHandlesValues$().map((sortedValue, index) => {
|
|
173
|
-
return {
|
|
173
|
+
return {
|
|
174
|
+
...sortedValue,
|
|
175
|
+
ariaLabel: ariaLabelHandle(sortedValue.value, index, sortedValue.id),
|
|
176
|
+
ariaValueText: ariaValueText(sortedValue.value, index, sortedValue.id),
|
|
177
|
+
};
|
|
174
178
|
});
|
|
175
179
|
});
|
|
176
180
|
const valuesPercent$ = computed(() => values$().map((val) => percentCompute(val)));
|
|
@@ -281,7 +285,7 @@ export function createSlider(config) {
|
|
|
281
285
|
clickedPercent = rtl$() ? 1 - clickedPercent : clickedPercent;
|
|
282
286
|
const derivedHandleIndex = handleNumber ?? getClosestSliderHandle(clickedPercent);
|
|
283
287
|
const newValue = clickedPercent * (max$() - min$()) + min$();
|
|
284
|
-
|
|
288
|
+
values$.update((dh) => {
|
|
285
289
|
dh = [...dh];
|
|
286
290
|
dh[derivedHandleIndex] = newValue;
|
|
287
291
|
return dh;
|
|
@@ -312,7 +316,7 @@ export function createSlider(config) {
|
|
|
312
316
|
patch,
|
|
313
317
|
api: {},
|
|
314
318
|
directives: {
|
|
315
|
-
sliderDirective: mergeDirectives(sliderDirective,
|
|
319
|
+
sliderDirective: mergeDirectives(sliderDirective, resizeDirective),
|
|
316
320
|
minLabelDirective,
|
|
317
321
|
maxLabelDirective,
|
|
318
322
|
},
|
|
@@ -322,30 +326,30 @@ export function createSlider(config) {
|
|
|
322
326
|
},
|
|
323
327
|
keydown(event, handleIndex) {
|
|
324
328
|
const { key } = event;
|
|
325
|
-
const rtl = rtl$(),
|
|
329
|
+
const rtl = rtl$(), stepSize = stepSize$(), min = min$(), max = max$(), vertical = vertical$();
|
|
326
330
|
if (isInteractable$()) {
|
|
327
331
|
switch (key) {
|
|
328
332
|
case 'ArrowDown':
|
|
329
|
-
|
|
333
|
+
updateValue(handleIndex, values$, stepSize, getUpdateDirection(vertical, rtl, true));
|
|
330
334
|
break;
|
|
331
335
|
case 'ArrowLeft':
|
|
332
|
-
|
|
336
|
+
updateValue(handleIndex, values$, stepSize, getUpdateDirection(vertical, rtl, false));
|
|
333
337
|
break;
|
|
334
338
|
case 'ArrowUp':
|
|
335
|
-
|
|
339
|
+
updateValue(handleIndex, values$, stepSize, -1 * getUpdateDirection(vertical, rtl, true));
|
|
336
340
|
break;
|
|
337
341
|
case 'ArrowRight':
|
|
338
|
-
|
|
342
|
+
updateValue(handleIndex, values$, stepSize, -1 * getUpdateDirection(vertical, rtl, false));
|
|
339
343
|
break;
|
|
340
344
|
case 'Home':
|
|
341
|
-
|
|
345
|
+
values$.update((value) => {
|
|
342
346
|
value = [...value];
|
|
343
347
|
value[handleIndex] = min;
|
|
344
348
|
return value;
|
|
345
349
|
});
|
|
346
350
|
break;
|
|
347
351
|
case 'End':
|
|
348
|
-
|
|
352
|
+
values$.update((value) => {
|
|
349
353
|
value = [...value];
|
|
350
354
|
value[handleIndex] = max;
|
|
351
355
|
return value;
|
|
@@ -366,10 +370,11 @@ export function createSlider(config) {
|
|
|
366
370
|
},
|
|
367
371
|
mouseDown(event, handleId) {
|
|
368
372
|
event.preventDefault();
|
|
373
|
+
const currentTarget = event.target;
|
|
369
374
|
const handleDrag = (e) => {
|
|
370
375
|
e.preventDefault();
|
|
371
376
|
const newCoord = vertical$() ? e.clientY : e.clientX;
|
|
372
|
-
|
|
377
|
+
currentTarget.focus();
|
|
373
378
|
if (_prevCoordinate !== newCoord) {
|
|
374
379
|
_prevCoordinate = newCoord;
|
|
375
380
|
adjustCoordinate(newCoord, handleId);
|
|
@@ -377,7 +382,7 @@ export function createSlider(config) {
|
|
|
377
382
|
};
|
|
378
383
|
if (isInteractable$()) {
|
|
379
384
|
updateSliderSize$.set({});
|
|
380
|
-
|
|
385
|
+
currentTarget.focus();
|
|
381
386
|
document.addEventListener('mousemove', handleDrag);
|
|
382
387
|
// TODO mouse up doesn't work outside the handle area
|
|
383
388
|
document.addEventListener('mouseup', () => {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toast';
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './toast';
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import type { ExtendWidgetAdaptSlotWidgetProps, ExtendWidgetInterfaces } from '../../services/extendWidget';
|
|
2
|
+
import type { Directive, PropsConfig, SlotContent, Widget, WidgetSlotContext } from '../../types';
|
|
3
|
+
import type { CommonAlertApi, CommonAlertDirectives, CommonAlertProps, CommonAlertState } from '../alert/common';
|
|
4
|
+
export type ToastContext = WidgetSlotContext<ToastWidget>;
|
|
5
|
+
export interface ToastExtraProps {
|
|
6
|
+
/**
|
|
7
|
+
* If `true` automatically hides the toast after the delay.
|
|
8
|
+
*/
|
|
9
|
+
autohide: boolean;
|
|
10
|
+
/**
|
|
11
|
+
* Delay in milliseconds before hiding the toast.
|
|
12
|
+
*/
|
|
13
|
+
delay: number;
|
|
14
|
+
/**
|
|
15
|
+
* Header template for the toast component
|
|
16
|
+
*/
|
|
17
|
+
slotHeader: SlotContent<ToastContext>;
|
|
18
|
+
}
|
|
19
|
+
export interface ExtraDirectives {
|
|
20
|
+
/**
|
|
21
|
+
* Directive that handles the autohide of the toast component
|
|
22
|
+
*/
|
|
23
|
+
autohideDirective: Directive;
|
|
24
|
+
}
|
|
25
|
+
export interface ToastState extends ExtendWidgetAdaptSlotWidgetProps<CommonAlertState, ToastExtraProps, ExtraDirectives> {
|
|
26
|
+
}
|
|
27
|
+
export interface ToastProps extends ExtendWidgetAdaptSlotWidgetProps<CommonAlertProps, ToastExtraProps, ExtraDirectives> {
|
|
28
|
+
}
|
|
29
|
+
export interface ToastApi extends CommonAlertApi {
|
|
30
|
+
}
|
|
31
|
+
export interface ToastDirectives extends ExtendWidgetInterfaces<CommonAlertDirectives, ExtraDirectives> {
|
|
32
|
+
}
|
|
33
|
+
export type ToastWidget = Widget<ToastProps, ToastState, ToastApi, object, ToastDirectives>;
|
|
34
|
+
/**
|
|
35
|
+
* Retrieve a shallow copy of the default toast config
|
|
36
|
+
* @returns the default toast config
|
|
37
|
+
*/
|
|
38
|
+
export declare function getToastDefaultConfig(): ToastProps;
|
|
39
|
+
/**
|
|
40
|
+
* Create a ToastWidget with given config props
|
|
41
|
+
* @param config - an optional toast config
|
|
42
|
+
* @returns a ToastWidget
|
|
43
|
+
*/
|
|
44
|
+
export declare function createToast(config?: PropsConfig<ToastProps>): ToastWidget;
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { computed } from '@amadeus-it-group/tansu';
|
|
2
|
+
import { extendWidgetProps } from '../../services/extendWidget';
|
|
3
|
+
import { directiveSubscribe } from '../../utils/directive';
|
|
4
|
+
import { typeBoolean, typeNumberInRangeFactory } from '../../utils/writables';
|
|
5
|
+
import { createCommonAlert, getCommonAlertDefaultConfig } from '../alert/common';
|
|
6
|
+
const toastDefaultConfig = {
|
|
7
|
+
autohide: true,
|
|
8
|
+
delay: 5000,
|
|
9
|
+
slotHeader: undefined,
|
|
10
|
+
};
|
|
11
|
+
const toastConfigValidator = {
|
|
12
|
+
autohide: typeBoolean,
|
|
13
|
+
delay: typeNumberInRangeFactory(0, +Infinity, { strict: true }),
|
|
14
|
+
};
|
|
15
|
+
/**
|
|
16
|
+
* Retrieve a shallow copy of the default toast config
|
|
17
|
+
* @returns the default toast config
|
|
18
|
+
*/
|
|
19
|
+
export function getToastDefaultConfig() {
|
|
20
|
+
return { ...getCommonAlertDefaultConfig(), ...toastDefaultConfig };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Create a ToastWidget with given config props
|
|
24
|
+
* @param config - an optional toast config
|
|
25
|
+
* @returns a ToastWidget
|
|
26
|
+
*/
|
|
27
|
+
export function createToast(config) {
|
|
28
|
+
let _timeout;
|
|
29
|
+
const extendedAlert = extendWidgetProps(createCommonAlert, toastDefaultConfig, toastConfigValidator)(config);
|
|
30
|
+
const time$ = computed(() => {
|
|
31
|
+
clearTimeout(_timeout);
|
|
32
|
+
if (extendedAlert.stores.autohide$()) {
|
|
33
|
+
_timeout = setTimeout(() => extendedAlert.api.close(), extendedAlert.stores.delay$());
|
|
34
|
+
}
|
|
35
|
+
});
|
|
36
|
+
return {
|
|
37
|
+
...extendedAlert,
|
|
38
|
+
directives: {
|
|
39
|
+
...extendedAlert.directives,
|
|
40
|
+
autohideDirective: directiveSubscribe(time$),
|
|
41
|
+
},
|
|
42
|
+
};
|
|
43
|
+
}
|
package/config.d.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type { SelectProps } from './components/select/select';
|
|
|
7
7
|
import type { AccordionProps } from './components/accordion/accordion';
|
|
8
8
|
import type { ProgressbarProps } from './components/progressbar/progressbar';
|
|
9
9
|
import type { SliderProps } from './components/slider/slider';
|
|
10
|
+
import type { ToastProps } from './components/toast/toast';
|
|
10
11
|
export type Partial2Levels<T> = Partial<{
|
|
11
12
|
[Level1 in keyof T]: Partial<T[Level1]>;
|
|
12
13
|
}>;
|
|
@@ -78,4 +79,8 @@ export interface WidgetsConfig {
|
|
|
78
79
|
* slider widget config
|
|
79
80
|
*/
|
|
80
81
|
slider: SliderProps;
|
|
82
|
+
/**
|
|
83
|
+
* toast widget config
|
|
84
|
+
*/
|
|
85
|
+
toast: ToastProps;
|
|
81
86
|
}
|
package/index.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export * from './components/progressbar';
|
|
|
8
8
|
export * from './components/rating';
|
|
9
9
|
export * from './components/select';
|
|
10
10
|
export * from './components/slider';
|
|
11
|
+
export * from './components/toast';
|
|
11
12
|
export * from './config';
|
|
12
13
|
export * from './services/extendWidget';
|
|
13
14
|
export * from './services/floatingUI';
|
|
@@ -15,6 +16,7 @@ export * from './services/focustrack';
|
|
|
15
16
|
export * from './services/intersection';
|
|
16
17
|
export * from './services/navManager';
|
|
17
18
|
export * from './services/portal';
|
|
19
|
+
export * from './services/resizeObserver';
|
|
18
20
|
export * from './services/siblingsInert';
|
|
19
21
|
export * from './services/transitions/baseTransitions';
|
|
20
22
|
export * from './services/transitions/cssTransitions';
|
package/index.js
CHANGED
|
@@ -10,6 +10,7 @@ export * from './components/progressbar';
|
|
|
10
10
|
export * from './components/rating';
|
|
11
11
|
export * from './components/select';
|
|
12
12
|
export * from './components/slider';
|
|
13
|
+
export * from './components/toast';
|
|
13
14
|
// config
|
|
14
15
|
export * from './config';
|
|
15
16
|
// services
|
|
@@ -19,6 +20,7 @@ export * from './services/focustrack';
|
|
|
19
20
|
export * from './services/intersection';
|
|
20
21
|
export * from './services/navManager';
|
|
21
22
|
export * from './services/portal';
|
|
23
|
+
export * from './services/resizeObserver';
|
|
22
24
|
export * from './services/siblingsInert';
|
|
23
25
|
// services transitions
|
|
24
26
|
export * from './services/transitions/baseTransitions';
|
package/package.json
CHANGED
|
@@ -47,14 +47,12 @@
|
|
|
47
47
|
"default": "./utils/*.js"
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
-
"dependencies": {
|
|
51
|
-
"@amadeus-it-group/tansu": "1.0.0"
|
|
52
|
-
},
|
|
53
50
|
"peerDependencies": {
|
|
51
|
+
"@amadeus-it-group/tansu": "*",
|
|
54
52
|
"@floating-ui/dom": "*"
|
|
55
53
|
},
|
|
56
54
|
"sideEffects": false,
|
|
57
|
-
"version": "0.
|
|
55
|
+
"version": "0.2.0",
|
|
58
56
|
"homepage": "https://amadeusitgroup.github.io/AgnosUI/latest/",
|
|
59
57
|
"bugs": "https://github.com/AmadeusITGroup/AgnosUI/issues",
|
|
60
58
|
"license": "MIT",
|