{"id":50893876,"url":"https://github.com/deciosfernandes/ng-date-hour-range-selector","last_synced_at":"2026-06-18T02:01:01.780Z","repository":{"id":341686930,"uuid":"1171055349","full_name":"deciosfernandes/ng-date-hour-range-selector","owner":"deciosfernandes","description":"A repository for a date/datetime range selector for modern Angular","archived":false,"fork":false,"pushed_at":"2026-05-22T17:49:44.000Z","size":483,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-16T16:06:38.929Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/deciosfernandes.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-02T20:32:14.000Z","updated_at":"2026-06-02T16:40:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/deciosfernandes/ng-date-hour-range-selector","commit_stats":null,"previous_names":["deciosfernandes/ng-date-hour-range-selector"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/deciosfernandes/ng-date-hour-range-selector","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deciosfernandes%2Fng-date-hour-range-selector","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deciosfernandes%2Fng-date-hour-range-selector/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deciosfernandes%2Fng-date-hour-range-selector/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deciosfernandes%2Fng-date-hour-range-selector/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/deciosfernandes","download_url":"https://codeload.github.com/deciosfernandes/ng-date-hour-range-selector/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/deciosfernandes%2Fng-date-hour-range-selector/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34472826,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-06-15T23:00:25.067Z","updated_at":"2026-06-18T02:01:01.774Z","avatar_url":"https://github.com/deciosfernandes.png","language":"TypeScript","funding_links":[],"categories":["Third Party Components"],"sub_categories":["Dates"],"readme":"# ng-date-hour-range-selector\n\n[![Live Demo](https://img.shields.io/badge/demo-live-orange?style=flat-square)](https://deciosfernandes.github.io/ng-date-hour-range-selector/)\n[![npm](https://img.shields.io/npm/v/ng-date-hour-range-selector?style=flat-square)](https://www.npmjs.com/package/ng-date-hour-range-selector)\n\nA flexible Angular **date / date-time range selector** built on Angular CDK Overlay. Supports predefined range shortcuts, time picking, localization, and full CSS customization — with zero third-party date-library dependency.\n\n**[→ Live Demo](https://deciosfernandes.github.io/ng-date-hour-range-selector/)**\n\n---\n\n## Features\n\n- Date **and** time range selection, or date-only mode\n- 12-hour (AM/PM) and 24-hour time formats\n- Configurable minute step\n- Optional manual time inputs for direct hour/minute editing\n- Sidebar with predefined range shortcuts (Today, Yesterday, This/Last Week…)\n- Configurable calendar icon position (`left`, `right`, or hidden)\n- Optional reset button in the sidebar\n- Works as a `ControlValueAccessor` — drop into any reactive or template-driven form\n- Fully localizable via the `PICKER_LOCALE` injection token\n- Pre-select a range on load via the `initialRange` input\n- `nextRange()` / `previousRange()` / `setRange()` public API methods\n- No third-party date library required\n- Built on Angular CDK Overlay\n- Standalone components — no NgModule needed\n- A directive variant (`drsDateRangePicker`) to attach the picker to any `\u003cinput\u003e`\n- Accessible: keyboard navigation, ARIA attributes, meets WCAG AA\n- Dark theme included; fully themeable via CSS custom properties\n\n---\n\n## Requirements\n\n| Dependency     | Version    |\n| -------------- | ---------- |\n| Angular        | `\u003e=19.0.0` |\n| `@angular/cdk` | `\u003e=19.0.0` |\n\n---\n\n## Installation\n\n```bash\nnpm install ng-date-hour-range-selector @angular/cdk\n```\n\nImport the built-in dark theme once in your global styles:\n\n```scss\n@use 'ng-date-hour-range-selector/styles/theme';\n```\n\nAdd `provideAnimationsAsync()` to your application config:\n\n```ts\nimport { provideAnimationsAsync } from '@angular/platform-browser/animations/async';\n\nexport const appConfig: ApplicationConfig = {\n  providers: [provideAnimationsAsync()],\n};\n```\n\n---\n\n## Quick start\n\n### Component (`\u003cdrs-date-range-picker\u003e`)\n\n```ts\nimport { DateRange, DateRangePickerComponent } from 'ng-date-hour-range-selector';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n  imports: [ReactiveFormsModule, DateRangePickerComponent],\n  template: `\n    \u003cdrs-date-range-picker\n      [formControl]=\"rangeControl\"\n      (rangeChange)=\"onRangeChange($event)\"\n      ariaLabel=\"Select date range\"\n    /\u003e\n  `,\n})\nexport class MyComponent {\n  readonly rangeControl = new FormControl\u003cDateRange | null\u003e(null);\n\n  onRangeChange(range: DateRange | null): void {\n    console.log(range?.start, range?.end);\n  }\n}\n```\n\n### Directive (`[drsDateRangePicker]`)\n\nAttach the picker to any `\u003cinput\u003e` element:\n\n```ts\nimport { DateRangePickerDirective } from 'ng-date-hour-range-selector';\nimport { FormControl, ReactiveFormsModule } from '@angular/forms';\n\n@Component({\n  imports: [ReactiveFormsModule, DateRangePickerDirective],\n  template: `\n    \u003cinput\n      drsDateRangePicker\n      [formControl]=\"rangeControl\"\n      (rangeChange)=\"onRangeChange($event)\"\n      ariaLabel=\"Select date range\"\n    /\u003e\n  `,\n})\nexport class MyComponent {\n  readonly rangeControl = new FormControl\u003cDateRange | null\u003e(null);\n\n  onRangeChange(range: DateRange | null): void {\n    console.log(range?.start, range?.end);\n  }\n}\n```\n\n---\n\n## Component API — `\u003cdrs-date-range-picker\u003e`\n\n### Inputs\n\n| Input              | Type                            | Default               | Description                                                                       |\n| ------------------ | ------------------------------- | --------------------- | --------------------------------------------------------------------------------- |\n| `showTime`         | `boolean`                       | `true`                | Show the time-picker section                                                      |\n| `timeFormat`       | `'12h' \\| '24h'`                | `'24h'`               | 12-hour (AM/PM) or 24-hour format                                                 |\n| `minuteStep`       | `number`                        | `1`                   | Minute increment step                                                             |\n| `allowManualTimeInput` | `boolean`                   | `false`               | Enable editable hour/minute text inputs in the time picker                       |\n| `weekStartsOn`     | `0 \\| 1`                        | `1`                   | First day of week — `0` Sunday, `1` Monday                                        |\n| `predefinedRanges` | `PredefinedRange[]`             | built-in              | Sidebar shortcut definitions                                                      |\n| `minDate`          | `Date`                          | —                     | Minimum selectable date (inclusive)                                               |\n| `maxDate`          | `Date`                          | —                     | Maximum selectable date (inclusive)                                               |\n| `position`         | `ConnectedPosition[]`           | bottom-start          | CDK Overlay connected positions                                                   |\n| `showResetButton`  | `boolean`                       | `true`                | Show or hide the reset button in the sidebar                                      |\n| `calendarIcon`     | `'left' \\| 'right' \\| 'hidden'` | `'right'`             | Position of the calendar icon in the trigger button, or hide it                   |\n| `showApplyButton`  | `boolean`                       | `false`               | Show an Apply button inside the overlay that closes it when clicked               |\n| `closeOnSelect`    | `boolean`                       | `true`                | Automatically close the overlay after a complete range is selected or pre-defined |\n| `rangeMatchMode`   | `'day' \\| 'exact'`              | `'day'`               | How selected ranges are matched to predefined labels — `'day'` ignores time, `'exact'` requires identical timestamps |\n| `emitOn`           | `'change' \\| 'close'`           | `'change'`            | Controls when `rangeChange` is emitted. `'change'` — emit immediately on every date/time selection (default). `'close'` — defer emission until the overlay is closed or Apply is clicked; reset always emits immediately. |\n| `initialRange`     | `DateRange \\| PredefinedRange`  | —                     | Range or predefined-range factory to pre-select on component load                 |\n| `ariaLabel`        | `string`                        | `'Select date range'` | Accessible label for the trigger button                                           |\n\n### Output\n\n| Output        | Payload             | Description                                           |\n| ------------- | ------------------- | ----------------------------------------------------- |\n| `rangeChange` | `DateRange \\| null` | Emitted when a complete range is committed or cleared |\n\n### Public methods\n\n| Method                        | Description                                                                                                    |\n| ----------------------------- | -------------------------------------------------------------------------------------------------------------- |\n| `nextRange()`                 | Advance the current range forward by its own duration (e.g. Mon–Sun → next Mon–Sun)                            |\n| `previousRange()`             | Rewind the current range backward by its own duration                                                          |\n| `setRange(range, emitEvent?)` | Programmatically set `DateRange \\| null`; pass `emitEvent: false` to suppress `rangeChange` and CVA `onChange` |\n\n### ControlValueAccessor\n\n`DateRangePickerComponent` implements `ControlValueAccessor`, so it works with both `[formControl]` and `[(ngModel)]`:\n\n```html\n\u003c!-- Reactive forms --\u003e\n\u003cdrs-date-range-picker [formControl]=\"rangeControl\" /\u003e\n\n\u003c!-- Template-driven --\u003e\n\u003cdrs-date-range-picker [(ngModel)]=\"range\" /\u003e\n```\n\n---\n\n## Directive API — `[drsDateRangePicker]`\n\nThe directive exposes the **same inputs and output** as the component, **except** `calendarIcon` (which is specific to the component's trigger button).\n\n```html\n\u003cinput drsDateRangePicker [formControl]=\"ctrl\" [showTime]=\"false\" /\u003e\n```\n\n---\n\n## Models\n\n```ts\ninterface DateRange {\n  start: Date;\n  end: Date;\n}\n\ninterface PredefinedRange {\n  /** Label shown in the sidebar */\n  label: string;\n  /** Factory function — called on each click to produce a fresh range */\n  range: () =\u003e DateRange;\n}\n```\n\n---\n\n## Global configuration — `PICKER_CONFIG`\n\nOverride defaults for every picker in your application (or a specific feature):\n\n```ts\nimport { PICKER_CONFIG } from 'ng-date-hour-range-selector';\n\n// app.config.ts\nproviders: [\n  {\n    provide: PICKER_CONFIG,\n    useValue: { showTime: false, timeFormat: '12h', weekStartsOn: 0 },\n  },\n];\n```\n\nIndividual component/directive inputs always take precedence over the global config.\n\n### `PickerConfig` interface\n\n| Property           | Type                            | Default      | Description                                                                       |\n| ------------------ | ------------------------------- | ------------ | --------------------------------------------------------------------------------- |\n| `showTime`         | `boolean`                       | `true`       | Show the time-picker section                                                      |\n| `timeFormat`       | `'12h' \\| '24h'`                | `'24h'`      | Hour format                                                                       |\n| `minuteStep`       | `number`                        | `1`          | Minute increment step                                                             |\n| `allowManualTimeInput` | `boolean`                   | `false`      | Enable editable hour/minute text inputs in the time picker                       |\n| `weekStartsOn`     | `0 \\| 1`                        | `1`          | First day of week                                                                 |\n| `predefinedRanges` | `PredefinedRange[]`             | built-in     | Override all shortcuts globally                                                   |\n| `minDate`          | `Date`                          | —            | Global minimum date                                                               |\n| `maxDate`          | `Date`                          | —            | Global maximum date                                                               |\n| `position`         | `ConnectedPosition[]`           | bottom-start | CDK overlay positions                                                             |\n| `showResetButton`  | `boolean`                       | `true`       | Show or hide the reset button                                                     |\n| `calendarIcon`     | `'left' \\| 'right' \\| 'hidden'` | `'right'`    | Calendar icon position in the trigger button                                      |\n| `showApplyButton`  | `boolean`                       | `false`      | Show an Apply button inside the overlay                                           |\n| `closeOnSelect`    | `boolean`                       | `true`       | Automatically close the overlay after a complete range is selected or pre-defined |\n| `rangeMatchMode`   | `'day' \\| 'exact'`              | `'day'`      | How selected ranges are matched to predefined labels — `'day'` ignores time, `'exact'` requires identical timestamps |\n| `emitOn`           | `'change' \\| 'close'`           | `'change'`   | Controls when `rangeChange` is emitted. `'change'` — emit immediately on every date/time selection. `'close'` — defer emission until the overlay is closed or Apply is clicked; reset always emits immediately. |\n\n---\n\n## Localization — `PICKER_LOCALE`\n\nProvide a `PickerLocale` object to translate every visible string:\n\n```ts\nimport { PICKER_LOCALE, PickerLocale } from 'ng-date-hour-range-selector';\n\nconst ptBrLocale: PickerLocale = {\n  daysOfWeek: ['Do', 'Se', 'Te', 'Qu', 'Qi', 'Se', 'Sa'],\n  monthNames: [\n    'Janeiro',\n    'Fevereiro',\n    'Março',\n    'Abril',\n    'Maio',\n    'Junho',\n    'Julho',\n    'Agosto',\n    'Setembro',\n    'Outubro',\n    'Novembro',\n    'Dezembro',\n  ],\n  am: 'AM',\n  pm: 'PM',\n  startTime: 'Início:',\n  endTime: 'Fim:',\n  reset: 'Limpar',\n  apply: 'Aplicar',\n  placeholder: 'Selecione um período',\n  formatRange: (start, end) =\u003e\n    `${start.toLocaleDateString('pt-BR')} – ${end.toLocaleDateString('pt-BR')}`,\n  formatRangeWithTime: (start, end) =\u003e {\n    const fmt = (d: Date) =\u003e\n      `${d.toLocaleDateString('pt-BR')} ${String(d.getHours()).padStart(2, '0')}:${String(d.getMinutes()).padStart(2, '0')}`;\n    return `${fmt(start)} – ${fmt(end)}`;\n  },\n};\n\nproviders: [{ provide: PICKER_LOCALE, useValue: ptBrLocale }];\n```\n\n\u003e `formatRangeWithTime` is optional. When `showTime` is `true` and it is provided, the trigger will include times in the display value. Falls back to `formatRange` if omitted.\n\n### `PickerLocale` interface\n\n| Property              | Type                                 | Description                                                              |\n| --------------------- | ------------------------------------ | ------------------------------------------------------------------------ |\n| `daysOfWeek`          | `[string × 7]`                       | Abbreviated day labels — Sunday first                                    |\n| `monthNames`          | `[string × 12]`                      | Full month names — January first                                         |\n| `am`                  | `string`                             | AM toggle label                                                          |\n| `pm`                  | `string`                             | PM toggle label                                                          |\n| `startTime`           | `string`                             | Label above the start time picker                                        |\n| `endTime`             | `string`                             | Label above the end time picker                                          |\n| `reset`               | `string`                             | Reset/clear button label                                                 |\n| `apply`               | `string`                             | Apply button label (used when `showApplyButton` is `true`)               |\n| `placeholder`         | `string?`                            | Trigger placeholder when no range is selected                            |\n| `formatRange`         | `(start: Date, end: Date) =\u003e string` | Formats the selected range for display in the trigger                    |\n| `formatRangeWithTime` | `(start: Date, end: Date) =\u003e string` | Formats the range including time; falls back to `formatRange` if omitted |\n\n---\n\n## Predefined ranges\n\nThe sidebar shows these built-in shortcuts by default:\n\n- Today\n- Yesterday\n- This week / Last week\n- This month / Last month\n- This quarter / Last quarter\n\nReplace them per-picker via the `predefinedRanges` input, or globally via `PICKER_CONFIG`:\n\n```ts\nimport { PredefinedRange } from 'ng-date-hour-range-selector';\n\nconst customRanges: PredefinedRange[] = [\n  {\n    label: 'Last 7 days',\n    range: () =\u003e {\n      const end = new Date();\n      const start = new Date();\n      start.setDate(start.getDate() - 6);\n      start.setHours(0, 0, 0, 0);\n      end.setHours(23, 59, 59, 0);\n      return { start, end };\n    },\n  },\n  {\n    label: 'Last 30 days',\n    range: () =\u003e {\n      const end = new Date();\n      const start = new Date();\n      start.setDate(start.getDate() - 29);\n      start.setHours(0, 0, 0, 0);\n      end.setHours(23, 59, 59, 0);\n      return { start, end };\n    },\n  },\n];\n```\n\n```html\n\u003cdrs-date-range-picker [predefinedRanges]=\"customRanges\" /\u003e\n```\n\n---\n\n## Examples\n\n### Date-only picker\n\n```html\n\u003cdrs-date-range-picker [showTime]=\"false\" /\u003e\n```\n\n### 12-hour format, Sunday start\n\n```html\n\u003cdrs-date-range-picker timeFormat=\"12h\" [weekStartsOn]=\"0\" /\u003e\n```\n\n### Calendar icon on the left, no reset button\n\n```html\n\u003cdrs-date-range-picker calendarIcon=\"left\" [showResetButton]=\"false\" /\u003e\n```\n\n### Pre-selected range on load\n\n```ts\nreadonly initialRange: PredefinedRange = {\n  label: 'Last 7 days',\n  range: () =\u003e {\n    const end = new Date();\n    const start = new Date();\n    start.setDate(start.getDate() - 6);\n    return { start, end };\n  },\n};\n```\n\n```html\n\u003cdrs-date-range-picker [initialRange]=\"initialRange\" /\u003e\n```\n\n### Navigate range programmatically\n\n```ts\nprivate picker = viewChild(DateRangePickerComponent);\n\nnext(): void { this.picker()?.nextRange(); }\nprev(): void { this.picker()?.previousRange(); }\n```\n\n### Directive on a plain input\n\n```html\n\u003cinput drsDateRangePicker [formControl]=\"ctrl\" [showTime]=\"false\" /\u003e\n```\n\n---\n\n## Theming — CSS custom properties\n\nImport the built-in dark theme and override variables at `:root` or on specific elements:\n\n```scss\n@use 'ng-date-hour-range-selector/styles/theme';\n\n// Global accent colour\n:root {\n  --drs-primary: #3b82f6;\n}\n\n// Light theme override\ndrs-date-range-picker.light {\n  --drs-bg: #ffffff;\n  --drs-text: #111111;\n  --drs-border: rgba(0, 0, 0, 0.12);\n  --drs-hover: rgba(0, 0, 0, 0.06);\n  --drs-range-bg: rgba(59, 130, 246, 0.12);\n}\n```\n\nYou can also use the `style` attribute inline:\n\n```html\n\u003cdrs-date-range-picker style=\"--drs-primary: #8b5cf6;\" /\u003e\n```\n\n### Full variable reference\n\n| Variable                   | Description                       | Default     |\n| -------------------------- | --------------------------------- | ----------- |\n| `--drs-radius`             | Overlay panel border radius       | `10px`      |\n| `--drs-radius-sm`          | Button border radius              | `5px`       |\n| `--drs-sidebar-width`      | Predefined-ranges sidebar width   | `148px`     |\n| `--drs-overlay-z`          | z-index of the overlay panel      | `1000`      |\n| `--drs-shadow`             | Overlay panel box shadow          | dark shadow |\n| `--drs-bg`                 | Overlay / modal background        | `#1e1f22`   |\n| `--drs-trigger-bg`         | Trigger button background         | `--drs-bg`  |\n| `--drs-primary`            | Accent / highlight colour         | `#f97316`   |\n| `--drs-primary-fg`         | Foreground on accent colour       | `#ffffff`   |\n| `--drs-text`               | Primary text colour               | `#f1f1f1`   |\n| `--drs-text-muted`         | Dimmed / secondary text           | 35% opacity |\n| `--drs-border`             | Border and divider colour         | 8% white    |\n| `--drs-hover`              | Hover background                  | 7% white    |\n| `--drs-range-bg`           | In-range day background           | orange 14%  |\n| `--drs-time-bg`            | Time-picker box background        | 5% white    |\n| `--drs-font-family`        | Font family                       | `inherit`   |\n| `--drs-font-size`          | Base font size                    | `0.875rem`  |\n| `--drs-header-font-size`   | Month / year header size          | `0.9375rem` |\n| `--drs-header-font-weight` | Month / year header weight        | `700`       |\n| `--drs-weekday-font-size`  | Day-of-week label size            | `0.6875rem` |\n| `--drs-day-font-size`      | Day number size                   | `0.875rem`  |\n| `--drs-sidebar-font-size`  | Predefined-range label size       | `0.875rem`  |\n| `--drs-time-font-size`     | Hour / minute number size         | `1.375rem`  |\n| `--drs-ampm-font-size`     | AM/PM toggle size                 | `0.9375rem` |\n| `--drs-label-font-size`    | \"Start time:\" / \"End time:\" label | `0.8125rem` |\n| `--drs-trigger-font-size`  | Trigger button text size          | `0.875rem`  |\n| `--drs-apply-font-size`    | Apply button text size            | `0.875rem`  |\n\n---\n\n## Exported API surface\n\n```ts\n// Components \u0026 Directive\nexport { DateRangePickerComponent } from 'ng-date-hour-range-selector';\nexport { DateRangePickerDirective } from 'ng-date-hour-range-selector';\nexport { DateRangePickerPanelComponent } from 'ng-date-hour-range-selector';\nexport { CalendarComponent } from 'ng-date-hour-range-selector';\nexport { TimePickerComponent } from 'ng-date-hour-range-selector';\nexport { PredefinedRangesComponent } from 'ng-date-hour-range-selector';\n\n// Models\nexport type { DateRange, PredefinedRange } from 'ng-date-hour-range-selector';\nexport type { PickerConfig } from 'ng-date-hour-range-selector';\nexport type { PickerLocale } from 'ng-date-hour-range-selector';\nexport type { TimeValue } from 'ng-date-hour-range-selector';\nexport type { CalendarCell } from 'ng-date-hour-range-selector';\nexport type { ResolvedPickerConfig } from 'ng-date-hour-range-selector';\n\n// Tokens \u0026 defaults\nexport { PICKER_CONFIG, DEFAULT_PICKER_CONFIG } from 'ng-date-hour-range-selector';\nexport { PICKER_LOCALE, DEFAULT_PICKER_LOCALE } from 'ng-date-hour-range-selector';\n\n// Service\nexport { DateUtilsService } from 'ng-date-hour-range-selector';\n```\n\n---\n\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Start the demo app at http://localhost:4200\nnpm start\n\n# Build the library\nnpm run build:lib\n\n# Build library + demo\nnpm run build\n\n# Run unit tests\nnpm test\n```\n\n---\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeciosfernandes%2Fng-date-hour-range-selector","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdeciosfernandes%2Fng-date-hour-range-selector","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdeciosfernandes%2Fng-date-hour-range-selector/lists"}