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