@agnos-ui/core 0.0.1-alpha.0 → 0.0.1-alpha.10

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 (126) hide show
  1. package/README.md +4 -4
  2. package/{dist/lib → components/accordion}/accordion.d.ts +29 -25
  3. package/{dist/lib → components/accordion}/accordion.js +81 -77
  4. package/components/accordion/index.d.ts +1 -0
  5. package/components/accordion/index.js +1 -0
  6. package/components/alert/alert.d.ts +31 -0
  7. package/components/alert/alert.js +22 -0
  8. package/{dist/lib/alert.d.ts → components/alert/common.d.ts} +17 -20
  9. package/{dist/lib/alert.js → components/alert/common.js} +22 -19
  10. package/components/alert/index.d.ts +2 -0
  11. package/components/alert/index.js +2 -0
  12. package/components/commonProps.d.ts +6 -0
  13. package/components/commonProps.js +1 -0
  14. package/components/modal/index.d.ts +1 -0
  15. package/components/modal/index.js +1 -0
  16. package/{dist/lib → components}/modal/modal.d.ts +30 -29
  17. package/{dist/lib → components}/modal/modal.js +59 -29
  18. package/components/pagination/index.d.ts +2 -0
  19. package/components/pagination/index.js +2 -0
  20. package/{dist/lib → components/pagination}/pagination.d.ts +5 -14
  21. package/{dist/lib → components/pagination}/pagination.js +6 -5
  22. package/components/progressbar/index.d.ts +1 -0
  23. package/components/progressbar/index.js +1 -0
  24. package/components/progressbar/progressbar.d.ts +86 -0
  25. package/components/progressbar/progressbar.js +78 -0
  26. package/components/rating/index.d.ts +1 -0
  27. package/components/rating/index.js +1 -0
  28. package/{dist/lib → components/rating}/rating.d.ts +6 -13
  29. package/{dist/lib → components/rating}/rating.js +6 -9
  30. package/components/select/index.d.ts +1 -0
  31. package/components/select/index.js +1 -0
  32. package/components/select/select.d.ts +337 -0
  33. package/components/select/select.js +266 -0
  34. package/components/slider/index.d.ts +1 -0
  35. package/components/slider/index.js +1 -0
  36. package/components/slider/slider.d.ts +245 -0
  37. package/components/slider/slider.js +413 -0
  38. package/{dist/lib/config.d.ts → config.d.ts} +17 -7
  39. package/{dist/lib/config.js → config.js} +3 -3
  40. package/index.d.ts +25 -0
  41. package/index.js +31 -0
  42. package/package.json +42 -28
  43. package/services/extendWidget.d.ts +23 -0
  44. package/services/extendWidget.js +35 -0
  45. package/services/floatingUI.d.ts +56 -0
  46. package/services/floatingUI.js +105 -0
  47. package/{dist/lib/services → services}/focustrack.js +5 -5
  48. package/services/intersection.d.ts +34 -0
  49. package/services/intersection.js +55 -0
  50. package/services/navManager.d.ts +93 -0
  51. package/services/navManager.js +172 -0
  52. package/{dist/lib/services → services}/portal.d.ts +7 -0
  53. package/services/portal.js +44 -0
  54. package/{dist/lib/services → services}/siblingsInert.d.ts +2 -1
  55. package/{dist/lib/services → services}/siblingsInert.js +2 -2
  56. package/{dist/lib → services}/transitions/baseTransitions.d.ts +15 -2
  57. package/{dist/lib → services}/transitions/baseTransitions.js +21 -10
  58. package/services/transitions/bootstrap/collapse.d.ts +2 -0
  59. package/services/transitions/bootstrap/fade.d.ts +1 -0
  60. package/services/transitions/bootstrap.d.ts +2 -0
  61. package/services/transitions/bootstrap.js +2 -0
  62. package/services/transitions/collapse.d.ts +43 -0
  63. package/{dist/lib → services}/transitions/collapse.js +15 -2
  64. package/{dist/lib → services}/transitions/cssTransitions.d.ts +6 -0
  65. package/{dist/lib → services}/transitions/cssTransitions.js +8 -4
  66. package/{dist/lib → services}/transitions/simpleClassTransition.d.ts +12 -1
  67. package/services/transitions/simpleClassTransition.js +42 -0
  68. package/{dist/lib/types.d.ts → types.d.ts} +43 -4
  69. package/types.js +14 -0
  70. package/{dist/lib/services/directiveUtils.js → utils/directive.js} +1 -1
  71. package/utils/internal/checks.d.ts +49 -0
  72. package/utils/internal/checks.js +60 -0
  73. package/utils/internal/dom.d.ts +25 -0
  74. package/utils/internal/dom.js +61 -0
  75. package/utils/internal/func.d.ts +11 -0
  76. package/utils/internal/func.js +11 -0
  77. package/utils/internal/isFocusable.d.ts +9 -0
  78. package/utils/internal/isFocusable.js +35 -0
  79. package/utils/internal/math.d.ts +5 -0
  80. package/utils/internal/math.js +13 -0
  81. package/utils/internal/promise.d.ts +87 -0
  82. package/utils/internal/promise.js +169 -0
  83. package/utils/internal/scrollbars.d.ts +8 -0
  84. package/{dist/lib/modal → utils/internal}/scrollbars.js +7 -1
  85. package/utils/internal/sort.d.ts +16 -0
  86. package/utils/internal/sort.js +28 -0
  87. package/utils/internal/textDirection.d.ts +7 -0
  88. package/utils/internal/textDirection.js +7 -0
  89. package/utils/internal/traversal.d.ts +54 -0
  90. package/utils/internal/traversal.js +105 -0
  91. package/{dist/lib/services → utils}/stores.d.ts +67 -33
  92. package/{dist/lib/services → utils}/stores.js +121 -59
  93. package/utils/writables.d.ts +32 -0
  94. package/utils/writables.js +72 -0
  95. package/dist/lib/index.d.ts +0 -11
  96. package/dist/lib/index.js +0 -11
  97. package/dist/lib/modal/scrollbars.d.ts +0 -2
  98. package/dist/lib/select.d.ts +0 -199
  99. package/dist/lib/select.js +0 -240
  100. package/dist/lib/services/checks.d.ts +0 -32
  101. package/dist/lib/services/checks.js +0 -43
  102. package/dist/lib/services/index.d.ts +0 -6
  103. package/dist/lib/services/index.js +0 -6
  104. package/dist/lib/services/portal.js +0 -33
  105. package/dist/lib/services/writables.d.ts +0 -7
  106. package/dist/lib/services/writables.js +0 -16
  107. package/dist/lib/transitions/bootstrap/collapse.d.ts +0 -2
  108. package/dist/lib/transitions/bootstrap/fade.d.ts +0 -1
  109. package/dist/lib/transitions/bootstrap/index.d.ts +0 -2
  110. package/dist/lib/transitions/bootstrap/index.js +0 -2
  111. package/dist/lib/transitions/collapse.d.ts +0 -29
  112. package/dist/lib/transitions/index.d.ts +0 -5
  113. package/dist/lib/transitions/index.js +0 -5
  114. package/dist/lib/transitions/simpleClassTransition.js +0 -28
  115. package/dist/lib/transitions/utils.d.ts +0 -20
  116. package/dist/lib/transitions/utils.js +0 -83
  117. package/dist/lib/tsdoc-metadata.json +0 -11
  118. package/dist/lib/types.js +0 -7
  119. package/dist/lib/utils.d.ts +0 -2
  120. package/dist/lib/utils.js +0 -2
  121. /package/{dist/lib/pagination.utils.d.ts → components/pagination/bootstrap.d.ts} +0 -0
  122. /package/{dist/lib/pagination.utils.js → components/pagination/bootstrap.js} +0 -0
  123. /package/{dist/lib/services → services}/focustrack.d.ts +0 -0
  124. /package/{dist/lib → services}/transitions/bootstrap/collapse.js +0 -0
  125. /package/{dist/lib → services}/transitions/bootstrap/fade.js +0 -0
  126. /package/{dist/lib/services/directiveUtils.d.ts → utils/directive.d.ts} +0 -0
