@agnos-ui/core 0.1.0 → 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.
@@ -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 filterText$ = bindableDerived(onFilterTextChange$, [_dirtyFilterText$]);
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
- _dirtyOpen$.update((value) => (isOpen != null ? isOpen : !value));
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
- patch({
214
- open: value != null && value !== '',
215
- filterText: value,
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
- _dirtyOpen$.set(false);
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, derived, writable } from '@amadeus-it-group/tansu';
2
- import { bindableDerived, writablesForProps } from '../../utils/stores';
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, _index) => '' + 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 dirtyValues for the slider keyboard navigation
70
+ * Method to update the values for the slider keyboard navigation
66
71
  * @param handleIndex - index of the handle to update
67
- * @param _dirtyValues$ - writable signal that contains dirtyValues
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 - value is increased, if equals -1 values is decreased
74
+ * @param updateDirection - if equals 1 value is increased, if equals -1 value is decreased
71
75
  */
72
- const updateDirtyValue = (handleIndex, _dirtyValues$, values, stepSize, updateDirection) => {
73
- _dirtyValues$.update((value) => {
76
+ const updateValue = (handleIndex, values$, stepSize, updateDirection) => {
77
+ values$.update((value) => {
74
78
  value = [...value];
75
- value[handleIndex] = values[handleIndex] + stepSize * updateDirection;
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$ = bindableDerived(onValuesChange$, [_dirtyValues$, min$, max$, _intStepSize$, _decimalPrecision$], ([dirtyValues, min, max, intStepSize, decimalPrecision]) => dirtyValues.map((dv) => computeCleanValue(dv, min, max, intStepSize, decimalPrecision)), typeArray.equal);
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 sliderResized$ = derived(sliderDom$, (sliderDom, set) => {
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
- sliderResized$();
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
- sliderResized$();
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
- sliderResized$();
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 { ...sortedValue, ariaLabel: ariaLabelHandle(sortedValue.value, index, sortedValue.id) };
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
- _dirtyValues$.update((dh) => {
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, directiveSubscribe(sliderResized$)),
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$(), values = values$(), stepSize = stepSize$(), min = min$(), max = max$(), vertical = vertical$();
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
- updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, getUpdateDirection(vertical, rtl, true));
333
+ updateValue(handleIndex, values$, stepSize, getUpdateDirection(vertical, rtl, true));
330
334
  break;
331
335
  case 'ArrowLeft':
332
- updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, getUpdateDirection(vertical, rtl, false));
336
+ updateValue(handleIndex, values$, stepSize, getUpdateDirection(vertical, rtl, false));
333
337
  break;
334
338
  case 'ArrowUp':
335
- updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, -1 * getUpdateDirection(vertical, rtl, true));
339
+ updateValue(handleIndex, values$, stepSize, -1 * getUpdateDirection(vertical, rtl, true));
336
340
  break;
337
341
  case 'ArrowRight':
338
- updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, -1 * getUpdateDirection(vertical, rtl, false));
342
+ updateValue(handleIndex, values$, stepSize, -1 * getUpdateDirection(vertical, rtl, false));
339
343
  break;
340
344
  case 'Home':
341
- _dirtyValues$.update((value) => {
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
- _dirtyValues$.update((value) => {
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
- event.target.focus();
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
- event.target.focus();
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.1.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",