diff --git a/CHANGELOG.md b/CHANGELOG.md index 0c80658ee..5a8b35e1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added number field ([387b002](https://github.com/dereekb/dbx-components/commit/387b002509a2409c707d098512540add06a7b86a)) +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/apps/demo-api/CHANGELOG.md b/apps/demo-api/CHANGELOG.md index 712c4c75f..8f0128e9b 100644 --- a/apps/demo-api/CHANGELOG.md +++ b/apps/demo-api/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/apps/demo-e2e/CHANGELOG.md b/apps/demo-e2e/CHANGELOG.md index 66aaa5b1b..0d4d2492a 100644 --- a/apps/demo-e2e/CHANGELOG.md +++ b/apps/demo-e2e/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/apps/demo/CHANGELOG.md b/apps/demo/CHANGELOG.md index 77767c018..f7ec7eebf 100644 --- a/apps/demo/CHANGELOG.md +++ b/apps/demo/CHANGELOG.md @@ -2,6 +2,16 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added number field ([387b002](https://github.com/dereekb/dbx-components/commit/387b002509a2409c707d098512540add06a7b86a)) +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/apps/demo/src/app/modules/doc/modules/form/container/value.component.html b/apps/demo/src/app/modules/doc/modules/form/container/value.component.html index 07aea6382..560756c71 100644 --- a/apps/demo/src/app/modules/doc/modules/form/container/value.component.html +++ b/apps/demo/src/app/modules/doc/modules/form/container/value.component.html @@ -5,6 +5,9 @@

There are also several helper builders available.

+ + + diff --git a/apps/demo/src/app/modules/doc/modules/form/container/value.component.ts b/apps/demo/src/app/modules/doc/modules/form/container/value.component.ts index 9aaa612ef..25ad8b026 100644 --- a/apps/demo/src/app/modules/doc/modules/form/container/value.component.ts +++ b/apps/demo/src/app/modules/doc/modules/form/container/value.component.ts @@ -1,14 +1,21 @@ import { FormlyFieldConfig } from '@ngx-formly/core'; import { Component } from '@angular/core'; -import { addressField, addressListField, cityField, countryField, emailField, phoneField, nameField, phoneAndLabelSectionField, wrappedPhoneAndLabelField, repeatArrayField, stateField, textAreaField, textField, zipCodeField, phoneListField, dateTimeField, DbxDateTimeFieldTimeMode, toggleField, checkboxField } from '@dereekb/dbx-form'; +import { addressField, addressListField, cityField, countryField, emailField, phoneField, nameField, phoneAndLabelSectionField, wrappedPhoneAndLabelField, repeatArrayField, stateField, textAreaField, textField, zipCodeField, phoneListField, dateTimeField, DbxDateTimeFieldTimeMode, toggleField, checkboxField, numberField } from '@dereekb/dbx-form'; @Component({ templateUrl: './value.component.html' }) export class DocFormValueComponent { - readonly textFields: FormlyFieldConfig[] = [textField({ key: 'test', label: 'Text Field', placeholder: 'Placeholder', required: true, minLength: 4, maxLength: 15 }), nameField(), emailField(), cityField(), stateField(), countryField(), zipCodeField()]; + readonly textFields: FormlyFieldConfig[] = [textField({ key: 'test', label: 'Text Field', description: 'A required text field.', placeholder: 'Placeholder', required: true, minLength: 4, maxLength: 15 }), nameField(), emailField(), cityField(), stateField(), countryField(), zipCodeField()]; - readonly textAreaField: FormlyFieldConfig[] = [textAreaField({ key: 'test', label: 'Text Area Field', placeholder: 'Placeholder', required: true })]; + readonly numberFields: FormlyFieldConfig[] = [ + // + numberField({ key: 'test', label: 'Number Field', description: 'A number between 0 and 100.', placeholder: 'Placeholder', min: 0, max: 100 }), + numberField({ key: 'steptest', label: 'Number Field With Step', description: 'Any number, but increases in steps of 5.', step: 5 }), + numberField({ key: 'enforcedsteptest', label: 'Number Divisible by 5', description: 'Any number divisible by 5.', step: 5, enforceStep: true }) + ]; + + readonly textAreaField: FormlyFieldConfig[] = [textAreaField({ key: 'test', label: 'Text Area Field', description: 'A required text area field.', placeholder: 'Placeholder', required: true })]; readonly dateTimeFields: FormlyFieldConfig[] = [ dateTimeField({ key: 'date', required: true, description: 'This is the default date field that requires the user pick a date and time.' }), diff --git a/apps/demo/src/app/modules/doc/modules/layout/component/item.list.grid.component.ts b/apps/demo/src/app/modules/doc/modules/layout/component/item.list.grid.component.ts index 5709b12b1..8dfe04b7f 100644 --- a/apps/demo/src/app/modules/doc/modules/layout/component/item.list.grid.component.ts +++ b/apps/demo/src/app/modules/doc/modules/layout/component/item.list.grid.component.ts @@ -1,6 +1,6 @@ import { LOREM } from '../../shared/lorem'; import { Component } from '@angular/core'; -import { AbstractDbxListGridViewDirective, DEFAULT_DBX_VALUE_LIST_GRID_DIRECTIVE_TEMPLATE, AbstractDbxSelectionListWrapperDirective, AbstractDbxValueListViewItemComponent, AbstractDbxSelectionListViewDirective, DEFAULT_LIST_WRAPPER_DIRECTIVE_TEMPLATE, DbxSelectionValueListViewConfig, provideDbxListView, DEFAULT_DBX_SELECTION_VALUE_LIST_DIRECTIVE_TEMPLATE, AbstractDbxListWrapperDirective, DbxValueListGridViewConfig } from '@dereekb/dbx-web'; +import { AbstractDbxListGridViewDirective, DEFAULT_DBX_VALUE_LIST_GRID_DIRECTIVE_TEMPLATE, AbstractDbxValueListViewItemComponent, DEFAULT_LIST_WRAPPER_DIRECTIVE_TEMPLATE, provideDbxListView, AbstractDbxListWrapperDirective, DbxValueListGridViewConfig } from '@dereekb/dbx-web'; import { of } from 'rxjs'; import { DocValue, DocValueWithSelection } from './item.list'; diff --git a/components/demo-components/CHANGELOG.md b/components/demo-components/CHANGELOG.md index b0c38eccc..e5e42cf4a 100644 --- a/components/demo-components/CHANGELOG.md +++ b/components/demo-components/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/components/demo-components/package.json b/components/demo-components/package.json index 4e8b55b20..47eb594ae 100644 --- a/components/demo-components/package.json +++ b/components/demo-components/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/demo-components", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.3.0", "@angular/core": "^13.3.0" diff --git a/components/demo-firebase/CHANGELOG.md b/components/demo-firebase/CHANGELOG.md index 48a1cfe18..fd9a5759f 100644 --- a/components/demo-firebase/CHANGELOG.md +++ b/components/demo-firebase/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/components/demo-firebase/package.json b/components/demo-firebase/package.json index 5f4259410..1d6943d42 100644 --- a/components/demo-firebase/package.json +++ b/components/demo-firebase/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/demo-firebase", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/package.json b/package.json index e7cff0854..f0043e2bf 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-components", - "version": "8.6.1", + "version": "8.7.0", "license": "MIT", "scripts": { "postinstall": "ngcc --properties es2015 browser module main", diff --git a/packages/browser/CHANGELOG.md b/packages/browser/CHANGELOG.md index 06dd0bd2b..a37ba806a 100644 --- a/packages/browser/CHANGELOG.md +++ b/packages/browser/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/browser/package.json b/packages/browser/package.json index 4280272a4..adbb0fbf4 100644 --- a/packages/browser/package.json +++ b/packages/browser/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/browser", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/packages/date/CHANGELOG.md b/packages/date/CHANGELOG.md index ef4d6e97a..ef955df6f 100644 --- a/packages/date/CHANGELOG.md +++ b/packages/date/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/date/package.json b/packages/date/package.json index fd4bca112..5cb132019 100644 --- a/packages/date/package.json +++ b/packages/date/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/date", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/packages/dbx-analytics/CHANGELOG.md b/packages/dbx-analytics/CHANGELOG.md index 9cd18d82f..e37559544 100644 --- a/packages/dbx-analytics/CHANGELOG.md +++ b/packages/dbx-analytics/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/dbx-analytics/package.json b/packages/dbx-analytics/package.json index 415132658..881f41ad8 100644 --- a/packages/dbx-analytics/package.json +++ b/packages/dbx-analytics/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-analytics", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.1.0", "@angular/core": "^13.1.0" diff --git a/packages/dbx-core/CHANGELOG.md b/packages/dbx-core/CHANGELOG.md index 596630397..ec4beca19 100644 --- a/packages/dbx-core/CHANGELOG.md +++ b/packages/dbx-core/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/dbx-core/package.json b/packages/dbx-core/package.json index 00458ceaf..d703a5733 100644 --- a/packages/dbx-core/package.json +++ b/packages/dbx-core/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-core", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.0.0", "@angular/core": "^13.0.0" diff --git a/packages/dbx-firebase/CHANGELOG.md b/packages/dbx-firebase/CHANGELOG.md index cf5b66feb..6c4c01bf9 100644 --- a/packages/dbx-firebase/CHANGELOG.md +++ b/packages/dbx-firebase/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/dbx-firebase/package.json b/packages/dbx-firebase/package.json index b2b40feff..955d7ab49 100644 --- a/packages/dbx-firebase/package.json +++ b/packages/dbx-firebase/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-firebase", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.0.0", "@angular/core": "^13.0.0" diff --git a/packages/dbx-firebase/src/lib/model/store/store.document.ts b/packages/dbx-firebase/src/lib/model/store/store.document.ts index 13b7441e1..220a5f13e 100644 --- a/packages/dbx-firebase/src/lib/model/store/store.document.ts +++ b/packages/dbx-firebase/src/lib/model/store/store.document.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { Observable, shareReplay, distinctUntilChanged, map, switchMap, combineLatest, Subscription, of } from 'rxjs'; -import { DocumentSnapshot, DocumentReference, FirestoreCollection, FirestoreDocument, documentDataWithId, DocumentDataWithId, FirestoreModelId, FirestoreModelKey, FirestoreCollectionLike, FirestoreModelIdentity, firestoreModelIdsFromKey, firestoreModelKeyPartPairs, FirestoreModelCollectionAndIdPair, firestoreModelKeyPairObject, FirestoreModelKeyPairObject } from '@dereekb/firebase'; +import { DocumentSnapshot, DocumentReference, FirestoreCollection, FirestoreDocument, documentDataWithId, DocumentDataWithId, FirestoreModelId, FirestoreModelKey, FirestoreCollectionLike, FirestoreModelIdentity, firestoreModelIdsFromKey, firestoreModelKeyPartPairs, FirestoreModelCollectionAndIdPair, firestoreModelKeyPairObject, FirestoreModelCollectionAndIdPairObject } from '@dereekb/firebase'; import { filterMaybe, LoadingState, beginLoading, successResult, loadingStateFromObs, errorResult, ObservableOrValue } from '@dereekb/rxjs'; import { Maybe, isMaybeSo } from '@dereekb/util'; import { LockSetComponent, LockSetComponentStore } from '@dereekb/dbx-core'; @@ -25,7 +25,7 @@ export interface DbxFirebaseDocumentStore = Fi readonly keyModelIds$: Observable; readonly keyPairs$: Observable; - readonly keyPairObject$: Observable; + readonly keyPairObject$: Observable; readonly documentLoadingState$: Observable>; readonly snapshot$: Observable>; @@ -150,7 +150,7 @@ export class AbstractDbxFirebaseDocumentStore readonly keyModelIds$: Observable = this.key$.pipe(map(firestoreModelIdsFromKey), shareReplay(1)); readonly keyPairs$: Observable = this.key$.pipe(map(firestoreModelKeyPartPairs), filterMaybe(), shareReplay(1)); - readonly keyPairObject$: Observable = this.key$.pipe(map(firestoreModelKeyPairObject), filterMaybe(), shareReplay(1)); + readonly keyPairObject$: Observable = this.key$.pipe(map(firestoreModelKeyPairObject), filterMaybe(), shareReplay(1)); readonly ref$: Observable> = this.document$.pipe( map((x) => x.documentRef), diff --git a/packages/dbx-form/CHANGELOG.md b/packages/dbx-form/CHANGELOG.md index 0ab049348..af204aedd 100644 --- a/packages/dbx-form/CHANGELOG.md +++ b/packages/dbx-form/CHANGELOG.md @@ -2,6 +2,16 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added number field ([387b002](https://github.com/dereekb/dbx-components/commit/387b002509a2409c707d098512540add06a7b86a)) +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/dbx-form/package.json b/packages/dbx-form/package.json index 0292eae80..cded3646a 100644 --- a/packages/dbx-form/package.json +++ b/packages/dbx-form/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-form", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.0.0", "@angular/core": "^13.0.0" diff --git a/packages/dbx-form/src/lib/formly/field/field.ts b/packages/dbx-form/src/lib/formly/field/field.ts index ef2be86c3..c35d071ae 100644 --- a/packages/dbx-form/src/lib/formly/field/field.ts +++ b/packages/dbx-form/src/lib/formly/field/field.ts @@ -1,5 +1,7 @@ -import { mergeObjects, filterFromPOJO, mergeObjectsFunction, filterFromPOJOFunction, FilterKeyValueTuplesInput, GeneralFilterFromPOJOFunction } from '@dereekb/util'; +import { AsyncValidatorFn, ValidatorFn } from '@angular/forms'; +import { mergeObjects, filterFromPOJO, mergeObjectsFunction, filterFromPOJOFunction, FilterKeyValueTuplesInput, GeneralFilterFromPOJOFunction, ArrayOrValue, Maybe, asArray, objectHasNoKeys } from '@dereekb/util'; import { FormlyFieldConfig, FormlyFieldProps } from '@ngx-formly/core'; +import { ValidationMessageOption } from '@ngx-formly/core/lib/models'; export interface FieldConfig { key: string; @@ -111,3 +113,56 @@ export function disableFormlyFieldAutofillAttributes(): { name: string; autocomp autocomplete: 'off' }; } + +export type FormlyMessageProperties = { + [messageProperties: string]: ValidationMessageOption['message']; +}; + +export interface ValidatorsForFieldConfigInput { + validators?: ArrayOrValue; + asyncValidators?: ArrayOrValue; + messages?: Maybe; +} + +export type ValidatorsForFieldConfig = { + validation?: { + messages?: FormlyMessageProperties; + }; + validators?: { + validation: ValidatorFn[]; + }; + asyncValidators?: { + validation: AsyncValidatorFn[]; + }; +}; + +export function validatorsForFieldConfig(input: ValidatorsForFieldConfigInput): Maybe { + const validators: ValidatorFn[] = asArray(input.validators); + const asyncValidators: AsyncValidatorFn[] = asArray(input.asyncValidators); + const messages: Maybe = input.messages; + let config: Maybe; + + if (messages || validators.length || asyncValidators.length) { + config = {}; + + if (validators.length) { + config.validators = { + validation: validators + }; + } + + if (asyncValidators.length) { + config.validators = { + validation: asyncValidators + }; + } + + if (messages && !objectHasNoKeys(messages)) { + config.validation = { + messages + }; + } + } + + return config; +} diff --git a/packages/dbx-form/src/lib/formly/field/value/hidden.field.ts b/packages/dbx-form/src/lib/formly/field/value/hidden.field.ts index 828fd0527..b982b3cc3 100644 --- a/packages/dbx-form/src/lib/formly/field/value/hidden.field.ts +++ b/packages/dbx-form/src/lib/formly/field/value/hidden.field.ts @@ -1,4 +1,4 @@ -import { FormlyFieldConfig } from '@ngx-formly/core/lib/core'; +import { FormlyFieldConfig } from '@ngx-formly/core'; import { LabeledFieldConfig, formlyField } from '../field'; export type HiddenFieldConfig = Pick; diff --git a/packages/dbx-form/src/lib/formly/field/value/index.ts b/packages/dbx-form/src/lib/formly/field/value/index.ts index 33c966659..7fec7b566 100644 --- a/packages/dbx-form/src/lib/formly/field/value/index.ts +++ b/packages/dbx-form/src/lib/formly/field/value/index.ts @@ -1,6 +1,7 @@ export * from './array'; export * from './boolean'; export * from './date'; +export * from './number'; export * from './enum'; export * from './phone'; export * from './text'; diff --git a/packages/dbx-form/src/lib/formly/field/value/number/index.ts b/packages/dbx-form/src/lib/formly/field/value/number/index.ts new file mode 100644 index 000000000..d094485ba --- /dev/null +++ b/packages/dbx-form/src/lib/formly/field/value/number/index.ts @@ -0,0 +1,2 @@ +export * from './number.field'; +export * from './number.field.module'; diff --git a/packages/dbx-form/src/lib/formly/field/value/number/number.field.module.ts b/packages/dbx-form/src/lib/formly/field/value/number/number.field.module.ts new file mode 100644 index 000000000..f0daaa529 --- /dev/null +++ b/packages/dbx-form/src/lib/formly/field/value/number/number.field.module.ts @@ -0,0 +1,10 @@ +import { FormlyMaterialModule } from '@ngx-formly/material'; +import { NgModule } from '@angular/core'; +import { DbxFormFormlyWrapperModule } from '../../wrapper/form.wrapper.module'; + +@NgModule({ + imports: [FormlyMaterialModule], + declarations: [], + exports: [DbxFormFormlyWrapperModule] +}) +export class DbxFormFormlyNumberFieldModule {} diff --git a/packages/dbx-form/src/lib/formly/field/value/number/number.field.ts b/packages/dbx-form/src/lib/formly/field/value/number/number.field.ts new file mode 100644 index 000000000..285e215e6 --- /dev/null +++ b/packages/dbx-form/src/lib/formly/field/value/number/number.field.ts @@ -0,0 +1,41 @@ +import { ValidatorFn } from '@angular/forms'; +import { FormlyFieldConfig } from '@ngx-formly/core'; +import { isDivisibleBy } from '../../../../validator'; +import { AttributesFieldConfig, LabeledFieldConfig, formlyField, propsForFieldConfig, DescriptionFieldConfig, validatorsForFieldConfig } from '../../field'; + +export interface NumberFieldNumberConfig { + min?: number; + max?: number; + step?: number; + enforceStep?: boolean; +} + +export type NumberFieldInputType = 'number'; + +export interface NumberFieldConfig extends LabeledFieldConfig, DescriptionFieldConfig, NumberFieldNumberConfig, AttributesFieldConfig { + inputType?: NumberFieldInputType; +} + +export function numberField(config: NumberFieldConfig): FormlyFieldConfig { + const { key, min, max, step, enforceStep, inputType: type = 'number' } = config; + + const validators: ValidatorFn[] = []; + + if (step && enforceStep) { + validators.push(isDivisibleBy(step)); + } + + return formlyField({ + key, + type: 'input', + ...propsForFieldConfig(config, { + type, + min, + max, + step + }), + ...validatorsForFieldConfig({ + validators + }) + }); +} diff --git a/packages/dbx-form/src/lib/formly/field/value/text/text.field.ts b/packages/dbx-form/src/lib/formly/field/value/text/text.field.ts index 4fdcd5d69..d69437e5c 100644 --- a/packages/dbx-form/src/lib/formly/field/value/text/text.field.ts +++ b/packages/dbx-form/src/lib/formly/field/value/text/text.field.ts @@ -1,5 +1,5 @@ -import { FormlyFieldConfig } from '@ngx-formly/core/lib/core'; -import { AttributesFieldConfig, LabeledFieldConfig, formlyField, propsForFieldConfig } from '../../field'; +import { FormlyFieldConfig } from '@ngx-formly/core'; +import { AttributesFieldConfig, LabeledFieldConfig, formlyField, propsForFieldConfig, DescriptionFieldConfig } from '../../field'; export interface TextFieldLengthConfig { minLength?: number; @@ -8,7 +8,7 @@ export interface TextFieldLengthConfig { export type TextFieldInputType = 'text' | 'password' | 'email'; -export interface TextFieldConfig extends LabeledFieldConfig, TextFieldLengthConfig, AttributesFieldConfig { +export interface TextFieldConfig extends LabeledFieldConfig, DescriptionFieldConfig, TextFieldLengthConfig, AttributesFieldConfig { inputType?: TextFieldInputType; pattern?: string | RegExp; } @@ -27,7 +27,7 @@ export function textField(config: TextFieldConfig): FormlyFieldConfig { }); } -export interface TextAreaFieldConfig extends LabeledFieldConfig, TextFieldLengthConfig, AttributesFieldConfig { +export interface TextAreaFieldConfig extends LabeledFieldConfig, DescriptionFieldConfig, TextFieldLengthConfig, AttributesFieldConfig { rows?: number; } diff --git a/packages/dbx-form/src/lib/formly/field/value/value.module.ts b/packages/dbx-form/src/lib/formly/field/value/value.module.ts index 482c7a624..e726cea26 100644 --- a/packages/dbx-form/src/lib/formly/field/value/value.module.ts +++ b/packages/dbx-form/src/lib/formly/field/value/value.module.ts @@ -6,10 +6,11 @@ import { DbxFormFormlyEnumFieldModule } from './enum/enum.field.module'; import { DbxFormFormlyPhoneFieldModule } from './phone/phone.field.module'; import { DbxFormFormlyDateFieldModule } from './date/date.field.module'; import { DbxFormFormlyTextFieldModule } from './text/text.field.module'; +import { DbxFormFormlyNumberFieldModule } from './number/number.field.module'; @NgModule({ imports: [CommonModule], declarations: [], - exports: [DbxFormFormlyArrayFieldModule, DbxFormFormlyBooleanFieldModule, DbxFormFormlyDateFieldModule, DbxFormFormlyEnumFieldModule, DbxFormFormlyPhoneFieldModule, DbxFormFormlyTextFieldModule] + exports: [DbxFormFormlyArrayFieldModule, DbxFormFormlyBooleanFieldModule, DbxFormFormlyDateFieldModule, DbxFormFormlyEnumFieldModule, DbxFormFormlyPhoneFieldModule, DbxFormFormlyNumberFieldModule, DbxFormFormlyTextFieldModule] }) export class DbxFormFormlyValueModule {} diff --git a/packages/dbx-form/src/lib/formly/formly.directive.ts b/packages/dbx-form/src/lib/formly/formly.directive.ts index 40c540aff..fd16967d8 100644 --- a/packages/dbx-form/src/lib/formly/formly.directive.ts +++ b/packages/dbx-form/src/lib/formly/formly.directive.ts @@ -1,6 +1,6 @@ import { SubscriptionObject, filterMaybe } from '@dereekb/rxjs'; import { Observable, BehaviorSubject, shareReplay, distinctUntilChanged } from 'rxjs'; -import { FormlyFieldConfig } from '@ngx-formly/core/lib/core'; +import { FormlyFieldConfig } from '@ngx-formly/core'; import { OnInit, OnDestroy, Directive, Input } from '@angular/core'; import { DbxFormlyContext } from './formly.context'; import { Maybe } from '@dereekb/util'; diff --git a/packages/dbx-form/src/lib/formly/template/available.ts b/packages/dbx-form/src/lib/formly/template/available.ts index 7e8894a16..3b5d9061f 100644 --- a/packages/dbx-form/src/lib/formly/template/available.ts +++ b/packages/dbx-form/src/lib/formly/template/available.ts @@ -1,4 +1,4 @@ -import { FormlyFieldConfig } from '@ngx-formly/core/lib/core'; +import { FormlyFieldConfig } from '@ngx-formly/core'; import { FieldValueIsAvailableValidatorConfig, fieldValueIsAvailableValidator } from '../../validator/available'; import { textField, TextFieldConfig } from '../field/value/text/text.field'; import { workingWrapper } from '../field/wrapper/wrapper'; diff --git a/packages/dbx-form/src/lib/validator/number.ts b/packages/dbx-form/src/lib/validator/number.ts index 1bd1291f8..c31fd1db9 100644 --- a/packages/dbx-form/src/lib/validator/number.ts +++ b/packages/dbx-form/src/lib/validator/number.ts @@ -1,4 +1,5 @@ import { AbstractControl, ValidationErrors, ValidatorFn, Validators } from '@angular/forms'; +import { isNumberDivisibleBy, nearestDivisibleValues } from '@dereekb/util'; /** * Merges the use of the min and max validator. @@ -27,3 +28,36 @@ export function isInRange(min: number = Number.MIN_SAFE_INTEGER, max: number = N return errors; }; } + +export const IS_DIVISIBLE_BY_VALIDATION_KEY = 'isDivisibleBy'; + +export interface IsDivisibleByError { + value: number; + nearest: number; + divisor: number; + message: string; +} + +export function isDivisibleBy(divisor: number): ValidatorFn { + if (divisor === 0) { + throw new Error('Divisior must be greater than zero.'); + } + + return (control: AbstractControl): ValidationErrors | null => { + const value: number | undefined = control.value; + + if (value != null && !isNumberDivisibleBy(value, divisor)) { + const nearest = nearestDivisibleValues(value, divisor); + return { + [IS_DIVISIBLE_BY_VALIDATION_KEY]: { + value, + divisor, + nearest, + message: `Number must by divisible by ${divisor}. The two nearest valid values are ${nearest.nearestFloor} and ${nearest.nearestCeil}.` + } + }; + } + + return {}; + }; +} diff --git a/packages/dbx-web/CHANGELOG.md b/packages/dbx-web/CHANGELOG.md index 935cb4baf..14bb8a983 100644 --- a/packages/dbx-web/CHANGELOG.md +++ b/packages/dbx-web/CHANGELOG.md @@ -2,6 +2,15 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/dbx-web/package.json b/packages/dbx-web/package.json index 5c1b116be..5b5c767aa 100644 --- a/packages/dbx-web/package.json +++ b/packages/dbx-web/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/dbx-web", - "version": "8.6.1", + "version": "8.7.0", "peerDependencies": { "@angular/common": "^13.0.0", "@angular/core": "^13.0.0" diff --git a/packages/dbx-web/src/lib/layout/list/list.grid.view.component.ts b/packages/dbx-web/src/lib/layout/list/list.grid.view.component.ts index 278211478..6ae01f116 100644 --- a/packages/dbx-web/src/lib/layout/list/list.grid.view.component.ts +++ b/packages/dbx-web/src/lib/layout/list/list.grid.view.component.ts @@ -1,9 +1,7 @@ import { Component, Input } from '@angular/core'; import { shareReplay, map } from 'rxjs'; -import { DbxValueListItem, AbstractDbxValueListViewConfig, DbxValueListItemConfig } from './list.view.value'; +import { DbxValueListItem } from './list.view.value'; import { AbstractDbxValueListViewDirective } from './list.view.value.directive'; -import { AnchorType, anchorTypeForAnchor } from '@dereekb/dbx-core'; -import { DbxListView } from './list.view'; import { Maybe, mergeObjects } from '@dereekb/util'; import { DbxValueListItemViewComponent, DbxValueListViewConfig } from './list.view.value.component'; diff --git a/packages/dbx-web/src/lib/layout/list/list.grid.view.directive.ts b/packages/dbx-web/src/lib/layout/list/list.grid.view.directive.ts index 12c8c7da1..ff7b6ec2b 100644 --- a/packages/dbx-web/src/lib/layout/list/list.grid.view.directive.ts +++ b/packages/dbx-web/src/lib/layout/list/list.grid.view.directive.ts @@ -1,8 +1,4 @@ -import { ListLoadingStateContext, switchMapMaybeObs } from '@dereekb/rxjs'; -import { BehaviorSubject, Observable, of, shareReplay } from 'rxjs'; -import { Directive, EventEmitter, Input, OnDestroy, Output } from '@angular/core'; -import { DbxListSelectionMode, DbxListView } from './list.view'; -import { Maybe } from '@dereekb/util'; +import { Directive } from '@angular/core'; import { AbstractDbxListViewDirective } from './list.view.directive'; export const DEFAULT_DBX_VALUE_LIST_GRID_DIRECTIVE_TEMPLATE = ''; diff --git a/packages/firebase-server/CHANGELOG.md b/packages/firebase-server/CHANGELOG.md index cc53744ae..0d8dfcca1 100644 --- a/packages/firebase-server/CHANGELOG.md +++ b/packages/firebase-server/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/firebase-server/package.json b/packages/firebase-server/package.json index 595e5f707..d667d947c 100644 --- a/packages/firebase-server/package.json +++ b/packages/firebase-server/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/firebase-server", - "version": "8.6.1", + "version": "8.7.0", "devDependencies": { "firebase-functions-test": "2.0.2" }, diff --git a/packages/firebase-server/test/CHANGELOG.md b/packages/firebase-server/test/CHANGELOG.md index 3e6fc675f..cef303b52 100644 --- a/packages/firebase-server/test/CHANGELOG.md +++ b/packages/firebase-server/test/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/firebase-server/test/package.json b/packages/firebase-server/test/package.json index 5cf18cbc1..0a5f6454e 100644 --- a/packages/firebase-server/test/package.json +++ b/packages/firebase-server/test/package.json @@ -1,4 +1,4 @@ { "name": "@dereekb/firebase-server/test", - "version": "8.6.1" + "version": "8.7.0" } \ No newline at end of file diff --git a/packages/firebase/CHANGELOG.md b/packages/firebase/CHANGELOG.md index 87e5f0375..346c98bc6 100644 --- a/packages/firebase/CHANGELOG.md +++ b/packages/firebase/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/firebase/package.json b/packages/firebase/package.json index d9e6331e1..c3619bae4 100644 --- a/packages/firebase/package.json +++ b/packages/firebase/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/firebase", - "version": "8.6.1", + "version": "8.7.0", "devDependencies": { "@firebase/rules-unit-testing": "^2.0.0" }, diff --git a/packages/firebase/src/lib/common/firestore/collection/collection.ts b/packages/firebase/src/lib/common/firestore/collection/collection.ts index 340f2011a..5ecd865ce 100644 --- a/packages/firebase/src/lib/common/firestore/collection/collection.ts +++ b/packages/firebase/src/lib/common/firestore/collection/collection.ts @@ -343,11 +343,11 @@ export function childFirestoreModelKeyPath(parent: FirestoreModelKeyPart, childr } } -export type FirestoreModelKeyPairObject = Record; +export type FirestoreModelCollectionAndIdPairObject = Record; -export function firestoreModelKeyPairObject(input: FirestoreModelKey | DocumentReferenceRef | FirestoreModelKeyRef): Maybe { +export function firestoreModelKeyPairObject(input: FirestoreModelKey | DocumentReferenceRef | FirestoreModelKeyRef): Maybe { const pairs = firestoreModelKeyPartPairs(input); - let object: Maybe; + let object: Maybe; if (pairs) { object = arrayToObject( @@ -362,8 +362,8 @@ export function firestoreModelKeyPairObject(input: FirestoreModelKey | DocumentR export interface FirestoreModelCollectionAndIdPair extends FirestoreModelIdRef, FirestoreCollectionNameRef {} -export function firestoreModelKeyPartPairs(input: FirestoreModelKey | DocumentReferenceRef | FirestoreModelKeyRef): Maybe { - const key = readFirestoreModelKey(input); +export function firestoreModelKeyPartPairs(input: ReadFirestoreModelKeyInput): Maybe { + const key = readFirestoreModelKey(input); let pairs: Maybe; if (key) { @@ -384,7 +384,9 @@ export function firestoreModelKeyPartPairs(input: FirestoreModelKey | DocumentRe return pairs; } -export function readFirestoreModelKey(input: FirestoreModelKey | DocumentReferenceRef | FirestoreModelKeyRef): Maybe { +export type ReadFirestoreModelKeyInput = FirestoreModelKey | FirestoreModelKeyRef | DocumentReferenceRef; + +export function readFirestoreModelKey(input: ReadFirestoreModelKeyInput): Maybe { let key: Maybe; if (typeof input === 'object') { diff --git a/packages/firebase/test/CHANGELOG.md b/packages/firebase/test/CHANGELOG.md index 5e53fb247..ac390c937 100644 --- a/packages/firebase/test/CHANGELOG.md +++ b/packages/firebase/test/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/firebase/test/package.json b/packages/firebase/test/package.json index 37ce54371..68257e011 100644 --- a/packages/firebase/test/package.json +++ b/packages/firebase/test/package.json @@ -1,4 +1,4 @@ { "name": "@dereekb/firebase/test", - "version": "8.6.1" + "version": "8.7.0" } \ No newline at end of file diff --git a/packages/model/CHANGELOG.md b/packages/model/CHANGELOG.md index 7cca64d95..aa7851f44 100644 --- a/packages/model/CHANGELOG.md +++ b/packages/model/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/model/package.json b/packages/model/package.json index 8458937fd..dae4e7695 100644 --- a/packages/model/package.json +++ b/packages/model/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/model", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/packages/nestjs/CHANGELOG.md b/packages/nestjs/CHANGELOG.md index ad39d009a..86557c7c4 100644 --- a/packages/nestjs/CHANGELOG.md +++ b/packages/nestjs/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/nestjs/package.json b/packages/nestjs/package.json index fbd3d3170..5b99655d3 100644 --- a/packages/nestjs/package.json +++ b/packages/nestjs/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/nestjs", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs", "exports": { ".": { diff --git a/packages/nestjs/stripe/CHANGELOG.md b/packages/nestjs/stripe/CHANGELOG.md index 45db65658..81d72cd95 100644 --- a/packages/nestjs/stripe/CHANGELOG.md +++ b/packages/nestjs/stripe/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/nestjs/stripe/package.json b/packages/nestjs/stripe/package.json index 677080335..92218ee90 100644 --- a/packages/nestjs/stripe/package.json +++ b/packages/nestjs/stripe/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/nestjs/stripe", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/packages/rxjs/CHANGELOG.md b/packages/rxjs/CHANGELOG.md index d3b80d9a0..44001daef 100644 --- a/packages/rxjs/CHANGELOG.md +++ b/packages/rxjs/CHANGELOG.md @@ -2,6 +2,15 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/rxjs/package.json b/packages/rxjs/package.json index f5b7bf7c1..5a9ecf37e 100644 --- a/packages/rxjs/package.json +++ b/packages/rxjs/package.json @@ -1,5 +1,5 @@ { "name": "@dereekb/rxjs", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs" } \ No newline at end of file diff --git a/packages/rxjs/src/lib/rxjs/rxjs.async.ts b/packages/rxjs/src/lib/rxjs/rxjs.async.ts index 83014c0bd..f6402bda1 100644 --- a/packages/rxjs/src/lib/rxjs/rxjs.async.ts +++ b/packages/rxjs/src/lib/rxjs/rxjs.async.ts @@ -99,6 +99,11 @@ export function asyncPusher(config: AsyncPusherConfig = {}): AsyncPusher = CachedFactoryWithInput, Observable>; + /** * Creates a cache that returns an AsyncPusher. * @@ -107,7 +112,7 @@ export function asyncPusher(config: AsyncPusherConfig = {}): AsyncPusher(config?: AsyncPusherConfig): CachedFactoryWithInput, Observable> { +export function asyncPusherCache(config?: AsyncPusherConfig): AsyncPusherCache { return cachedGetter((cleanupObs?: Observable) => { const pusher = asyncPusher(config); diff --git a/packages/util/CHANGELOG.md b/packages/util/CHANGELOG.md index a83a2abd6..9e69461a3 100644 --- a/packages/util/CHANGELOG.md +++ b/packages/util/CHANGELOG.md @@ -2,6 +2,15 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + +### Features + +* added step, enforceStep to numberField ([a57b1c7](https://github.com/dereekb/dbx-components/commit/a57b1c7f9f0194874e4dcadafabf01ee49d44c48)) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/util/package.json b/packages/util/package.json index e5d07a835..239dbcaf3 100644 --- a/packages/util/package.json +++ b/packages/util/package.json @@ -1,6 +1,6 @@ { "name": "@dereekb/util", - "version": "8.6.1", + "version": "8.7.0", "type": "commonjs", "exports": { ".": { diff --git a/packages/util/src/lib/number/index.ts b/packages/util/src/lib/number/index.ts index b4b919e15..f98b90201 100644 --- a/packages/util/src/lib/number/index.ts +++ b/packages/util/src/lib/number/index.ts @@ -1,3 +1,4 @@ export * from './factory'; export * from './random'; export * from './round'; +export * from './number'; diff --git a/packages/util/src/lib/number/number.spec.ts b/packages/util/src/lib/number/number.spec.ts new file mode 100644 index 000000000..1283ee9fd --- /dev/null +++ b/packages/util/src/lib/number/number.spec.ts @@ -0,0 +1,12 @@ +import { nearestDivisibleValues } from './number'; + +describe('nearestDivisibleValues', () => { + it('should return the nearest divisible values to 3', () => { + const result = nearestDivisibleValues(1, 3); + + expect(result.value).toBe(1); + expect(result.divisor).toBe(3); + expect(result.nearestFloor).toBe(0); + expect(result.nearestCeil).toBe(3); + }); +}); diff --git a/packages/util/src/lib/number/number.ts b/packages/util/src/lib/number/number.ts new file mode 100644 index 000000000..0afac71ad --- /dev/null +++ b/packages/util/src/lib/number/number.ts @@ -0,0 +1,40 @@ +import { Maybe } from '../value/maybe.type'; + +/** + * Returns true if the input value is divisible by the divisor. + * + * @param value + * @param divisor + * @returns + */ +export function isNumberDivisibleBy(value: Maybe, divisor: number): boolean { + const remainder = (value ?? 0) % divisor; + return remainder === 0; +} + +export interface NearestDivisibleValues { + value: number; + divisor: number; + nearestCeil: number; + nearestFloor: number; +} + +/** + * Returns true if the input value is divisible by the divisor. + * + * @param value + * @param divisor + * @returns + */ +export function nearestDivisibleValues(value: number, divisor: number): NearestDivisibleValues { + const point = value / divisor; + const ceilPoint = Math.ceil(point); + const floorPoint = Math.floor(point); + + return { + value, + divisor, + nearestCeil: ceilPoint * divisor, + nearestFloor: floorPoint * divisor + }; +} diff --git a/packages/util/test/CHANGELOG.md b/packages/util/test/CHANGELOG.md index 715afbd73..c75d61ffa 100644 --- a/packages/util/test/CHANGELOG.md +++ b/packages/util/test/CHANGELOG.md @@ -2,6 +2,10 @@ This file was generated using [@jscutlery/semver](https://github.com/jscutlery/semver). +# [8.7.0](https://github.com/dereekb/dbx-components/compare/v8.6.1-dev...v8.7.0) (2022-06-23) + + + ## [8.6.1](https://github.com/dereekb/dbx-components/compare/v8.6.0-dev...v8.6.1) (2022-06-23) diff --git a/packages/util/test/package.json b/packages/util/test/package.json index f8d87b280..d4f6cb089 100644 --- a/packages/util/test/package.json +++ b/packages/util/test/package.json @@ -1,4 +1,4 @@ { "name": "@dereekb/util/test", - "version": "8.6.1" + "version": "8.7.0" } \ No newline at end of file