@@ -0,0 +1,245 @@
1
+ import type { WidgetsCommonPropsAndState } from '../commonProps';
2
+ import type { Directive, PropsConfig, Widget } from '../../types';
3
+ export interface ProgressDisplayOptions {
4
+ /**
5
+ * Right offset of the progress in %
6
+ */
7
+ left: number | null;
8
+ /**
9
+ * Left offset of the progress in %
10
+ */
11
+ right: number | null;
12
+ /**
13
+ * Top offset of the progress in %
14
+ */
15
+ top: number | null;
16
+ /**
17
+ * Bottom offset of the progress in %
18
+ */
19
+ bottom: number | null;
20
+ /**
21
+ * Width of the progress in %
22
+ */
23
+ width: number;
24
+ /**
25
+ * Height of hte progress in %
26
+ */
27
+ height: number;
28
+ }
29
+ export interface HandleDisplayOptions {
30
+ /**
31
+ * Left offset of the handle in %
32
+ */
33
+ left: number | null;
34
+ /**
35
+ * Top offset of the handle in %
36
+ */
37
+ top: number | null;
38
+ }
39
+ export interface SliderCommonPropsAndState extends WidgetsCommonPropsAndState {
40
+ /**
41
+ * Minimum value that can be assigned to the slider
42
+ */
43
+ min: number;
44
+ /**
45
+ * Maximum value that can be assigned to the slider
46
+ */
47
+ max: number;
48
+ /**
49
+ * Unit value between slider steps
50
+ */
51
+ stepSize: number;
52
+ /**
53
+ * If `true` slider value cannot be changed but the slider is still focusable
54
+ */
55
+ readonly: boolean;
56
+ /**
57
+ * If `true` slider value cannot be changed and the slider cannot be focused
58
+ */
59
+ disabled: boolean;
60
+ /**
61
+ * If `true` is vertically positioned otherwise it is horizontal
62
+ */
63
+ vertical: boolean;
64
+ /**
65
+ * Current slider values
66
+ */
67
+ values: number[];
68
+ /**
69
+ * If `true` the value labels are displayed on the slider
70
+ */
71
+ showValueLabels: boolean;
72
+ /**
73
+ * If `true` the min and max labels are displayed on the slider
74
+ */
75
+ showMinMaxLabels: boolean;
76
+ /**
77
+ * It `true` slider display is inversed
78
+ */
79
+ rtl: boolean;
80
+ }
81
+ export interface SliderState extends SliderCommonPropsAndState {
82
+ /**
83
+ * Sorted slider values
84
+ */
85
+ sortedValues: number[];
86
+ /**
87
+ * Combined label left offset in %
88
+ */
89
+ combinedLabelPositionLeft: number;
90
+ /**
91
+ * Combined label top offset in %
92
+ */
93
+ combinedLabelPositionTop: number;
94
+ /**
95
+ * If true, the minimum label will be visible
96
+ */
97
+ minValueLabelDisplay: boolean;
98
+ /**
99
+ * If true, the maximum label will be visible
100
+ */
101
+ maxValueLabelDisplay: boolean;
102
+ /**
103
+ * If true, the label when the handles are close is visible
104
+ */
105
+ combinedLabelDisplay: boolean;
106
+ /**
107
+ * Array of the sorted handles to display
108
+ */
109
+ sortedHandles: {
110
+ value: number;
111
+ id: number;
112
+ ariaLabel: string;
113
+ }[];
114
+ /**
115
+ * Array of objects representing progress display options
116
+ */
117
+ progressDisplayOptions: ProgressDisplayOptions[];
118
+ /**
119
+ * Array of objects representing handle display options
120
+ */
121
+ handleDisplayOptions: HandleDisplayOptions[];
122
+ }
123
+ export interface SliderProps extends SliderCommonPropsAndState {
124
+ /**
125
+ * Return the value for the 'aria-label' attribute for the handle
126
+ * @param value - value of the handle
127
+ * @param sortedIndex - index of the handle in the sorted list
128
+ * @param index - index of the handle in the original list
129
+ */
130
+ ariaLabelHandle: (value: number, sortedIndex: number, index: number) => string;
131
+ /**
132
+ * An event emitted when slider values are changed
133
+ *
134
+ * Event payload equals to the updated slider values
135
+ */
136
+ onValuesChange: (values: number[]) => void;
137
+ }
138
+ export interface SliderApi {
139
+ }
140
+ export interface SliderDirectives {
141
+ /**
142
+ * Directive to get the slider component elementRef
143
+ */
144
+ sliderDirective: Directive;
145
+ /**
146
+ * Directive to get the minLabel elementRef
147
+ */
148
+ minLabelDirective: Directive;
149
+ /**
150
+ * Directive to get the maxLabel elementRef
151
+ */
152
+ maxLabelDirective: Directive;
153
+ }
154
+ export interface SliderActions {
155
+ /**
156
+ * Method to handle click on the slider
157
+ * @param event - mouse event
158
+ */
159
+ click(event: MouseEvent): void;
160
+ /**
161
+ * Method to process the keyboard event
162
+ * @param event - keyboard event object
163
+ * @param handleNumber - id of the modified handle
164
+ */
165
+ keydown(event: KeyboardEvent, handleNumber: number): void;
166
+ /**
167
+ * Method describing the behavior of the slider handle on mouse down event
168
+ * @param event - mouse event
169
+ * @param handleId - numeric id of the handle
170
+ */
171
+ mouseDown(event: MouseEvent, handleId: number): void;
172
+ /**
173
+ * Method describing the behavior of the slider handle on touch start event
174
+ * @param event - touch event
175
+ * @param handleId - number id of the handle
176
+ */
177
+ touchStart(event: TouchEvent, handleId: number): void;
178
+ }
179
+ export type SliderWidget = Widget<SliderProps, SliderState, SliderApi, SliderActions, SliderDirectives>;
180
+ /**
181
+ * Returns a shallow copy of the default slider config.
182
+ * @returns a copy of the default config
183
+ */
184
+ export declare function getSliderDefaultConfig(): {
185
+ /**
186
+ * Return the value for the 'aria-label' attribute for the handle
187
+ * @param value - value of the handle
188
+ * @param sortedIndex - index of the handle in the sorted list
189
+ * @param index - index of the handle in the original list
190
+ */
191
+ ariaLabelHandle: (value: number, sortedIndex: number, index: number) => string;
192
+ /**
193
+ * An event emitted when slider values are changed
194
+ *
195
+ * Event payload equals to the updated slider values
196
+ */
197
+ onValuesChange: (values: number[]) => void;
198
+ /**
199
+ * Minimum value that can be assigned to the slider
200
+ */
201
+ min: number;
202
+ /**
203
+ * Maximum value that can be assigned to the slider
204
+ */
205
+ max: number;
206
+ /**
207
+ * Unit value between slider steps
208
+ */
209
+ stepSize: number;
210
+ /**
211
+ * If `true` slider value cannot be changed but the slider is still focusable
212
+ */
213
+ readonly: boolean;
214
+ /**
215
+ * If `true` slider value cannot be changed and the slider cannot be focused
216
+ */
217
+ disabled: boolean;
218
+ /**
219
+ * If `true` is vertically positioned otherwise it is horizontal
220
+ */
221
+ vertical: boolean;
222
+ /**
223
+ * Current slider values
224
+ */
225
+ values: number[];
226
+ /**
227
+ * If `true` the value labels are displayed on the slider
228
+ */
229
+ showValueLabels: boolean;
230
+ /**
231
+ * If `true` the min and max labels are displayed on the slider
232
+ */
233
+ showMinMaxLabels: boolean;
234
+ /**
235
+ * It `true` slider display is inversed
236
+ */
237
+ rtl: boolean;
238
+ className: string;
239
+ };
240
+ /**
241
+ * Create a slider widget with given config props
242
+ * @param config - an optional slider config
243
+ * @returns a SliderWidget
244
+ */
245
+ export declare function createSlider(config?: PropsConfig<SliderProps>): SliderWidget;
@@ -0,0 +1,413 @@
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';
6
+ import { noop } from '../../utils/internal/func';
7
+ import { getDecimalPrecision } from '../../utils/internal/math';
8
+ const defaultSliderConfig = {
9
+ min: 0,
10
+ max: 100,
11
+ stepSize: 1,
12
+ readonly: false,
13
+ disabled: false,
14
+ vertical: false,
15
+ className: '',
16
+ ariaLabelHandle: (value, _index) => '' + value,
17
+ onValuesChange: noop,
18
+ values: [0],
19
+ showValueLabels: true,
20
+ showMinMaxLabels: true,
21
+ rtl: false,
22
+ };
23
+ /**
24
+ * Returns a shallow copy of the default slider config.
25
+ * @returns a copy of the default config
26
+ */
27
+ export function getSliderDefaultConfig() {
28
+ return { ...defaultSliderConfig };
29
+ }
30
+ const configValidator = {
31
+ min: typeNumber,
32
+ max: typeNumber,
33
+ stepSize: typeNumberInRangeFactory(0, +Infinity, { strict: true }),
34
+ readonly: typeBoolean,
35
+ disabled: typeBoolean,
36
+ vertical: typeBoolean,
37
+ ariaLabelHandle: typeFunction,
38
+ onValuesChange: typeFunction,
39
+ values: typeArray,
40
+ showValueLabels: typeBoolean,
41
+ showMinMaxLabels: typeBoolean,
42
+ rtl: typeBoolean,
43
+ };
44
+ /**
45
+ * Computes slider clean value based on the input parameters
46
+ * @param value - dirty value
47
+ * @param min - minimum value
48
+ * @param max - maximum value
49
+ * @param intStepSize - step size converted to integer
50
+ * @param decimalPrecision - maximum decimum precision of slider values
51
+ * @returns adjusted clean value
52
+ */
53
+ const computeCleanValue = (value, min, max, intStepSize, decimalPrecision) => {
54
+ const magnitude = Math.pow(10, decimalPrecision);
55
+ if (value >= max) {
56
+ return max;
57
+ }
58
+ else if (value <= min) {
59
+ return min;
60
+ }
61
+ const indexMin = Math.floor(((value - min) * magnitude) / intStepSize);
62
+ return +(((((value - min) * magnitude) % intStepSize < intStepSize / 2 ? indexMin : indexMin + 1) * intStepSize) / magnitude + min).toFixed(decimalPrecision);
63
+ };
64
+ /**
65
+ * Method to update the dirtyValues for the slider keyboard navigation
66
+ * @param handleIndex - index of the handle to update
67
+ * @param _dirtyValues$ - writable signal that contains dirtyValues
68
+ * @param values - slider values
69
+ * @param stepSize - slider step size
70
+ * @param updateDirection - if equals 1 - value is increased, if equals -1 values is decreased
71
+ */
72
+ const updateDirtyValue = (handleIndex, _dirtyValues$, values, stepSize, updateDirection) => {
73
+ _dirtyValues$.update((value) => {
74
+ value = [...value];
75
+ value[handleIndex] = values[handleIndex] + stepSize * updateDirection;
76
+ return value;
77
+ });
78
+ };
79
+ const getUpdateDirection = (vertical, rtl, keysVertical) => {
80
+ if (vertical && rtl) {
81
+ return keysVertical ? 1 : -1;
82
+ }
83
+ else if (vertical && !rtl) {
84
+ return -1;
85
+ }
86
+ else if (!vertical && rtl) {
87
+ return keysVertical ? -1 : 1;
88
+ }
89
+ else if (!vertical && !rtl) {
90
+ return -1;
91
+ }
92
+ return 1;
93
+ };
94
+ /**
95
+ * Create a slider widget with given config props
96
+ * @param config - an optional slider config
97
+ * @returns a SliderWidget
98
+ */
99
+ export function createSlider(config) {
100
+ const [{
101
+ // dirty inputs that need adjustment:
102
+ min$: _dirtyMinimum$, max$: _dirtyMaximum$, stepSize$, rtl$, values$: _dirtyValues$, ariaLabelHandle$, onValuesChange$, showValueLabels$, showMinMaxLabels$, ...stateProps }, patch,] = writablesForProps(defaultSliderConfig, config, configValidator);
103
+ const { vertical$, disabled$, readonly$ } = stateProps;
104
+ let _prevCoordinate = -1;
105
+ // clean inputs adjustment
106
+ const min$ = computed(() => {
107
+ const _dirtyMinimum = _dirtyMinimum$(), _dirtyMaximum = _dirtyMaximum$();
108
+ if (_dirtyMinimum === _dirtyMaximum) {
109
+ return defaultSliderConfig.min;
110
+ }
111
+ return Math.min(_dirtyMinimum, _dirtyMaximum);
112
+ });
113
+ const max$ = computed(() => {
114
+ const _dirtyMinimum = _dirtyMinimum$(), _dirtyMaximum = _dirtyMaximum$();
115
+ if (_dirtyMinimum === _dirtyMaximum) {
116
+ return defaultSliderConfig.max;
117
+ }
118
+ return Math.max(_dirtyMinimum, _dirtyMaximum);
119
+ });
120
+ const _decimalPrecision$ = computed(() => Math.max(getDecimalPrecision(stepSize$()), getDecimalPrecision(min$()), getDecimalPrecision(max$())));
121
+ 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);
123
+ // computed
124
+ const { directive: sliderDirective, element$: sliderDom$ } = createStoreDirective();
125
+ const { directive: minLabelDirective, element$: minLabelDom$ } = createStoreDirective();
126
+ 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
+ }, {});
138
+ const updateSliderSize$ = writable({});
139
+ const sliderDomRect$ = computed(() => {
140
+ sliderResized$();
141
+ updateSliderSize$();
142
+ return sliderDom$()?.getBoundingClientRect() ?? {};
143
+ }, {
144
+ equal: Object.is,
145
+ });
146
+ const minLabelDomRect$ = computed(() => {
147
+ sliderResized$();
148
+ updateSliderSize$();
149
+ return minLabelDom$()?.getBoundingClientRect() ?? {};
150
+ }, {
151
+ equal: (a, b) => Object.is(a, b),
152
+ });
153
+ const maxLabelDomRect$ = computed(() => {
154
+ sliderResized$();
155
+ updateSliderSize$();
156
+ return maxLabelDom$()?.getBoundingClientRect() ?? {};
157
+ }, {
158
+ equal: (a, b) => Object.is(a, b),
159
+ });
160
+ const sliderDomRectOffset$ = computed(() => (vertical$() ? sliderDomRect$().top : sliderDomRect$().left));
161
+ const sliderDomRectSize$ = computed(() => (vertical$() ? sliderDomRect$().height : sliderDomRect$().width));
162
+ const sortedValues$ = computed(() => [...values$()].sort((a, b) => a - b));
163
+ const _sortedHandlesValues$ = computed(() => {
164
+ return values$()
165
+ .map((val, index) => {
166
+ return { id: index, value: val };
167
+ })
168
+ .sort((a, b) => a.value - b.value);
169
+ });
170
+ const sortedHandles$ = computed(() => {
171
+ const ariaLabelHandle = ariaLabelHandle$();
172
+ return _sortedHandlesValues$().map((sortedValue, index) => {
173
+ return { ...sortedValue, ariaLabel: ariaLabelHandle(sortedValue.value, index, sortedValue.id) };
174
+ });
175
+ });
176
+ const valuesPercent$ = computed(() => values$().map((val) => percentCompute(val)));
177
+ const sortedValuesPercent$ = computed(() => [...valuesPercent$()].sort((a, b) => a - b));
178
+ const minLabelWidth$ = computed(() => (minLabelDomRect$().width / sliderDomRectSize$()) * 100);
179
+ const maxLabelWidth$ = computed(() => (maxLabelDomRect$().width / sliderDomRectSize$()) * 100);
180
+ const minValueLabelDisplay$ = computed(() => {
181
+ if (!showMinMaxLabels$()) {
182
+ return false;
183
+ }
184
+ else if (!showValueLabels$()) {
185
+ return true;
186
+ }
187
+ const minLabelWidth = minLabelWidth$();
188
+ return rtl$()
189
+ ? !valuesPercent$().some((percent) => 100 - percent > 100 - minLabelWidth - 1)
190
+ : !valuesPercent$().some((percent) => percent < minLabelWidth + 1);
191
+ });
192
+ const maxValueLabelDisplay$ = computed(() => {
193
+ if (!showMinMaxLabels$()) {
194
+ return false;
195
+ }
196
+ else if (!showValueLabels$()) {
197
+ return true;
198
+ }
199
+ const maxLabelWidth = maxLabelWidth$();
200
+ return rtl$()
201
+ ? !valuesPercent$().some((percent) => 100 - percent < maxLabelWidth + 1)
202
+ : !valuesPercent$().some((percent) => percent > 100 - maxLabelWidth - 1);
203
+ });
204
+ // TODO define the intersection value
205
+ const combinedLabelDisplay$ = computed(() => {
206
+ const values = values$();
207
+ return values.length == 2 && Math.abs(values[0] - values[1]) < 10;
208
+ });
209
+ const isInteractable$ = computed(() => !disabled$() && !readonly$());
210
+ const combinedLabelPositionLeft$ = computed(() => {
211
+ const sortedValuesPercent = sortedValuesPercent$();
212
+ const combinedPosition = (sortedValuesPercent[0] + sortedValuesPercent[1]) / 2;
213
+ return vertical$() || sortedValuesPercent.length != 2 ? 0 : rtl$() ? 100 - combinedPosition : combinedPosition;
214
+ });
215
+ const combinedLabelPositionTop$ = computed(() => {
216
+ const sortedValuesPercent = sortedValuesPercent$();
217
+ const combinedPosition = 100 - (sortedValuesPercent[0] + sortedValuesPercent[1]) / 2;
218
+ return vertical$() && sortedValuesPercent.length == 2 ? (rtl$() ? 100 - combinedPosition : combinedPosition) : 0;
219
+ });
220
+ const handleDisplayOptions$ = computed(() => {
221
+ const vertical = vertical$(), rtl = rtl$();
222
+ return valuesPercent$().map((vp, index) => {
223
+ return {
224
+ left: rtl ? (vertical ? null : 100 - vp) : vertical ? null : vp,
225
+ top: rtl ? (vertical ? vp : null) : vertical ? 100 - vp : null,
226
+ };
227
+ });
228
+ });
229
+ const progressDisplayOptions$ = computed(() => {
230
+ const vertical = vertical$(), sortedValuesPercent = sortedValuesPercent$(), rtl = rtl$();
231
+ if (sortedValuesPercent.length === 1) {
232
+ return [
233
+ {
234
+ left: vertical ? null : rtl ? null : 0,
235
+ right: vertical ? null : rtl ? 0 : null,
236
+ bottom: vertical ? (rtl ? null : 0) : null,
237
+ top: vertical ? (rtl ? 0 : null) : null,
238
+ width: vertical ? 100 : sortedValuesPercent[0],
239
+ height: vertical ? sortedValuesPercent[0] : 100,
240
+ },
241
+ ];
242
+ }
243
+ else {
244
+ return sortedValuesPercent
245
+ .map((svp, index, array) => {
246
+ return {
247
+ left: vertical ? null : rtl ? null : svp,
248
+ right: vertical ? null : rtl ? array[index] : null,
249
+ bottom: vertical ? (rtl ? null : svp) : null,
250
+ top: vertical ? (rtl ? array[index] : null) : null,
251
+ width: vertical ? 100 : index === array.length - 1 ? svp : array[index + 1] - svp,
252
+ height: vertical ? (index === array.length - 1 ? svp : array[index + 1] - svp) : 100,
253
+ };
254
+ })
255
+ .slice(0, sortedValuesPercent.length - 1);
256
+ }
257
+ });
258
+ // functions
259
+ const percentCompute = (value) => {
260
+ const min = min$();
261
+ return ((value - min) * 100) / (max$() - min);
262
+ };
263
+ const getClosestSliderHandle = (clickedPercent) => {
264
+ const values = values$();
265
+ if (values.length === 1) {
266
+ return 0;
267
+ }
268
+ const sortedValues = sortedValues$();
269
+ const closestBigger = sortedValues.find((sv) => sv > clickedPercent * 100);
270
+ const closestBiggerIndex = closestBigger ? sortedValues.indexOf(closestBigger) : sortedValues.length - 1;
271
+ const midPoint = sortedValues[closestBiggerIndex - 1] + (sortedValues[closestBiggerIndex] - sortedValues[closestBiggerIndex - 1]) / 2;
272
+ const closestValue = sortedValues[clickedPercent * 100 <= midPoint ? closestBiggerIndex - 1 : closestBiggerIndex];
273
+ return values.indexOf(closestValue);
274
+ };
275
+ const adjustCoordinate = (clickedCoordinate, handleNumber) => {
276
+ if (isInteractable$()) {
277
+ const sliderDomRectSize = sliderDomRectSize$(), sliderDomRectOffset = sliderDomRectOffset$();
278
+ let clickedPercent = vertical$()
279
+ ? (sliderDomRectSize - clickedCoordinate + sliderDomRectOffset) / sliderDomRectSize
280
+ : (clickedCoordinate - sliderDomRectOffset) / sliderDomRectSize;
281
+ clickedPercent = rtl$() ? 1 - clickedPercent : clickedPercent;
282
+ const derivedHandleIndex = handleNumber ?? getClosestSliderHandle(clickedPercent);
283
+ const newValue = clickedPercent * (max$() - min$()) + min$();
284
+ _dirtyValues$.update((dh) => {
285
+ dh = [...dh];
286
+ dh[derivedHandleIndex] = newValue;
287
+ return dh;
288
+ });
289
+ }
290
+ };
291
+ return {
292
+ ...stateStores({
293
+ min$,
294
+ max$,
295
+ stepSize$,
296
+ values$,
297
+ sortedValues$,
298
+ sortedHandles$,
299
+ minValueLabelDisplay$,
300
+ maxValueLabelDisplay$,
301
+ combinedLabelDisplay$,
302
+ isInteractable$,
303
+ combinedLabelPositionLeft$,
304
+ combinedLabelPositionTop$,
305
+ progressDisplayOptions$,
306
+ handleDisplayOptions$,
307
+ showValueLabels$,
308
+ showMinMaxLabels$,
309
+ rtl$,
310
+ ...stateProps,
311
+ }),
312
+ patch,
313
+ api: {},
314
+ directives: {
315
+ sliderDirective: mergeDirectives(sliderDirective, directiveSubscribe(sliderResized$)),
316
+ minLabelDirective,
317
+ maxLabelDirective,
318
+ },
319
+ actions: {
320
+ click(event) {
321
+ adjustCoordinate(vertical$() ? event.clientY : event.clientX);
322
+ },
323
+ keydown(event, handleIndex) {
324
+ const { key } = event;
325
+ const rtl = rtl$(), values = values$(), stepSize = stepSize$(), min = min$(), max = max$(), vertical = vertical$();
326
+ if (isInteractable$()) {
327
+ switch (key) {
328
+ case 'ArrowDown':
329
+ updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, getUpdateDirection(vertical, rtl, true));
330
+ break;
331
+ case 'ArrowLeft':
332
+ updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, getUpdateDirection(vertical, rtl, false));
333
+ break;
334
+ case 'ArrowUp':
335
+ updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, -1 * getUpdateDirection(vertical, rtl, true));
336
+ break;
337
+ case 'ArrowRight':
338
+ updateDirtyValue(handleIndex, _dirtyValues$, values, stepSize, -1 * getUpdateDirection(vertical, rtl, false));
339
+ break;
340
+ case 'Home':
341
+ _dirtyValues$.update((value) => {
342
+ value = [...value];
343
+ value[handleIndex] = min;
344
+ return value;
345
+ });
346
+ break;
347
+ case 'End':
348
+ _dirtyValues$.update((value) => {
349
+ value = [...value];
350
+ value[handleIndex] = max;
351
+ return value;
352
+ });
353
+ break;
354
+ case 'PageUp':
355
+ // TODO it is optional in accessibility guidelines, so define the skip value for steps and write unit test
356
+ break;
357
+ case 'PageDown':
358
+ // TODO it is optional in accessibility guidelines, so define the skip value for steps and write unit test
359
+ break;
360
+ default:
361
+ return;
362
+ }
363
+ event.preventDefault();
364
+ event.stopPropagation();
365
+ }
366
+ },
367
+ mouseDown(event, handleId) {
368
+ event.preventDefault();
369
+ const handleDrag = (e) => {
370
+ e.preventDefault();
371
+ const newCoord = vertical$() ? e.clientY : e.clientX;
372
+ event.target.focus();
373
+ if (_prevCoordinate !== newCoord) {
374
+ _prevCoordinate = newCoord;
375
+ adjustCoordinate(newCoord, handleId);
376
+ }
377
+ };
378
+ if (isInteractable$()) {
379
+ event.target.focus();
380
+ document.addEventListener('mousemove', handleDrag);
381
+ // TODO mouse up doesn't work outside the handle area
382
+ document.addEventListener('mouseup', () => {
383
+ document.removeEventListener('mousemove', handleDrag);
384
+ }, { once: true });
385
+ }
386
+ },
387
+ touchStart(event, handleId) {
388
+ event.preventDefault();
389
+ const handleDrag = (e) => {
390
+ e.preventDefault();
391
+ const newCoord = vertical$() ? e.touches[0].clientY : e.touches[0].clientX;
392
+ event.target.focus();
393
+ if (_prevCoordinate !== newCoord) {
394
+ _prevCoordinate = newCoord;
395
+ adjustCoordinate(newCoord, handleId);
396
+ }
397
+ };
398
+ if (isInteractable$()) {
399
+ event.target.focus();
400
+ document.addEventListener('touchmove', handleDrag);
401
+ document.addEventListener('touchend', () => {
402
+ document.removeEventListener('touchmove', handleDrag);
403
+ document.removeEventListener('touchcancel', handleDrag);
404
+ }, { once: true });
405
+ document.addEventListener('touchcancel', () => {
406
+ document.removeEventListener('touchmove', handleDrag);
407
+ document.removeEventListener('touchend', handleDrag);
408
+ }, { once: true });
409
+ }
410
+ },
411
+ },
412
+ };
413
+ }
@@ -1,10 +1,12 @@
1
1
  import type { ReadableSignal, WritableSignal } from '@amadeus-it-group/tansu';
