denwa-web-shared 1.0.54 → 1.0.55

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.
@@ -1,3 +1,4 @@
1
1
  export * from './use-disable-scroll';
2
2
  export * from './use-is-client';
3
3
  export * from './use-view-port';
4
+ export * from './use-appear-animation';
@@ -0,0 +1,17 @@
1
+ import { MotionProps, Easing } from 'motion/react';
2
+ type MarginValue = `${number}${'px' | '%'}`;
3
+ export interface UseAppearAnimationProps {
4
+ once?: boolean;
5
+ margin?: MarginValue | `${MarginValue} ${MarginValue}` | `${MarginValue} ${MarginValue} ${MarginValue}` | `${MarginValue} ${MarginValue} ${MarginValue} ${MarginValue}`;
6
+ delay?: number;
7
+ direction?: 'up' | 'down' | 'left' | 'right' | 'scale' | 'fade';
8
+ animationDistance?: number;
9
+ duration?: number;
10
+ ease?: Easing | Easing[];
11
+ }
12
+ export declare const useAppearAnimation: <T extends HTMLElement = HTMLElement>({ once, margin, delay, direction, animationDistance, duration, ease, }?: UseAppearAnimationProps) => {
13
+ ref: import('../../../node_modules/react').RefObject<T | null>;
14
+ isInView: boolean;
15
+ motionProps: Omit<MotionProps, "ref">;
16
+ };
17
+ export {};
@@ -18,7 +18,28 @@ const useIsClient = () => {
18
18
  }, []);
19
19
  return isClient;
20
20
  };
21
+ function on(obj) {
22
+ var args = [];
23
+ for (var _i = 1; _i < arguments.length; _i++) {
24
+ args[_i - 1] = arguments[_i];
25
+ }
26
+ if (obj && obj.addEventListener) {
27
+ obj.addEventListener.apply(obj, args);
28
+ }
29
+ }
30
+ function off(obj) {
31
+ var args = [];
32
+ for (var _i = 1; _i < arguments.length; _i++) {
33
+ args[_i - 1] = arguments[_i];
34
+ }
35
+ if (obj && obj.removeEventListener) {
36
+ obj.removeEventListener.apply(obj, args);
37
+ }
38
+ }
21
39
  var isBrowser = typeof window !== "undefined";
