@codesuma/baseline 1.0.11 → 1.0.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/index.ts CHANGED
@@ -32,5 +32,5 @@ export { default as state } from './lib/state'
32
32
  export { createEmitter, emitter, IEmitter } from './utils/emitter'
33
33
  export { createStyler, injectCSS, IStyler, CS } from './utils/styler'
34
34
  export { waitFor } from './utils/wait'
35
- export { withRipple } from './utils/ripple'
35
+ export { initRipple } from './utils/ripple'
36
36
  export { nextId, shortUUID, uuidv4 } from './utils/id'
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@codesuma/baseline",
3
- "version": "1.0.11",
3
+ "version": "1.0.12",
4
4
  "description": "A minimal, imperative UI framework for building fast web apps. No virtual DOM, no magic, no dependencies.",
5
5
  "main": "index.ts",
6
6
  "types": "index.ts",
package/utils/ripple.ts CHANGED
@@ -1,59 +1,60 @@
1
- // Ripple effect - Material Design style touch feedback
2
-
3
- import { Base, IBaseComponent } from '../components/base'
4
1
  import { injectCSS } from '../utils/styler'
5
2
 
6
3
  const RIPPLE_CSS = `
4
+ [data-ripple] {
5
+ position: relative;
6
+ overflow: hidden;
7
+ }
7
8
  [data-ripple] .ripple {
8
9
  position: absolute;
9
10
  border-radius: 50%;
10
11
  background: currentColor;
11
- opacity: 0.1;
12
+ opacity: 0.15;
12
13
  transform: scale(0);
13
14
  pointer-events: none;
14
- }
15
- [data-ripple] .ripple.animate {
16
- animation: ripple 1s ease-out;
15
+ animation: ripple 600ms ease-out forwards;
17
16
  }
18
17
  @keyframes ripple {
19
18
  to { transform: scale(4); opacity: 0; }
20
19
  }
21
20
  `
22
21
 
23
- export const withRipple = <T extends IBaseComponent<any>>(component: T): T => {
22
+ export const initRipple = () => {
24
23
  injectCSS('base-ripple', RIPPLE_CSS)
25
24
 
26
- component.el.setAttribute('data-ripple', '')
27
-
28
- const createRipple = (x: number, y: number) => {
29
- const ripple = Base('span')
30
- ripple.el.className = 'ripple'
25
+ let touchedRecently = false
31
26
 
32
- const rect = component.el.getBoundingClientRect()
27
+ const createRipple = (el: HTMLElement, x: number, y: number) => {
28
+ const rect = el.getBoundingClientRect()
33
29
  const size = Math.max(rect.width, rect.height) * 2
34
30
 
35
- ripple.style({
31
+ const ripple = document.createElement('span')
32
+ ripple.className = 'ripple'
33
+ Object.assign(ripple.style, {
36
34
  width: size + 'px',
37
35
  height: size + 'px',
38
36
  left: (x - rect.left - size / 2) + 'px',
39
37
  top: (y - rect.top - size / 2) + 'px'
40
38
  })
41
39
 
42
- component.el.appendChild(ripple.el)
43
- ripple.el.classList.add('animate')
44
-
45
- setTimeout(() => ripple.el.remove(), 600)
40
+ el.appendChild(ripple)
41
+ ripple.addEventListener('animationend', () => ripple.remove())
46
42
  }
47
43
 
48
- component.el.addEventListener('touchstart', (e: TouchEvent) => {
49
- createRipple(e.touches[0].clientX, e.touches[0].clientY)
44
+ document.addEventListener('touchstart', (e) => {
45
+ const el = (e.target as HTMLElement).closest<HTMLElement>('[data-ripple]')
46
+ if (el) {
47
+ touchedRecently = true
48
+ createRipple(el, e.touches[0].clientX, e.touches[0].clientY)
49
+ setTimeout(() => touchedRecently = false, 100)
50
+ }
50
51
  }, { passive: true })
51
52
 
52
- component.el.addEventListener('mousedown', (e: MouseEvent) => {
53
- createRipple(e.clientX, e.clientY)
53
+ document.addEventListener('mousedown', (e) => {
54
+ if (touchedRecently) return
55
+ const el = (e.target as HTMLElement).closest<HTMLElement>('[data-ripple]')
56
+ if (el) {
57
+ createRipple(el, e.clientX, e.clientY)
58
+ }
54
59
  })
55
-
56
- return component
57
- }
58
-
59
- export default withRipple
60
+ }