2
- import type { ModalProps } from './modal/modal';
3
- import type { AlertProps } from './alert';
4
- import type { PaginationProps } from './pagination';
5
- import type { RatingProps } from './rating';
6
- import type { SelectProps } from './select';
7
- import type { AccordionProps } from './accordion';
2
+ import type { ModalProps } from './components/modal/modal';
3
+ import type { AlertProps } from './components/alert/alert';
4
+ import type { PaginationProps } from './components/pagination/pagination';
5
+ import type { RatingProps } from './components/rating/rating';
6
+ import type { SelectProps } from './components/select/select';
7
+ import type { AccordionProps } from './components/accordion/accordion';
8
+ import type { ProgressbarProps } from './components/progressbar/progressbar';
9
+ import type { SliderProps } from './components/slider/slider';
8
10
  export type Partial2Levels<T> = Partial<{
9
11
  [Level1 in keyof T]: Partial<T[Level1]>;
10
12
  }>;
@@ -59,7 +61,7 @@ export interface WidgetsConfig {
59
61
  /**
60
62
  * the modal widget config
61
63
  */
62
- modal: ModalProps;
64
+ modal: ModalProps<any>;
63
65
  /**
64
66
  * the alert widget config
65
67
  */
@@ -68,4 +70,12 @@ export interface WidgetsConfig {
68
70
  * the accordion widget config
69
71
  */
70
72
  accordion: AccordionProps;
73
+ /**
74
+ * the progress bar widget config
75
+ */
76
+ progressbar: ProgressbarProps;
77
+ /**
78
+ * slider widget config
79
+ */
80
+ slider: SliderProps;
71
81
  }