40
+ var useEffectOnce = function(effect) {
41
+ React.useEffect(effect, []);
42
+ };
22
43
  var useIntersection = function(ref, options) {
23
44
  var _a = React.useState(null), intersectionObserverEntry = _a[0], setIntersectionObserverEntry = _a[1];
24
45
  React.useEffect(function() {
@@ -67,6 +88,57 @@ var useMedia = function(query, defaultState) {
67
88
  }, [query]);
68
89
  return state;
69
90
  };
91
+ var useUnmount = function(fn) {
92
+ var fnRef = React.useRef(fn);
93
+ fnRef.current = fn;
94
+ useEffectOnce(function() {
95
+ return function() {
96
+ return fnRef.current();
97
+ };
98
+ });
99
+ };
100
+ var useRafState = function(initialState) {
101
+ var frame = React.useRef(0);
102
+ var _a = React.useState(initialState), state = _a[0], setState = _a[1];
103
+ var setRafState = React.useCallback(function(value) {
104
+ cancelAnimationFrame(frame.current);
105
+ frame.current = requestAnimationFrame(function() {
106
+ setState(value);
107
+ });
108
+ }, []);
109
+ useUnmount(function() {
110
+ cancelAnimationFrame(frame.current);
111
+ });
112
+ return [state, setRafState];
113
+ };
114
+ var useWindowScroll = function() {
115
+ var _a = useRafState(function() {
116
+ return {
117
+ x: isBrowser ? window.pageXOffset : 0,
118
+ y: isBrowser ? window.pageYOffset : 0
119
+ };
120
+ }), state = _a[0], setState = _a[1];
121
+ React.useEffect(function() {
122
+ var handler = function() {
123
+ setState(function(state2) {
124
+ var pageXOffset = window.pageXOffset, pageYOffset = window.pageYOffset;
125
+ return state2.x !== pageXOffset || state2.y !== pageYOffset ? {
126
+ x: pageXOffset,
127
+ y: pageYOffset
128
+ } : state2;
129
+ });
130
+ };
131
+ handler();
132
+ on(window, "scroll", handler, {
133
+ capture: false,
134
+ passive: true
135
+ });
136
+ return function() {
137
+ off(window, "scroll", handler);
138
+ };
139
+ }, []);
140
+ return state;
141
+ };
70
142
  const THEME = {
71
143
  VIEW_PORT: {
72
144
  SMALL: 320,
@@ -125,6 +197,126 @@ const useSmallViewPort = () => {
125
197
  isSmallMaxWidth
126
198
  };
127
199
  };
200
+ function resolveElements(elementOrSelector, scope, selectorCache) {
201
+ if (elementOrSelector == null) {
202
+ return [];
203
+ }
204
+ if (elementOrSelector instanceof EventTarget) {
205
+ return [elementOrSelector];
206
+ } else if (typeof elementOrSelector === "string") {
207
+ let root = document;
208
+ const elements = root.querySelectorAll(elementOrSelector);
209
+ return elements ? Array.from(elements) : [];
210
+ }
211
+ return Array.from(elementOrSelector).filter((element) => element != null);
212
+ }
213
+ const thresholds = {
214
+ some: 0,
215
+ all: 1
216
+ };
217
+ function inView(elementOrSelector, onStart, { root, margin: rootMargin, amount = "some" } = {}) {
218
+ const elements = resolveElements(elementOrSelector);
219
+ const activeIntersections = /* @__PURE__ */ new WeakMap();
220
+ const onIntersectionChange = (entries) => {
221
+ entries.forEach((entry) => {
222
+ const onEnd = activeIntersections.get(entry.target);
223
+ if (entry.isIntersecting === Boolean(onEnd))
224
+ return;
225
+ if (entry.isIntersecting) {
226
+ const newOnEnd = onStart(entry.target, entry);
227
+ if (typeof newOnEnd === "function") {
228
+ activeIntersections.set(entry.target, newOnEnd);
229
+ } else {
230
+ observer.unobserve(entry.target);
231
+ }
232
+ } else if (typeof onEnd === "function") {
233
+ onEnd(entry);
234
+ activeIntersections.delete(entry.target);
235
+ }
236
+ });
237
+ };
238
+ const observer = new IntersectionObserver(onIntersectionChange, {
239
+ root,
240
+ rootMargin,
241
+ threshold: typeof amount === "number" ? amount : thresholds[amount]
242
+ });
243
+ elements.forEach((element) => observer.observe(element));
244
+ return () => observer.disconnect();
245
+ }
246
+ function useInView(ref, { root, margin, amount, once = false, initial = false } = {}) {
247
+ const [isInView, setInView] = React.useState(initial);
248
+ React.useEffect(() => {
249
+ if (!ref.current || once && isInView)
250
+ return;
251
+ const onEnter = () => {
252
+ setInView(true);
253
+ return once ? void 0 : () => setInView(false);
254
+ };
255
+ const options = {
256
+ root: root && root.current || void 0,
257
+ margin,
258
+ amount
259
+ };
260
+ return inView(ref.current, onEnter, options);
261
+ }, [root, ref, margin, once, amount]);
262
+ return isInView;
263
+ }
264
+ const useAppearAnimation = ({
265
+ once = true,
266
+ margin = "-100px",
267
+ delay = 0.1,
268
+ direction = "up",
269
+ animationDistance = 50,
270
+ duration = 0.8,
271
+ ease = "easeOut"
272
+ } = {}) => {
273
+ const ref = React.useRef(null);
274
+ const isInView = useInView(ref, { once, margin });
275
+ const getInitialState2 = () => {
276
+ switch (direction) {
277
+ case "up":
278
+ return { opacity: 0, y: animationDistance };
279
+ case "down":
280
+ return { opacity: 0, y: -animationDistance };
281
+ case "left":
282
+ return { opacity: 0, x: animationDistance };
283
+ case "right":
284
+ return { opacity: 0, x: -animationDistance };
285
+ case "scale":
286
+ return { opacity: 0, scale: 0.8 };
287
+ case "fade":
288
+ return { opacity: 0 };
289
+ default:
290
+ return { opacity: 0, y: animationDistance };
291
+ }
292
+ };
293
+ const getAnimateState = () => {
294
+ switch (direction) {
295
+ case "up":
296
+ case "down":
297
+ return { opacity: 1, y: 0 };
298
+ case "left":
299
+ case "right":
300
+ return { opacity: 1, x: 0 };
301
+ case "scale":
302
+ return { opacity: 1, scale: 1 };
303
+ case "fade":
304
+ return { opacity: 1 };
305
+ default:
306
+ return { opacity: 1, y: 0 };
307
+ }
308
+ };
309
+ const motionProps = {
310
+ initial: getInitialState2(),
311
+ animate: isInView ? getAnimateState() : void 0,
312
+ transition: {
313
+ duration,
314
+ ease,
315
+ delay
316
+ }
317
+ };
318
+ return { ref, isInView, motionProps };
319
+ };
128
320
  function r(e) {
129
321
  var t, f, n = "";
130
322
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -3093,6 +3285,28 @@ const twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3093
3285
  function cn(...inputs) {
3094
3286
  return twMerge(clsx(inputs));
3095
3287
  }
3288
+ const HeaderWrapper = ({
3289
+ children,
3290
+ className,
3291
+ hideClassName,
3292
+ scrollPosition = 100,
3293
+ hideBackgroundOnScroll = true
3294
+ }) => {
3295
+ const { y } = useWindowScroll();
3296
+ const isClient = useIsClient();
3297
+ const isHiddenBackground = hideBackgroundOnScroll && y > scrollPosition && isClient;
3298
+ const headerClass = cn(
3299
+ "fixed z-30 w-full transition bg-background",
3300
+ className,
3301
+ {
3302
+ "bg-transparent": isHiddenBackground
3303
+ },
3304
+ {
3305
+ hideClassName: isHiddenBackground && hideClassName
3306
+ }
3307
+ );
3308
+ return /* @__PURE__ */ jsxRuntime.jsx("header", { className: headerClass, children });
3309
+ };
3096
3310
  const InfinityList = ({
3097
3311
  children,
3098
3312
  intersectionElementClassName,
@@ -3124,7 +3338,9 @@ const InfinityList = ({
3124
3338
  )
3125
3339
  ] });
3126
3340
  };
3341
+ exports.HeaderWrapper = HeaderWrapper;
3127
3342
  exports.InfinityList = InfinityList;
3343
+ exports.useAppearAnimation = useAppearAnimation;
3128
3344
  exports.useDisableScroll = useDisableScroll;
3129
3345
  exports.useExtraMediumViewPort = useExtraMediumViewPort;
3130
3346
  exports.useIsClient = useIsClient;
@@ -1,5 +1,5 @@
1
- import { useEffect, useState, useRef } from "react";
2
- import { jsxs, jsx } from "react/jsx-runtime";
1
+ import { useEffect, useState, useRef, useCallback } from "react";
2
+ import { jsx, jsxs } from "react/jsx-runtime";
3
3
  const useDisableScroll = (isDisableScroll) => {
4
4
  useEffect(() => {
5
5
  if (!isDisableScroll) return;
@@ -16,7 +16,28 @@ const useIsClient = () => {
16
16
  }, []);
17
17
  return isClient;
18
18
  };
19
+ function on(obj) {
20
+ var args = [];
21
+ for (var _i = 1; _i < arguments.length; _i++) {
22
+ args[_i - 1] = arguments[_i];
23
+ }
24
+ if (obj && obj.addEventListener) {
25
+ obj.addEventListener.apply(obj, args);
26
+ }
27
+ }
28
+ function off(obj) {
29
+ var args = [];
30
+ for (var _i = 1; _i < arguments.length; _i++) {
31
+ args[_i - 1] = arguments[_i];
32
+ }
33
+ if (obj && obj.removeEventListener) {
34
+ obj.removeEventListener.apply(obj, args);
35
+ }
36
+ }
19
37
  var isBrowser = typeof window !== "undefined";
38
+ var useEffectOnce = function(effect) {
39
+ useEffect(effect, []);
40
+ };
20
41
  var useIntersection = function(ref, options) {
21
42
  var _a = useState(null), intersectionObserverEntry = _a[0], setIntersectionObserverEntry = _a[1];
22
43
  useEffect(function() {
@@ -65,6 +86,57 @@ var useMedia = function(query, defaultState) {
65
86
  }, [query]);
66
87
  return state;
67
88
  };
89
+ var useUnmount = function(fn) {
90
+ var fnRef = useRef(fn);
91
+ fnRef.current = fn;
92
+ useEffectOnce(function() {
93
+ return function() {
94
+ return fnRef.current();
95
+ };
96
+ });
97
+ };
98
+ var useRafState = function(initialState) {
99
+ var frame = useRef(0);
100
+ var _a = useState(initialState), state = _a[0], setState = _a[1];
101
+ var setRafState = useCallback(function(value) {
102
+ cancelAnimationFrame(frame.current);
103
+ frame.current = requestAnimationFrame(function() {
104
+ setState(value);
105
+ });
106
+ }, []);
107
+ useUnmount(function() {
108
+ cancelAnimationFrame(frame.current);
109
+ });
110
+ return [state, setRafState];
111
+ };
112
+ var useWindowScroll = function() {
113
+ var _a = useRafState(function() {
114
+ return {
115
+ x: isBrowser ? window.pageXOffset : 0,
116
+ y: isBrowser ? window.pageYOffset : 0
117
+ };
118
+ }), state = _a[0], setState = _a[1];
119
+ useEffect(function() {
120
+ var handler = function() {
121
+ setState(function(state2) {
122
+ var pageXOffset = window.pageXOffset, pageYOffset = window.pageYOffset;
123
+ return state2.x !== pageXOffset || state2.y !== pageYOffset ? {
124
+ x: pageXOffset,
125
+ y: pageYOffset
126
+ } : state2;
127
+ });
128
+ };
129
+ handler();
130
+ on(window, "scroll", handler, {
131
+ capture: false,
132
+ passive: true
133
+ });
134
+ return function() {
135
+ off(window, "scroll", handler);
136
+ };
137
+ }, []);
138
+ return state;
139
+ };
68
140
  const THEME = {
69
141
  VIEW_PORT: {
70
142
  SMALL: 320,
@@ -123,6 +195,126 @@ const useSmallViewPort = () => {
123
195
  isSmallMaxWidth
124
196
  };
125
197
  };
198
+ function resolveElements(elementOrSelector, scope, selectorCache) {
199
+ if (elementOrSelector == null) {
200
+ return [];
201
+ }
202
+ if (elementOrSelector instanceof EventTarget) {
203
+ return [elementOrSelector];
204
+ } else if (typeof elementOrSelector === "string") {
205
+ let root = document;
206
+ const elements = root.querySelectorAll(elementOrSelector);
207
+ return elements ? Array.from(elements) : [];
208
+ }
209
+ return Array.from(elementOrSelector).filter((element) => element != null);
210
+ }
211
+ const thresholds = {
212
+ some: 0,
213
+ all: 1
214
+ };
215
+ function inView(elementOrSelector, onStart, { root, margin: rootMargin, amount = "some" } = {}) {
216
+ const elements = resolveElements(elementOrSelector);
217
+ const activeIntersections = /* @__PURE__ */ new WeakMap();
218
+ const onIntersectionChange = (entries) => {
219
+ entries.forEach((entry) => {
220
+ const onEnd = activeIntersections.get(entry.target);
221
+ if (entry.isIntersecting === Boolean(onEnd))
222
+ return;
223
+ if (entry.isIntersecting) {
224
+ const newOnEnd = onStart(entry.target, entry);
225
+ if (typeof newOnEnd === "function") {
226
+ activeIntersections.set(entry.target, newOnEnd);
227
+ } else {
228
+ observer.unobserve(entry.target);
229
+ }
230
+ } else if (typeof onEnd === "function") {
231
+ onEnd(entry);
232
+ activeIntersections.delete(entry.target);
233
+ }
234
+ });
235
+ };
236
+ const observer = new IntersectionObserver(onIntersectionChange, {
237
+ root,
238
+ rootMargin,
239
+ threshold: typeof amount === "number" ? amount : thresholds[amount]
240
+ });
241
+ elements.forEach((element) => observer.observe(element));
242
+ return () => observer.disconnect();
243
+ }
244
+ function useInView(ref, { root, margin, amount, once = false, initial = false } = {}) {
245
+ const [isInView, setInView] = useState(initial);
246
+ useEffect(() => {
247
+ if (!ref.current || once && isInView)
248
+ return;
249
+ const onEnter = () => {
250
+ setInView(true);
251
+ return once ? void 0 : () => setInView(false);
252
+ };
253
+ const options = {
254
+ root: root && root.current || void 0,
255
+ margin,
256
+ amount
257
+ };
258
+ return inView(ref.current, onEnter, options);
259
+ }, [root, ref, margin, once, amount]);
260
+ return isInView;
261
+ }
262
+ const useAppearAnimation = ({
263
+ once = true,
264
+ margin = "-100px",
265
+ delay = 0.1,
266
+ direction = "up",
267
+ animationDistance = 50,
268
+ duration = 0.8,
269
+ ease = "easeOut"
270
+ } = {}) => {
271
+ const ref = useRef(null);
272
+ const isInView = useInView(ref, { once, margin });
273
+ const getInitialState2 = () => {
274
+ switch (direction) {
275
+ case "up":
276
+ return { opacity: 0, y: animationDistance };
277
+ case "down":
278
+ return { opacity: 0, y: -animationDistance };
279
+ case "left":
280
+ return { opacity: 0, x: animationDistance };
281
+ case "right":
282
+ return { opacity: 0, x: -animationDistance };
283
+ case "scale":
284
+ return { opacity: 0, scale: 0.8 };
285
+ case "fade":
286
+ return { opacity: 0 };
287
+ default:
288
+ return { opacity: 0, y: animationDistance };
289
+ }
290
+ };
291
+ const getAnimateState = () => {
292
+ switch (direction) {
293
+ case "up":
294
+ case "down":
295
+ return { opacity: 1, y: 0 };
296
+ case "left":
297
+ case "right":
298
+ return { opacity: 1, x: 0 };
299
+ case "scale":
300
+ return { opacity: 1, scale: 1 };
301
+ case "fade":
302
+ return { opacity: 1 };
303
+ default:
304
+ return { opacity: 1, y: 0 };
305
+ }
306
+ };
307
+ const motionProps = {
308
+ initial: getInitialState2(),
309
+ animate: isInView ? getAnimateState() : void 0,
310
+ transition: {
311
+ duration,
312
+ ease,
313
+ delay
314
+ }
315
+ };
316
+ return { ref, isInView, motionProps };
317
+ };
126
318
  function r(e) {
127
319
  var t, f, n = "";
128
320
  if ("string" == typeof e || "number" == typeof e) n += e;
@@ -3091,6 +3283,28 @@ const twMerge = /* @__PURE__ */ createTailwindMerge(getDefaultConfig);
3091
3283
  function cn(...inputs) {
3092
3284
  return twMerge(clsx(inputs));
3093
3285
  }
3286
+ const HeaderWrapper = ({
3287
+ children,
3288
+ className,
3289
+ hideClassName,
3290
+ scrollPosition = 100,
3291
+ hideBackgroundOnScroll = true
3292
+ }) => {
3293
+ const { y } = useWindowScroll();
3294
+ const isClient = useIsClient();
3295
+ const isHiddenBackground = hideBackgroundOnScroll && y > scrollPosition && isClient;
3296
+ const headerClass = cn(
3297
+ "fixed z-30 w-full transition bg-background",
3298
+ className,
3299
+ {
3300
+ "bg-transparent": isHiddenBackground
3301
+ },
3302
+ {
3303
+ hideClassName: isHiddenBackground && hideClassName
3304
+ }
3305
+ );
3306
+ return /* @__PURE__ */ jsx("header", { className: headerClass, children });
3307
+ };
3094
3308
  const InfinityList = ({
3095
3309
  children,
3096
3310
  intersectionElementClassName,
@@ -3123,7 +3337,9 @@ const InfinityList = ({
3123
3337
  ] });
3124
3338
  };
3125
3339
  export {
3340
+ HeaderWrapper,
3126
3341
  InfinityList,
3342
+ useAppearAnimation,
3127
3343
  useDisableScroll,
3128
3344
  useExtraMediumViewPort,
3129
3345
  useIsClient,
@@ -0,0 +1,8 @@
1
+ import { MotionProps } from 'motion/react';
2
+ import { FC } from '../../../node_modules/react';
3
+ import { UseAppearAnimationProps } from '../hooks/use-appear-animation';
4
+ type AnimatedDivProps = React.DetailedHTMLProps<React.HTMLAttributes<HTMLDivElement>, HTMLDivElement> & MotionProps & {
5
+ animationConfig?: Partial<UseAppearAnimationProps>;
6
+ };
7
+ export declare const AnimatedDiv: FC<AnimatedDivProps>;
8
+ export {};
@@ -0,0 +1,10 @@
1
+ import { FC } from '../../../node_modules/react';
2
+ interface HeaderWrapperProps {
3
+ children: React.ReactNode;
4
+ className?: string;
5
+ hideClassName?: string;
6
+ scrollPosition?: number;
7
+ hideBackgroundOnScroll?: boolean;
8
+ }
9
+ export declare const HeaderWrapper: FC<HeaderWrapperProps>;
10
+ export {};
@@ -1 +1,2 @@
1
+ export * from './header-wrapper';
1
2
  export * from './infinity-list';
@@ -0,0 +1,53 @@
1
+ html,
2
+ body {
3
+ max-width: 100vw;
4
+ min-width: 280px;
5
+ margin: 0;
6
+ font-size: 16px;
7
+ font-weight: 400;
8
+ font-style: normal;
9
+ font-family: 'Inter', system-ui;
10
+ }
11
+
12
+ @media (max-width: 280px) {
13
+ body {
14
+ overflow-x: auto;
15
+ }
16
+ }
17
+
18
+ @layer base {
19
+ * {
20
+ @apply border-border outline-ring/50;
21
+ }
22
+ body {
23
+ @apply bg-background text-foreground;
24
+ }
25
+ }
26
+
27
+ .hyphens {
28
+ -webkit-hyphens: auto;
29
+ -webkit-hyphenate-limit-before: 3;
30
+ -webkit-hyphenate-limit-after: 3;
31
+ -webkit-hyphenate-limit-chars: 6 3 3;
32
+ -webkit-hyphenate-limit-lines: 2;
33
+ -webkit-hyphenate-limit-last: always;
34
+ -webkit-hyphenate-limit-zone: 8%;
35
+
36
+ -moz-hyphens: auto;
37
+ -moz-hyphenate-limit-chars: 6 3 3;
38
+ -moz-hyphenate-limit-lines: 2;
39
+ -moz-hyphenate-limit-last: always;
40
+ -moz-hyphenate-limit-zone: 8%;
41
+
42
+ -ms-hyphens: auto;
43
+ -ms-hyphenate-limit-chars: 6 3 3;
44
+ -ms-hyphenate-limit-lines: 2;
45
+ -ms-hyphenate-limit-last: always;
46
+ -ms-hyphenate-limit-zone: 8%;
47
+
48
+ hyphens: auto;
49
+ hyphenate-limit-chars: 6 3 3;
50
+ hyphenate-limit-lines: 2;
51
+ hyphenate-limit-last: always;
52
+ hyphenate-limit-zone: 8%;
53
+ }