@gnireeg/float-bar 0.1.0
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/README.md +124 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +225 -0
- package/dist/index.js.map +1 -0
- package/dist/jsx.d.ts +26 -0
- package/dist/types-entry.d.ts +3 -0
- package/dist/types.d.ts +35 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +5 -0
- package/dist/types.js.map +1 -0
- package/package.json +54 -0
package/README.md
ADDED
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
# @gnireeg/float-bar
|
|
2
|
+
|
|
3
|
+
Floating bar web component that automatically hides when scrolling down and reveals when scrolling up.
|
|
4
|
+
|
|
5
|
+
## Features
|
|
6
|
+
|
|
7
|
+
- ✨ Smooth animations using requestAnimationFrame
|
|
8
|
+
- 📍 Auto-hide on scroll down, auto-show on scroll up
|
|
9
|
+
- 🎯 Works with both window scroll and container scroll
|
|
10
|
+
- ⚙️ Configurable offset to account for sticky elements
|
|
11
|
+
- 📦 Zero dependencies
|
|
12
|
+
- 🎯 TypeScript support
|
|
13
|
+
- 💨 Lightweight and performant
|
|
14
|
+
|
|
15
|
+
## Installation
|
|
16
|
+
|
|
17
|
+
```bash
|
|
18
|
+
npm install @gnireeg/float-bar
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
## Usage
|
|
22
|
+
|
|
23
|
+
### Basic Usage
|
|
24
|
+
|
|
25
|
+
```html
|
|
26
|
+
<script type="module">
|
|
27
|
+
import '@gnireeg/float-bar';
|
|
28
|
+
</script>
|
|
29
|
+
|
|
30
|
+
<float-bar class="bg-slate-800 text-white px-6 py-4">
|
|
31
|
+
<nav>Your navigation content</nav>
|
|
32
|
+
</float-bar>
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
### With Offset
|
|
36
|
+
|
|
37
|
+
Use the `offset` attribute to account for sticky elements above the float bar:
|
|
38
|
+
|
|
39
|
+
```html
|
|
40
|
+
<float-bar offset="80" class="bg-white shadow-md">
|
|
41
|
+
<nav>Your navigation content</nav>
|
|
42
|
+
</float-bar>
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
### With Offset Element
|
|
46
|
+
|
|
47
|
+
Automatically use another element's height as offset:
|
|
48
|
+
|
|
49
|
+
```html
|
|
50
|
+
<header id="top-header" style="height: 60px;">Fixed header</header>
|
|
51
|
+
|
|
52
|
+
<float-bar offset-element="#top-header" class="bg-white shadow-md">
|
|
53
|
+
<nav>Your navigation content</nav>
|
|
54
|
+
</float-bar>
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### In Scrollable Container
|
|
58
|
+
|
|
59
|
+
The float bar automatically detects its scroll container:
|
|
60
|
+
|
|
61
|
+
```html
|
|
62
|
+
<div style="position: relative; overflow: auto; height: 500px;">
|
|
63
|
+
<float-bar class="bg-white shadow-md">
|
|
64
|
+
<nav>Your navigation content</nav>
|
|
65
|
+
</float-bar>
|
|
66
|
+
<div>Scrollable content...</div>
|
|
67
|
+
</div>
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Disabled (Static)
|
|
71
|
+
|
|
72
|
+
Disable the auto-hide behavior:
|
|
73
|
+
|
|
74
|
+
```html
|
|
75
|
+
<float-bar disabled class="bg-white shadow-md">
|
|
76
|
+
<nav>Static navigation</nav>
|
|
77
|
+
</float-bar>
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## API
|
|
81
|
+
|
|
82
|
+
### Attributes
|
|
83
|
+
|
|
84
|
+
| Attribute | Type | Default | Description |
|
|
85
|
+
|-----------|------|---------|-------------|
|
|
86
|
+
| `offset` | number | `0` | Offset in pixels from the top |
|
|
87
|
+
| `offset-element` | string | - | CSS selector for an element whose height will be used as offset |
|
|
88
|
+
| `disabled` | boolean | `false` | Disables auto-hide behavior |
|
|
89
|
+
|
|
90
|
+
## Styling
|
|
91
|
+
|
|
92
|
+
The float bar uses CSS transforms for smooth animations. You can style it like any other element:
|
|
93
|
+
|
|
94
|
+
```css
|
|
95
|
+
float-bar {
|
|
96
|
+
background: white;
|
|
97
|
+
box-shadow: 0 2px 4px rgba(0,0,0,0.1);
|
|
98
|
+
padding: 1rem;
|
|
99
|
+
}
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## How it Works
|
|
103
|
+
|
|
104
|
+
The float bar:
|
|
105
|
+
1. Automatically detects its scroll container (window or parent element)
|
|
106
|
+
2. Monitors scroll direction
|
|
107
|
+
3. Hides when scrolling down (using translateY transform)
|
|
108
|
+
4. Shows when scrolling up
|
|
109
|
+
5. Uses requestAnimationFrame for smooth 60fps animations
|
|
110
|
+
|
|
111
|
+
## Browser Support
|
|
112
|
+
|
|
113
|
+
Works in all modern browsers that support:
|
|
114
|
+
- Custom Elements v1
|
|
115
|
+
- Shadow DOM v1
|
|
116
|
+
- ES Modules
|
|
117
|
+
|
|
118
|
+
## License
|
|
119
|
+
|
|
120
|
+
MIT
|
|
121
|
+
|
|
122
|
+
## Author
|
|
123
|
+
|
|
124
|
+
Joel Geering
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,YAAY,EACV,eAAe,EACf,kBAAkB,GACnB,MAAM,SAAS,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
// SSR-safe: Only define and register components in browser environment
|
|
2
|
+
if (typeof window !== 'undefined' && typeof HTMLElement !== 'undefined') {
|
|
3
|
+
/**
|
|
4
|
+
* A floating bar component with scroll spy, automatic positioning, and sticky behavior.
|
|
5
|
+
*
|
|
6
|
+
* Works with both window scroll and container scroll. The scroll container is automatically
|
|
7
|
+
* detected based on the element's offsetParent. If offsetParent is null or document.body,
|
|
8
|
+
* it will listen to window/document scroll events. Otherwise, it listens to the scroll
|
|
9
|
+
* events of the offsetParent element.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* <!-- Window scroll -->
|
|
13
|
+
* <float-bar>
|
|
14
|
+
* <nav>Your navigation content</nav>
|
|
15
|
+
* </float-bar>
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* <!-- Container scroll -->
|
|
19
|
+
* <div style="position: relative; overflow: auto; height: 500px;">
|
|
20
|
+
* <float-bar>
|
|
21
|
+
* <nav>Your navigation content</nav>
|
|
22
|
+
* </float-bar>
|
|
23
|
+
* <div>Scrollable content...</div>
|
|
24
|
+
* </div>
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
* <!-- With offset (e.g., when a fixed header is above) -->
|
|
28
|
+
* <float-bar offset="80">
|
|
29
|
+
* <nav>Your navigation content</nav>
|
|
30
|
+
* </float-bar>
|
|
31
|
+
*
|
|
32
|
+
* @example
|
|
33
|
+
* <!-- With offset-element (automatically uses another element's height as offset) -->
|
|
34
|
+
* <header id="top-header">Fixed header</header>
|
|
35
|
+
* <float-bar offset-element="#top-header">
|
|
36
|
+
* <nav>Your navigation content</nav>
|
|
37
|
+
* </float-bar>
|
|
38
|
+
*
|
|
39
|
+
* @example
|
|
40
|
+
* <!-- Disabled (bar scrolls normally without hiding) -->
|
|
41
|
+
* <float-bar disabled>
|
|
42
|
+
* <nav>Your navigation content</nav>
|
|
43
|
+
* </float-bar>
|
|
44
|
+
*/
|
|
45
|
+
class FloatBar extends HTMLElement {
|
|
46
|
+
static get observedAttributes() {
|
|
47
|
+
return ['offset', 'disabled'];
|
|
48
|
+
}
|
|
49
|
+
constructor() {
|
|
50
|
+
super();
|
|
51
|
+
this.lastScroll = 0;
|
|
52
|
+
this.translateAmount = 0;
|
|
53
|
+
this.navbarHeight = 0;
|
|
54
|
+
this.ticking = false;
|
|
55
|
+
this.resizeTimeout = null;
|
|
56
|
+
this.scrollParent = document;
|
|
57
|
+
this.disabled = false;
|
|
58
|
+
this.offset = 0;
|
|
59
|
+
this.offsetElement = null;
|
|
60
|
+
this.totalOffset = 0;
|
|
61
|
+
this.offsetElementObserver = null;
|
|
62
|
+
this.isResizing = false;
|
|
63
|
+
this.handleScroll = () => {
|
|
64
|
+
if (this.isResizing) {
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
if (!this.ticking) {
|
|
68
|
+
requestAnimationFrame(() => {
|
|
69
|
+
this.calculateTranslateAmount();
|
|
70
|
+
this.applyTransform();
|
|
71
|
+
this.ticking = false;
|
|
72
|
+
});
|
|
73
|
+
this.ticking = true;
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
this.handleResize = () => {
|
|
77
|
+
if (this.resizeTimeout)
|
|
78
|
+
clearTimeout(this.resizeTimeout);
|
|
79
|
+
this.resizeTimeout = setTimeout(() => {
|
|
80
|
+
this.handleResizeUpdate();
|
|
81
|
+
}, 150);
|
|
82
|
+
};
|
|
83
|
+
this.disabled = this.hasAttribute('disabled');
|
|
84
|
+
const offsetAttr = this.getAttribute('offset');
|
|
85
|
+
//this.offset = offsetAttr ? parseInt(offsetAttr, 10) : 0;
|
|
86
|
+
this.shadow = this.attachShadow({ mode: 'open' });
|
|
87
|
+
this.shadow.innerHTML = `
|
|
88
|
+
<style>
|
|
89
|
+
:host {
|
|
90
|
+
display: block;
|
|
91
|
+
position: sticky;
|
|
92
|
+
top: var(--sticky-top, 0px);
|
|
93
|
+
left: 0;
|
|
94
|
+
width: 100%;
|
|
95
|
+
}
|
|
96
|
+
</style>
|
|
97
|
+
<slot></slot>
|
|
98
|
+
`;
|
|
99
|
+
this.updateStickyTop();
|
|
100
|
+
}
|
|
101
|
+
updateStickyTop() {
|
|
102
|
+
this.style.setProperty('--sticky-top', `${this.totalOffset}px`);
|
|
103
|
+
}
|
|
104
|
+
calculateTotalOffset() {
|
|
105
|
+
this.totalOffset = this.offset + (this.offsetElement ? this.offsetElement.clientHeight : 0);
|
|
106
|
+
}
|
|
107
|
+
attributeChangedCallback(name, oldValue, newValue) {
|
|
108
|
+
if (oldValue === newValue)
|
|
109
|
+
return;
|
|
110
|
+
if (name === 'offset') {
|
|
111
|
+
this.offset = newValue ? parseInt(newValue, 10) : 0;
|
|
112
|
+
this.calculateTotalOffset();
|
|
113
|
+
this.updateStickyTop();
|
|
114
|
+
}
|
|
115
|
+
if (name === 'disabled') {
|
|
116
|
+
const wasDisabled = this.disabled;
|
|
117
|
+
this.disabled = newValue !== null;
|
|
118
|
+
// Reset navbar position when disabled state changes
|
|
119
|
+
this.translateAmount = 0;
|
|
120
|
+
this.applyTransform();
|
|
121
|
+
// If re-enabled, reset scroll tracking
|
|
122
|
+
if (wasDisabled && !this.disabled) {
|
|
123
|
+
this.lastScroll = this.getScrollPosition();
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
connectedCallback() {
|
|
128
|
+
this.scrollParent = this.offsetParent ?? document;
|
|
129
|
+
if (this.scrollParent === document.body) {
|
|
130
|
+
this.scrollParent = document;
|
|
131
|
+
}
|
|
132
|
+
const offsetElementSelector = this.getAttribute('offset-element');
|
|
133
|
+
if (offsetElementSelector) {
|
|
134
|
+
const el = document.querySelector(offsetElementSelector);
|
|
135
|
+
if (el) {
|
|
136
|
+
this.offsetElement = el;
|
|
137
|
+
this.addObserverToOffsetElement();
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
requestAnimationFrame(() => {
|
|
141
|
+
this.measureNavbarHeight();
|
|
142
|
+
this.calculateTotalOffset();
|
|
143
|
+
this.updateStickyTop();
|
|
144
|
+
this.lastScroll = this.getScrollPosition();
|
|
145
|
+
});
|
|
146
|
+
this.scrollParent.addEventListener('scroll', this.handleScroll, { passive: true });
|
|
147
|
+
window.addEventListener('resize', this.handleResize);
|
|
148
|
+
}
|
|
149
|
+
disconnectedCallback() {
|
|
150
|
+
this.scrollParent.removeEventListener('scroll', this.handleScroll);
|
|
151
|
+
window.removeEventListener('resize', this.handleResize);
|
|
152
|
+
if (this.resizeTimeout) {
|
|
153
|
+
clearTimeout(this.resizeTimeout);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
addObserverToOffsetElement() {
|
|
157
|
+
if (this.offsetElement) {
|
|
158
|
+
this.offsetElementObserver = new ResizeObserver(() => {
|
|
159
|
+
this.handleResizeUpdate();
|
|
160
|
+
});
|
|
161
|
+
this.offsetElementObserver.observe(this.offsetElement);
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
handleResizeUpdate() {
|
|
165
|
+
this.isResizing = true;
|
|
166
|
+
this.measureNavbarHeight();
|
|
167
|
+
this.calculateTotalOffset();
|
|
168
|
+
this.updateStickyTop();
|
|
169
|
+
// Update lastScroll after a short delay to ensure layout has settled
|
|
170
|
+
// and any scroll events triggered by the resize have fired
|
|
171
|
+
setTimeout(() => {
|
|
172
|
+
this.lastScroll = this.getScrollPosition();
|
|
173
|
+
this.isResizing = false;
|
|
174
|
+
}, 0);
|
|
175
|
+
}
|
|
176
|
+
measureNavbarHeight() {
|
|
177
|
+
this.navbarHeight = this.offsetHeight;
|
|
178
|
+
}
|
|
179
|
+
getScrollPosition() {
|
|
180
|
+
if (this.scrollParent === document) {
|
|
181
|
+
return window.scrollY || document.documentElement.scrollTop;
|
|
182
|
+
}
|
|
183
|
+
return this.scrollParent.scrollTop;
|
|
184
|
+
}
|
|
185
|
+
isSticky() {
|
|
186
|
+
if (this.scrollParent === document) {
|
|
187
|
+
return this.getBoundingClientRect().top <= this.totalOffset;
|
|
188
|
+
}
|
|
189
|
+
const parent = this.scrollParent;
|
|
190
|
+
const parentRect = parent.getBoundingClientRect();
|
|
191
|
+
const navbarRect = this.getBoundingClientRect();
|
|
192
|
+
// Account for parent's border
|
|
193
|
+
const computedStyle = window.getComputedStyle(parent);
|
|
194
|
+
const borderTop = parseFloat(computedStyle.borderTopWidth) || 0;
|
|
195
|
+
const threshold = parentRect.top + borderTop + this.totalOffset;
|
|
196
|
+
// Use small tolerance (1px) to account for floating point precision
|
|
197
|
+
return navbarRect.top <= threshold + 1;
|
|
198
|
+
}
|
|
199
|
+
calculateTranslateAmount() {
|
|
200
|
+
if (this.disabled) {
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
const currentScroll = this.getScrollPosition();
|
|
204
|
+
const scrollDiff = currentScroll - this.lastScroll;
|
|
205
|
+
const isSticky = this.isSticky();
|
|
206
|
+
if (currentScroll <= 0 || !isSticky) {
|
|
207
|
+
this.translateAmount = 0;
|
|
208
|
+
}
|
|
209
|
+
else if (scrollDiff > 0) {
|
|
210
|
+
this.translateAmount = Math.min(this.translateAmount + scrollDiff, this.navbarHeight);
|
|
211
|
+
}
|
|
212
|
+
else {
|
|
213
|
+
this.translateAmount = Math.max(this.translateAmount + scrollDiff, 0);
|
|
214
|
+
}
|
|
215
|
+
this.lastScroll = currentScroll;
|
|
216
|
+
}
|
|
217
|
+
applyTransform() {
|
|
218
|
+
this.style.transform = `translateY(-${this.translateAmount}px)`;
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
// Register custom element
|
|
222
|
+
customElements.define('float-bar', FloatBar);
|
|
223
|
+
}
|
|
224
|
+
export {};
|
|
225
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/jsx.d.ts
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSX type definitions for float-bar web component
|
|
3
|
+
*
|
|
4
|
+
* This file augments the JSX namespace to add type definitions for custom elements.
|
|
5
|
+
* Works with both React and Preact without requiring React-specific types.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import type {
|
|
9
|
+
FloatBarAttributes,
|
|
10
|
+
} from './types';
|
|
11
|
+
|
|
12
|
+
declare global {
|
|
13
|
+
namespace JSX {
|
|
14
|
+
interface IntrinsicElements {
|
|
15
|
+
'float-bar': FloatBarAttributes;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
namespace React.JSX {
|
|
19
|
+
interface IntrinsicElements {
|
|
20
|
+
'float-bar': FloatBarAttributes;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// This export is required to make this file a module
|
|
26
|
+
export {};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom element interfaces for float-bar components
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* FloatBar custom element interface
|
|
6
|
+
*/
|
|
7
|
+
export interface FloatBarElement extends HTMLElement {
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* HTML attributes for float-bar element
|
|
11
|
+
*/
|
|
12
|
+
export interface FloatBarAttributes {
|
|
13
|
+
/**
|
|
14
|
+
* Offset in pixels from the top
|
|
15
|
+
*/
|
|
16
|
+
offset?: string | number;
|
|
17
|
+
/**
|
|
18
|
+
* CSS selector for an element whose height will be used as offset
|
|
19
|
+
*/
|
|
20
|
+
'offset-element'?: string;
|
|
21
|
+
/**
|
|
22
|
+
* Disables auto-hide behavior
|
|
23
|
+
*/
|
|
24
|
+
disabled?: boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Children and standard HTML attributes
|
|
27
|
+
*/
|
|
28
|
+
children?: any;
|
|
29
|
+
slot?: string;
|
|
30
|
+
className?: string;
|
|
31
|
+
class?: string;
|
|
32
|
+
style?: string | Record<string, any>;
|
|
33
|
+
id?: string;
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH;;GAEG;AACH,MAAM,WAAW,eAAgB,SAAQ,WAAW;CAAG;AAEvD;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC;;OAEG;IACH,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IAEzB;;OAEG;IACH,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,QAAQ,CAAC,EAAE,OAAO,CAAC;IAEnB;;OAEG;IACH,QAAQ,CAAC,EAAE,GAAG,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IACrC,EAAE,CAAC,EAAE,MAAM,CAAC;CACb"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
|
package/package.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@gnireeg/float-bar",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Floating bar web component with automatic positioning and sticky behavior",
|
|
5
|
+
"type": "module",
|
|
6
|
+
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/types-entry.d.ts",
|
|
9
|
+
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"types": "./dist/types-entry.d.ts",
|
|
13
|
+
"default": "./dist/index.js"
|
|
14
|
+
}
|
|
15
|
+
},
|
|
16
|
+
|
|
17
|
+
"files": [
|
|
18
|
+
"dist",
|
|
19
|
+
"README.md"
|
|
20
|
+
],
|
|
21
|
+
|
|
22
|
+
"keywords": [
|
|
23
|
+
"float-bar",
|
|
24
|
+
"floating-bar",
|
|
25
|
+
"navigation",
|
|
26
|
+
"tabs",
|
|
27
|
+
"sticky",
|
|
28
|
+
"web-components",
|
|
29
|
+
"custom-elements",
|
|
30
|
+
"accessible",
|
|
31
|
+
"a11y",
|
|
32
|
+
"typescript",
|
|
33
|
+
"ui-components"
|
|
34
|
+
],
|
|
35
|
+
|
|
36
|
+
"author": "Joel Geering <joel@geering.dev> (https://geering.dev)",
|
|
37
|
+
"license": "MIT",
|
|
38
|
+
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/gnireeG/web-components.git",
|
|
42
|
+
"directory": "packages/float-bar"
|
|
43
|
+
},
|
|
44
|
+
|
|
45
|
+
"scripts": {
|
|
46
|
+
"build": "tsc && node -e \"const fs = require('fs'); fs.copyFileSync('src/jsx.d.ts', 'dist/jsx.d.ts'); fs.copyFileSync('src/types-entry.d.ts', 'dist/types-entry.d.ts');\"",
|
|
47
|
+
"dev": "tsc --watch",
|
|
48
|
+
"prepublishOnly": "npm run build"
|
|
49
|
+
},
|
|
50
|
+
|
|
51
|
+
"devDependencies": {
|
|
52
|
+
"typescript": "^5.4.0"
|
|
53
|
+
}
|
|
54
|
+
}
|