Skip to content

Commit

Permalink
refactor: removing bindableDerived
Browse files Browse the repository at this point in the history
  • Loading branch information
divdavem committed Dec 15, 2023
1 parent 276af8c commit 255ad4f
Show file tree
Hide file tree
Showing 9 changed files with 79 additions and 216 deletions.
6 changes: 3 additions & 3 deletions core/src/components/accordion/accordion.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type {ReadableSignals} from '../../utils/stores';
import {bindableDerived, stateStores, writablesForProps, normalizeConfigStores, mergeConfigStores} from '../../utils/stores';
import {stateStores, writablesForProps, normalizeConfigStores, mergeConfigStores} from '../../utils/stores';
import type {TransitionFn} from '../../services/transitions/baseTransitions';
import {createTransition} from '../../services/transitions/baseTransitions';
import {collapseVerticalTransition} from '../../services/transitions/bootstrap/collapse';
import type {ConfigValidator, Directive, PropsConfig, SlotContent, Widget, WidgetSlotContext} from '../../types';
import type {ReadableSignal} from '@amadeus-it-group/tansu';
import {computed, readable, writable} from '@amadeus-it-group/tansu';
import {computed, writable} from '@amadeus-it-group/tansu';
import {noop} from '../../utils/internal/func';
import type {WidgetsCommonPropsAndState} from '../commonProps';
import {typeBoolean, typeFunction, typeString} from '../../utils/writables';
Expand Down Expand Up @@ -479,7 +479,7 @@ function createAccordionItem(
] = writablesForProps(defaultItemConfig, config, configItemValidator);

const initDone$ = writable(false);
const itemId$ = bindableDerived(readable(noop), [_dirtyItemId$], ([dirtyItemId]) => (dirtyItemId ? dirtyItemId : getItemId()));
const itemId$ = computed(() => _dirtyItemId$() ?? getItemId());
const shouldBeInDOM$ = computed(() => {
return itemDestroyOnHide$() === false || !itemTransition.state$().hidden;
});
Expand Down
19 changes: 12 additions & 7 deletions core/src/components/pagination/pagination.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {computed} from '@amadeus-it-group/tansu';
import {INVALID_VALUE} from '../../types';
import {bindableDerived, stateStores, writablesForProps} from '../../utils/stores';
import {stateStores, writablesForProps} from '../../utils/stores';
import {clamp, isNumber} from '../../utils/internal/checks';
import {typeBoolean, typeFunction, typeNumber, typeString} from '../../utils/writables';
import type {ConfigValidator, PropsConfig, Widget, SlotContent, WidgetSlotContext} from '../../types';
Expand Down Expand Up @@ -388,7 +388,12 @@ export function createPagination(config?: PropsConfig<PaginationProps>): Paginat
return pageCount;
});
// current page
const page$ = bindableDerived(onPageChange$, [_dirtyPage$, pageCount$], ([dirtyPage, pageCount]) => clamp(dirtyPage, pageCount, 1));
// const page$ = bindableDerived(onPageChange$, [_dirtyPage$, pageCount$], ([dirtyPage, pageCount]) => clamp(dirtyPage, pageCount, 1));
const page$ = computed(() => clamp(_dirtyPage$(), pageCount$(), 1));
const changePage = (page: number) => {
_dirtyPage$.set(page);
onPageChange$()(page);
};

const pages$ = computed(() => pagesFactory$()(page$(), pageCount$()));

Expand Down Expand Up @@ -419,35 +424,35 @@ export function createPagination(config?: PropsConfig<PaginationProps>): Paginat
* Value is normalized between 1 and the number of page
*/
select(pageNumber: number) {
patch({page: pageNumber});
changePage(pageNumber);
},

/**
* Select the first page
*/
first() {
patch({page: 1});
changePage(1);
},

/**
* Select the previous page
*/
previous() {
patch({page: page$() - 1});
changePage(page$() - 1);
},

/**
* Select the next page
*/
next() {
patch({page: page$() + 1});
changePage(page$() + 1);
},

