native-datepicker
Advanced tools
Comparing version 0.0.1 to 1.0.2
{ | ||
"name": "native-datepicker", | ||
"version": "0.0.1", | ||
"description": "Native JavaScript date picker", | ||
"keywords": [], | ||
"author": "Ivan Mrvelj <sk8raid@gmail.com>", | ||
"license": "MIT", | ||
"main": "dist/index.js", | ||
"scripts": { | ||
"build": "webpack -p", | ||
"test": "" | ||
}, | ||
"repository": { | ||
"type": "git", | ||
"url": "git+https://github.com/perpaer/native-datepicker.git" | ||
}, | ||
"bugs": { | ||
"url": "https://github.com/perpaer/native-datepicker/issues" | ||
}, | ||
"homepage": "https://github.com/perpaer/native-datepicker#readme", | ||
"devDependencies": { | ||
"babel-core": "^6.13.2", | ||
"babel-loader": "^6.2.5", | ||
"chai": "^3.5.0", | ||
"eslint": "^3.3.1", | ||
"eslint-loader": "^1.5.0", | ||
"mocha": "^3.0.2", | ||
"webpack": "^1.13.2" | ||
}, | ||
"dependencies": { | ||
"moment": "^2.14.1" | ||
} | ||
"version": "1.0.2", | ||
"main": "src/index.js", | ||
"repository": "https://github.com/codeclown/native-datepicker", | ||
"author": "Martti Laine <martti@marttilaine.com>", | ||
"license": "ISC" | ||
} |
190
README.md
@@ -1,1 +0,189 @@ | ||
# native-datepicker | ||
# native-datepicker | ||
> Styleable datepicker utilizing the native `<input type="date">` | ||
Features: | ||
- Light-weight, no dependencies | ||
- Includes optional React-component | ||
- Supports datetime strings (only replaces date-portion upon change) | ||
- Simple styling, with BEM classes | ||
## Browser support | ||
Supported: | ||
- Chrome | ||
- Firefox | ||
- Edge | ||
- Safari iOS | ||
Not supported (datepicker is hidden): | ||
- Safari MacOS | ||
- IE | ||
## Usage | ||
### Vanilla JS | ||
```js | ||
const NativeDatepicker = require('native-datepicker'); | ||
const picker = new NativeDatepicker({ | ||
onChange: (newValue) => { | ||
console.log(newValue); | ||
}, | ||
}); | ||
someElement.appendChild(picker.element); | ||
``` | ||
See [API](#api). | ||
### React | ||
```jsx | ||
const NativeDatepicker = require('native-datepicker/src/react'); | ||
const SomeComponent = () => { | ||
const [date, setDate] = useState('2020-11-01'); | ||
return ( | ||
<NativeDatepicker value={date} onChange={(newValue) => setDate(newValue)} /> | ||
); | ||
}; | ||
``` | ||
See [React API](#react-api). | ||
## API | ||
### `class NativeDatepicker` | ||
#### `constructor(options)` | ||
`options` is an object with the following properties: | ||
##### `options.onChange` | ||
type: `function` default: `(value) => {}` | ||
Callback function which is called when the user selects a new date. | ||
Receives the new value as string (e.g. `"2020-11-01"` or `"2020-11-01 13:15:00"`; just the date-portion of the original value is replaced). | ||
##### `options.existingElement` | ||
type: `DOMElement` default: `null` | ||
If set, existing element will be used instead of creating a new `span` element. | ||
##### `options.win` | ||
type: `Window` default: `window` | ||
For the rare use case (e.g. using inside a child iframe) when setting `window` is necessary. | ||
#### `setValue(dateString)` | ||
Set the value of the datepicker. | ||
`dateString` should be a string containing a date in `YYYY-MM-DD` format. For example, all of these are valid: | ||
- `"2020-11-01"` | ||
- `"2020-11-01 13:15:00"` | ||
- `"2020-11-01T13:15:00"` | ||
Upon changes, NativeDatepicker will replace the date-portion of the string and return the result. | ||
#### `element` | ||
Contains a reference to the datepicker element. | ||
## React API | ||
### `NativeDatepicker` component | ||
Props: | ||
```jsx | ||
<NativeDatepicker | ||
value={date} | ||
onChange={(newValue) => {}} | ||
className="customClassName" | ||
> | ||
{optionalChildren} | ||
</NativeDatepicker> | ||
``` | ||
#### `props.value` | ||
type: `string` default: `""` | ||
Initial value. Examples: | ||
- `value="2020-11-01"` | ||
- `value="2020-11-01 13:15:00"` | ||
- `value="2020-11-01T13:15:00"` | ||
#### `props.onChange` | ||
type: `function` default: `(value) => {}` | ||
Callback function which is called when the user selects a new date. | ||
Receives the new value as string (e.g. `"2020-11-01"` or `"2020-11-01 13:15:00"`; just the date-portion of the original value is replaced). | ||
#### `props.className` | ||
type: `string` default: `""` | ||
Custom className for the created element. | ||
Example with `className="CustomClass"`: | ||
```html | ||
<span class="NativeDatepicker CustomClass"> | ||
<input class="NativeDatepicker__input" type="date" /> | ||
</span> | ||
``` | ||
#### `optionalChildren` | ||
If `children` are given, they are inserted into the resulting DOM. This can be used for any styling needs. | ||
Example: | ||
```html | ||
<span class="NativeDatepicker"> | ||
<!-- Children will be inserted here --> | ||
<input class="NativeDatepicker__input" type="date" /> | ||
</span> | ||
``` | ||
## Styling / DOM structure | ||
The following DOM is created for each datepicker: | ||
```html | ||
<span class="NativeDatepicker"> | ||
<input class="NativeDatepicker__input" type="date" /> | ||
</span> | ||
``` | ||
The recommended way to style the datepicker is to apply styles (e.g. width/height and a background-image) to the topmost element. Example: | ||
```css | ||
.NativeDatepicker { | ||
width: 16px; | ||
height: 16px; | ||
background: transparent url(...) no-repeat center center; | ||
} | ||
``` | ||
Note: under normal circumstances you should not add any styles to `.NativeDatepicker__input`! | ||
## Development | ||
Source files reside in `src/`. They should be remain valid ES5 code (they are not precompiled in any way). | ||
## License | ||
[ISC](./LICENSE) |
111
src/index.js
@@ -1,3 +0,110 @@ | ||
import moment from 'moment'; | ||
const classNames = { | ||
wrapper: 'NativeDatepicker', | ||
input: 'NativeDatepicker__input', | ||
}; | ||
console.log('hello world'); | ||
const dateRegex = /\d{4}-\d{2}-\d{2}/; | ||
class NativeDatepicker { | ||
constructor(options) { | ||
this.options = Object.assign( | ||
{ | ||
win: typeof window !== 'undefined' ? window : undefined, | ||
existingElement: null, | ||
onChange: () => {}, | ||
}, | ||
options | ||
); | ||
this.addStylesheet(); | ||
this.buildDom(); | ||
} | ||
setValue(fullString) { | ||
const match = fullString.match(dateRegex); | ||
if (match) { | ||
this.fullValue = fullString; | ||
this.dateValue = match[0]; | ||
this.dateInputElement.value = match[0]; | ||
} | ||
} | ||
buildDom() { | ||
// DOM structure: | ||
// <span class="datepicker-toggle"> | ||
// <!-- optional DOM nodes from user --> | ||
// <input type="date" class="datepicker-input"> | ||
// </span> | ||
const element = | ||
this.options.existingElement || | ||
this.options.win.document.createElement('span'); | ||
element.classList.add(classNames.wrapper); | ||
this.element = element; | ||
if (!this.isSupported()) { | ||
// Not via CSS class because we don't want to mess with | ||
// CSS-set display values, to not mess up user styles | ||
element.style.display = 'none'; | ||
} | ||
const dateInputElement = this.options.win.document.createElement('input'); | ||
dateInputElement.type = 'date'; | ||
dateInputElement.classList.add(classNames.input); | ||
element.appendChild(dateInputElement); | ||
this.dateInputElement = dateInputElement; | ||
dateInputElement.addEventListener('change', () => { | ||
let newValue = this.fullValue.replace(dateRegex, dateInputElement.value); | ||
// Regex didn't match, fallback to setting the entire value | ||
if (!newValue.includes(dateInputElement.value)) { | ||
newValue = dateInputElement.value; | ||
} | ||
dateInputElement.value = this.dateValue; | ||
this.options.onChange(newValue); | ||
}); | ||
} | ||
addStylesheet() { | ||
if (!this.options.win.document.querySelector('style#nativeDatepicker')) { | ||
const style = this.options.win.document.createElement('style'); | ||
style.id = 'nativeDatepicker'; | ||
style.textContent = ` | ||
.${classNames.wrapper} { | ||
display: inline-block; | ||
position: relative; | ||
} | ||
.${classNames.input} { | ||
position: absolute; | ||
left: 0; | ||
top: 0; | ||
width: 100%; | ||
height: 100%; | ||
opacity: 0; | ||
cursor: pointer; | ||
box-sizing: border-box; | ||
} | ||
.${classNames.input}::-webkit-calendar-picker-indicator { | ||
position: absolute; | ||
left: 0; | ||
top: 0; | ||
width: 100%; | ||
height: 100%; | ||
margin: 0; | ||
padding: 0; | ||
cursor: pointer; | ||
} | ||
`; | ||
this.options.win.document.head.appendChild(style); | ||
} | ||
} | ||
isSupported() { | ||
const input = this.options.win.document.createElement('input'); | ||
input.type = 'date'; | ||
input.value = 'invalid date value'; | ||
return input.value !== 'invalid date value'; | ||
} | ||
} | ||
module.exports = NativeDatepicker; |
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No bug tracker
MaintenancePackage does not have a linked bug tracker in package.json.
Found 1 instance in 1 package
No repository
Supply chain riskPackage does not have a linked source code repository. Without this field, a package will have no reference to the location of the source code use to generate the package.
Found 1 instance in 1 package
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No tests
QualityPackage does not have any tests. This is a strong signal of a poorly maintained or low quality package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
8774
0
0
133
1
190
5
1
1
- Removedmoment@^2.14.1
- Removedmoment@2.30.1(transitive)