/**
* Select the last page
*/
last() {
patch({page: pageCount$()});
changePage(pageCount$());
},
},
api: {
Expand Down
9 changes: 4 additions & 5 deletions core/src/components/progressbar/progressbar.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
import {clamp} from '../../utils/internal/checks';
import {typeBoolean, typeFunction, typeNumber, typeString} from '../../utils/writables';
import {bindableDerived, stateStores, writablesForProps} from '../../utils/stores';
import {stateStores, writablesForProps} from '../../utils/stores';
import type {ConfigValidator, PropsConfig, SlotContent, Widget, WidgetSlotContext} from '../../types';
import {computed, readable} from '@amadeus-it-group/tansu';
import {noop} from '../../utils/internal/func';
import {computed} from '@amadeus-it-group/tansu';
import type {WidgetsCommonPropsAndState} from '../commonProps';

export type ProgressbarContext = WidgetSlotContext<ProgressbarWidget>;
Expand Down Expand Up @@ -138,8 +137,8 @@ export function createProgressbar(config?: PropsConfig<ProgressbarProps>): Progr
patch,
] = writablesForProps(defaultConfig, config, configValidator);

const max$ = bindableDerived(readable(noop), [_dirtyMaximum$, min$], ([dirtyMaximum, minimum]) => Math.max(minimum, dirtyMaximum));
const value$ = bindableDerived(readable(noop), [_dirtyValue$, min$, max$], ([dirtyValue, min, max]) => clamp(dirtyValue, max, min));
const max$ = computed(() => Math.max(min$(), _dirtyMaximum$()));
const value$ = computed(() => clamp(_dirtyValue$(), max$(), min$()));
const percentage$ = computed(() => {
const max = max$();
const min = min$();
Expand Down
22 changes: 13 additions & 9 deletions core/src/components/rating/rating.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {computed, writable} from '@amadeus-it-group/tansu';
import {INVALID_VALUE} from '../../types';
import {bindableDerived, stateStores, writablesForProps} from '../../utils/stores';
import {stateStores, writablesForProps} from '../../utils/stores';
import {clamp, isNumber} from '../../utils/internal/checks';
import {typeBoolean, typeFunction, typeNumber, typeString} from '../../utils/writables';
import type {ConfigValidator, PropsConfig, SlotContent, Widget} from '../../types';
Expand Down Expand Up @@ -221,17 +221,21 @@ export function createRating(config?: PropsConfig<RatingProps>): RatingWidget {
// clean inputs adjustment to valid range
const tabindex$ = computed(() => (disabled$() ? -1 : _dirtyTabindex$()));

const rating$ = bindableDerived(onRatingChange$, [_dirtyRating$, maxRating$], ([dirtyRating, maxRating]) => clamp(dirtyRating, maxRating));
// const rating$ = bindableDerived(onRatingChange$, [_dirtyRating$, maxRating$], ([dirtyRating, maxRating]) => clamp(dirtyRating, maxRating));
const rating$ = computed(() => clamp(_dirtyRating$(), maxRating$()));
const changeRating = (rating: number) => {
_dirtyRating$.set(rating);
onRatingChange$()(rating);
};

// internal inputs
const _hoveredRating$ = writable(0);

// computed
const isInteractive$ = computed(() => !disabled$() && !readonly$());
const visibleRating$ = computed(() => {
const rating = rating$(); // call rating unconditionnally (for the bindableDerived to stay active)
const hoveredRating = _hoveredRating$();
return hoveredRating !== 0 ? hoveredRating : rating;
return hoveredRating !== 0 ? hoveredRating : rating$();
});
const ariaValueText$ = computed(() => ariaValueTextFn$()(visibleRating$(), maxRating$()));
const stars$ = computed(() => {
Expand All @@ -256,7 +260,7 @@ export function createRating(config?: PropsConfig<RatingProps>): RatingWidget {
actions: {
click: (index: number) => {
if (isInteractive$() && index > 0 && index <= maxRating$()) {
patch({rating: rating$() === index && resettable$() ? 0 : index});
changeRating(rating$() === index && resettable$() ? 0 : index);
}
},
hover: (index: number) => {
Expand All @@ -277,19 +281,19 @@ export function createRating(config?: PropsConfig<RatingProps>): RatingWidget {
switch (key) {
case 'ArrowLeft':
case 'ArrowDown':
patch({rating: rating$() - 1});
changeRating(rating$() - 1);
break;
case 'ArrowRight':
case 'ArrowUp':
patch({rating: rating$() + 1});
changeRating(rating$() + 1);
break;
case 'Home':
case 'PageDown':
patch({rating: 0});
changeRating(0);
break;
case 'End':
case 'PageUp':
patch({rating: maxRating$()});
changeRating(maxRating$());
break;
default:
return;
Expand Down
33 changes: 15 additions & 18 deletions core/src/components/select/select.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type {HasFocus} from '../../services/focustrack';
import {createHasFocus} from '../../services/focustrack';
import type {PropsConfig, SlotContent, Widget, WidgetSlotContext} from '../../types';
import {noop} from '../../utils/internal/func';
import {bindableDerived, stateStores, writablesForProps} from '../../utils/stores';
import {stateStores, writablesForProps} from '../../utils/stores';
import type {WidgetsCommonPropsAndState} from '../commonProps';

/**
Expand Down Expand Up @@ -335,25 +335,16 @@ export function getSelectDefaultConfig() {
export function createSelect<Item>(config?: PropsConfig<SelectProps<Item>>): SelectWidget<Item> {
// Props
const [
{
open$: _dirtyOpen$,
filterText$: _dirtyFilterText$,
items$,
itemIdFn$,
onOpenChange$,
onFilterTextChange$,
onSelectedChange$,
allowedPlacements$,
...stateProps
},
{open$: _dirtyOpen$, filterText$, items$, itemIdFn$, onOpenChange$, onFilterTextChange$, onSelectedChange$, allowedPlacements$, ...stateProps},
patch,
] = writablesForProps<SelectProps<Item>>(defaultConfig, config);
const {selected$} = stateProps;

const filterText$ = bindableDerived(onFilterTextChange$, [_dirtyFilterText$]);
// const filterText$ = bindableDerived(onFilterTextChange$, [_dirtyFilterText$]);

const {hasFocus$, directive: hasFocusDirective} = createHasFocus();
const open$ = bindableDerived(onOpenChange$, [_dirtyOpen$, hasFocus$], ([_dirtyOpen, hasFocus]) => _dirtyOpen && hasFocus);
// const open$ = bindableDerived(onOpenChange$, [_dirtyOpen$, hasFocus$], ([_dirtyOpen, hasFocus]) => _dirtyOpen && hasFocus);
const open$ = computed(() => _dirtyOpen$() && hasFocus$());

const selectedContextsMap$ = computed(() => {
const selectedItemsContext = new Map<string, ItemContext<Item>>();
Expand Down Expand Up @@ -448,7 +439,9 @@ export function createSelect<Item>(config?: PropsConfig<SelectProps<Item>>): Sel
patch,
api: {
clear() {
selected$.set([]);
const selected: Item[] = [];
selected$.set(selected);
onSelectedChange$()(selected);
},

select(item: Item) {
Expand Down Expand Up @@ -541,11 +534,14 @@ export function createSelect<Item>(config?: PropsConfig<SelectProps<Item>>): Sel
},
actions: {
onInput({target}: {target: HTMLInputElement}) {
const value = target.value;
const filterText = target.value;
const open = filterText != null && filterText !== '';
patch({
open: value != null && value !== '',
filterText: value,
open,
filterText,
});
onFilterTextChange$()(filterText);
onOpenChange$()(open);
},
onInputKeydown(e: KeyboardEvent) {
const {ctrlKey, key} = e;
Expand Down Expand Up @@ -582,6 +578,7 @@ export function createSelect<Item>(config?: PropsConfig<SelectProps<Item>>): Sel
}
case 'Escape':
_dirtyOpen$.set(false);
onOpenChange$()(false);
break;
default:
keyManaged = false;
Expand Down
54 changes: 27 additions & 27 deletions core/src/components/slider/slider.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {computed, derived, writable} from '@amadeus-it-group/tansu';
import type {WidgetsCommonPropsAndState} from '../commonProps';
import {bindableDerived, writablesForProps} from '../../utils/stores';
import {writablesForProps} from '../../utils/stores';
import {createStoreDirective, directiveSubscribe, mergeDirectives} from '../../utils/directive';
import {stateStores} from '../../utils/stores';
import {typeArray, typeBoolean, typeFunction, typeNumber, typeNumberInRangeFactory} from '../../utils/writables';
Expand Down Expand Up @@ -287,13 +287,33 @@ export function createSlider(config?: PropsConfig<SliderProps>): SliderWidget {
const _decimalPrecision$ = computed(() => Math.max(getDecimalPrecision(stepSize$()), getDecimalPrecision(min$()), getDecimalPrecision(max$())));
const _intStepSize$ = computed(() => stepSize$() * Math.pow(10, _decimalPrecision$()));

const values$ = bindableDerived(
/* 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,
); */

const values$ = computed(
() => {
const min = min$();
const max = max$();
const intStepSize = _intStepSize$();
const decimalPrecision = _decimalPrecision$();
return _dirtyValues$().map((dv) => computeCleanValue(dv, min, max, intStepSize, decimalPrecision));
},
{equal: typeArray.equal},
);
const changeValues = (values: number[]) => {
_dirtyValues$.set(values);
onValuesChange$()(values);
};
const updateValue = (valueIndex: number, value: number) => {
const newValues = [...values$()];
newValues[valueIndex] = value;
changeValues(newValues);
};

// computed
const {directive: sliderDirective, element$: sliderDom$} = createStoreDirective();
Expand Down Expand Up @@ -464,11 +484,7 @@ export function createSlider(config?: PropsConfig<SliderProps>): SliderWidget {
: (clickedCoordinate - sliderDomRectOffset) / sliderDomRectSize;
const derivedHandleIndex = handleNumber ?? getClosestSliderHandle(clickedPercent);
const newValue = clickedPercent * (max$() - min$()) + min$();
_dirtyValues$.update((dh) => {
dh = [...dh];
dh[derivedHandleIndex] = newValue;
return dh;
});
updateValue(derivedHandleIndex, newValue);
}
};

Expand Down Expand Up @@ -509,33 +525,17 @@ export function createSlider(config?: PropsConfig<SliderProps>): SliderWidget {
switch (key) {
case 'ArrowDown':
case 'ArrowLeft':
_dirtyValues$.update((value) => {
value = [...value];
value[handleIndex] = values$()[handleIndex] - stepSize$();
return value;
});
updateValue(handleIndex, values$()[handleIndex] - stepSize$());
break;
case 'ArrowUp':
case 'ArrowRight':
_dirtyValues$.update((value) => {
value = [...value];
value[handleIndex] = values$()[handleIndex] + stepSize$();
return value;
});
updateValue(handleIndex, values$()[handleIndex] + stepSize$());
break;
case 'Home':
_dirtyValues$.update((value) => {
value = [...value];
value[handleIndex] = min$();
return value;
});
updateValue(handleIndex, min$());
break;
case 'End':
_dirtyValues$.update((value) => {
value = [...value];
value[handleIndex] = max$();
return value;
});
updateValue(handleIndex, max$());
break;
case 'PageUp':
// TODO it is optional in accessibility guidelines, so define the skip value for steps and write unit test
Expand Down
6 changes: 4 additions & 2 deletions core/src/services/transitions/baseTransitions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import {typeBoolean, typeBooleanOrNull, typeFunction} from '../../utils/writable
import type {ConfigValidator, Directive, PropsConfig, Widget} from '../../types';
import {promiseWithResolve} from '../../utils/internal/promise';
import {noop} from '../../utils/internal/func';
import {bindableDerived, stateStores, writablesForProps} from '../../utils/stores';
import {stateStores, writablesForProps} from '../../utils/stores';
import {createStoreDirective, directiveSubscribe, directiveUpdate, mergeDirectives} from '../../utils/directive';

/**
Expand Down Expand Up @@ -196,7 +196,9 @@ export const createTransition = (config?: PropsConfig<TransitionProps>): Transit
writablesForProps(defaultValues, config, configValidator);
const {element$, directive: storeDirective} = createStoreDirective();
const elementPresent$ = computed(() => !!element$());
const visible$ = bindableDerived(onVisibleChange$, [requestedVisible$], ([visible]) => visible);
// const visible$ = bindableDerived(onVisibleChange$, [requestedVisible$], ([visible]) => visible);
// TODO: when should we call onVisibleChange$ ? or should we remove it ?
const visible$ = requestedVisible$;
const currentTransition$ = writable(
null as null | {
abort: AbortController;
Expand Down
Loading

0 comments on commit 255ad4f

Please sign in to comment.