@marianmeres/stuic 1.1.0 → 1.3.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.
@@ -1,3 +1,13 @@
1
+ <script context="module">export const appShellSetHtmlBodyHeight = () => {
2
+ const _set = (flag) => {
3
+ document.body.style.height = flag ? "100vh" : "auto";
4
+ document.body.style.overflow = flag ? "hidden" : "visible";
5
+ };
6
+ _set(true);
7
+ return () => _set(false);
8
+ };
9
+ </script>
10
+
1
11
  <script>import { createEventDispatcher } from "svelte";
2
12
  import { twMerge } from "tailwind-merge";
3
13
  const dispatch = createEventDispatcher();
@@ -193,9 +203,4 @@ Then update your global stylesheet with the following. This will disable overflo
193
203
  html and body tags to prevent duplicate scroll bars.
194
204
 
195
205
  html, body { @apply h-full overflow-hidden; }
196
- */
197
- :global(html),
198
- :global(body) {
199
- height: 100vh !important;
200
- overflow: hidden !important;
201
- }</style>
206
+ */</style>
@@ -1,4 +1,5 @@
1
1
  import { SvelteComponent } from "svelte";
2
+ export declare const appShellSetHtmlBodyHeight: () => (() => any);
2
3
  declare const __propDef: {
3
4
  props: {
4
5
  class?: string | undefined;
@@ -1,11 +1,11 @@
1
1
  <script context="module">import { createClog } from "@marianmeres/clog";
2
2
  import { createSwitchStore } from "@marianmeres/switch-store";
3
3
  import { createEventDispatcher } from "svelte";
4
- import { slide, fly } from "svelte/transition";
4
+ import { fly } from "svelte/transition";
5
5
  import { twMerge } from "tailwind-merge";
6
+ import { clickOutside } from "../../actions/click-outside.js";
6
7
  import { prefersReducedMotionStore } from "../../utils/prefers-reduced-motion.js";
7
8
  import Backdrop from "../Backdrop/Backdrop.svelte";
8
- import { clickOutside } from "../../actions/click-outside.js";
9
9
  export const createDrawerStore = (open = false) => createSwitchStore(open);
10
10
  </script>
11
11
 
@@ -36,8 +36,8 @@ const _presetsClsBackdrop = {
36
36
  const _presetsCls = {
37
37
  left: `w-full sm:w-[66vw] h-full`,
38
38
  right: `w-full sm:w-[66vw] h-full`,
39
- top: `w-full h-full sm:h-[66vh]`,
40
- bottom: `w-full h-full sm:h-[66vh]`
39
+ top: `w-full h-full sm:h-[66vh]`,
40
+ bottom: `w-full h-full sm:h-[66vh]`
41
41
  };
42
42
  $:
43
43
  _presetsAnim = {
@@ -52,12 +52,9 @@ $:
52
52
  dispatch("element", { drawer: el });
53
53
  </script>
54
54
 
55
- <!-- prettier-ignore -->
56
55
  {#if $drawer.isOpen}
57
56
  <Backdrop
58
- class={twMerge(`
59
- ${_presetsClsBackdrop[position] || ''} ${backdropClass}
60
- `.trim())}
57
+ class={twMerge(`${_presetsClsBackdrop[position] || ''} ${backdropClass}`)}
61
58
  on:escape
62
59
  on:click={(e) => dispatch('click_backdrop')}
63
60
  {fadeInDuration}
@@ -72,7 +69,7 @@ $:
72
69
  <div
73
70
  bind:this={el}
74
71
  on:click|stopPropagation
75
- aria-modal="true"
72
+ aria-modal="true"
76
73
  role="dialog"
77
74
  aria-labelledby={labelledby}
78
75
  aria-describedby={describedby}
@@ -80,7 +77,7 @@ $:
80
77
  duration: transitionEnabled ? transitionDuration : 0,
81
78
  ...(_presetsAnim[position] || {}),
82
79
  }}
83
- class={twMerge(`overflow-y-auto ${_presetsCls[position] || ''} ${_class}`.trim())}
80
+ class={twMerge(`overflow-y-auto ${_presetsCls[position] || ''} ${_class}`)}
84
81
  use:clickOutside={() => dispatch('click_outside')}
85
82
  >
86
83
  <slot />
@@ -0,0 +1,102 @@
1
+ <script>import { createClog } from "@marianmeres/clog";
2
+ import { createEventDispatcher } from "svelte";
3
+ import { get } from "svelte/store";
4
+ import { prefersReducedMotionStore } from "../../utils/prefers-reduced-motion.js";
5
+ import { windowSize } from "../../utils/window-size.js";
6
+ import { twMerge } from "tailwind-merge";
7
+ const clog = createClog("HoverExpandableWidth");
8
+ const dispatch = createEventDispatcher();
9
+ export let shadowOpacity = 0.8;
10
+ export let transitionDuration = 150;
11
+ export let targetWidth = 300;
12
+ let _class = "";
13
+ export { _class as class };
14
+ $:
15
+ _isExpanded = false;
16
+ let _isShrinking = false;
17
+ let _isExpanding = false;
18
+ let _todo;
19
+ let el;
20
+ const _maybeTodo = () => {
21
+ if (typeof _todo === "function")
22
+ _todo();
23
+ _todo = null;
24
+ };
25
+ const _expand = () => {
26
+ _todo = _expand;
27
+ if (_isExpanding || _isShrinking || _isExpanded)
28
+ return;
29
+ _isExpanded = true;
30
+ _isExpanding = true;
31
+ const box = el.getBoundingClientRect();
32
+ const w = get(windowSize);
33
+ const pos = {
34
+ top: box.top,
35
+ bottom: w.height - box.bottom,
36
+ left: box.left,
37
+ right: w.width - box.right
38
+ };
39
+ el.style.boxShadow = `8px 0 16px -8px rgb(0 0 0 / ${shadowOpacity})`;
40
+ el.style.zIndex = `1`;
41
+ el.style.top = `${pos.top}px`;
42
+ el.style.right = `${pos.right}px`;
43
+ el.style.bottom = `${pos.bottom}px`;
44
+ el.style.left = `${pos.left}px`;
45
+ el.style.width = "auto";
46
+ el.style.height = "auto";
47
+ setTimeout(
48
+ () => {
49
+ _isExpanding = false;
50
+ _maybeTodo();
51
+ },
52
+ transitionDuration + 1e3 / 60 * 3
53
+ // 3 x raf
54
+ );
55
+ requestAnimationFrame(() => {
56
+ el.style.position = `fixed`;
57
+ requestAnimationFrame(() => {
58
+ el.style.width = `${box.width}px`;
59
+ requestAnimationFrame(() => {
60
+ !$prefersReducedMotionStore && (el.style.transitionProperty = "all");
61
+ el.style.width = `${targetWidth}px`;
62
+ });
63
+ });
64
+ });
65
+ };
66
+ const _shrink = () => {
67
+ _todo = _shrink;
68
+ if (_isExpanding || _isShrinking || !_isExpanded)
69
+ return;
70
+ _isExpanded = false;
71
+ _isShrinking = true;
72
+ el.style.position = `static`;
73
+ el.style.zIndex = `auto`;
74
+ el.style.top = "auto";
75
+ el.style.right = "auto";
76
+ el.style.bottom = "auto";
77
+ el.style.left = "auto";
78
+ el.style.width = "100%";
79
+ el.style.height = "100%";
80
+ el.style.boxShadow = "none";
81
+ setTimeout(() => {
82
+ _isShrinking = false;
83
+ el.style.transitionProperty = "none";
84
+ _maybeTodo();
85
+ }, transitionDuration);
86
+ };
87
+ $:
88
+ dispatch("change", _isExpanded);
89
+ </script>
90
+
91
+ <!-- svelte-ignore a11y-click-events-have-key-events a11y-no-static-element-interactions -->
92
+ <div
93
+ bind:this={el}
94
+ on:mouseenter={_expand}
95
+ on:mouseleave={_shrink}
96
+ on:click
97
+ aria-expanded={_isExpanded}
98
+ class={twMerge(`${_class}`)}
99
+ style="width: 100%; height: 100%; transition-duration: {transitionDuration}ms;"
100
+ >
101
+ <slot isExpanded={_isExpanded} inTransition={_isExpanding || _isShrinking} />
102
+ </div>
@@ -0,0 +1,27 @@
1
+ import { SvelteComponent } from "svelte";
2
+ declare const __propDef: {
3
+ props: {
4
+ shadowOpacity?: number | undefined;
5
+ transitionDuration?: number | undefined;
6
+ targetWidth?: number | undefined;
7
+ class?: string | undefined;
8
+ };
9
+ events: {
10
+ click: MouseEvent;
11
+ change: CustomEvent<any>;
12
+ } & {
13
+ [evt: string]: CustomEvent<any>;
14
+ };
15
+ slots: {
16
+ default: {
17
+ isExpanded: boolean;
18
+ inTransition: boolean;
19
+ };
20
+ };
21
+ };
22
+ export type HoverExpandableWidthProps = typeof __propDef.props;
23
+ export type HoverExpandableWidthEvents = typeof __propDef.events;
24
+ export type HoverExpandableWidthSlots = typeof __propDef.slots;
25
+ export default class HoverExpandableWidth extends SvelteComponent<HoverExpandableWidthProps, HoverExpandableWidthEvents, HoverExpandableWidthSlots> {
26
+ }
27
+ export {};
package/dist/index.d.ts CHANGED
@@ -1,8 +1,10 @@
1
- export { default as AppShell } from './components/AppShell/AppShell.svelte';
1
+ export { default as AppShell, appShellSetHtmlBodyHeight, } from './components/AppShell/AppShell.svelte';
2
2
  export { default as Backdrop, BackdropConfig, } from './components/Backdrop/Backdrop.svelte';
3
3
  export { default as Button, ButtonConfig } from './components/Button/Button.svelte';
4
4
  export { default as SystemAwareColorScheme } from './components/ColorScheme/SystemAwareColorScheme.svelte';
5
5
  export { default as LocalColorScheme } from './components/ColorScheme/LocalColorScheme.svelte';
6
6
  export { ColorScheme } from './components/ColorScheme/color-scheme.js';
7
7
  export { default as Drawer, createDrawerStore } from './components/Drawer/Drawer.svelte';
8
+ export { default as HoverExpandableWidth } from './components/HoverExpandableWidth/HoverExpandableWidth.svelte';
8
9
  export { default as X } from './components/X/X.svelte';
10
+ export { windowSize, breakpoint } from './utils/window-size.js';
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  // Reexport your entry components here
2
2
  //
3
- export { default as AppShell } from './components/AppShell/AppShell.svelte';
3
+ export { default as AppShell, appShellSetHtmlBodyHeight, } from './components/AppShell/AppShell.svelte';
4
4
  //
5
5
  export { default as Backdrop, BackdropConfig, } from './components/Backdrop/Backdrop.svelte';
6
6
  //
@@ -12,4 +12,8 @@ export { ColorScheme } from './components/ColorScheme/color-scheme.js';
12
12
  //
13
13
  export { default as Drawer, createDrawerStore } from './components/Drawer/Drawer.svelte';
14
14
  //
15
+ export { default as HoverExpandableWidth } from './components/HoverExpandableWidth/HoverExpandableWidth.svelte';
16
+ //
15
17
  export { default as X } from './components/X/X.svelte';
18
+ //
19
+ export { windowSize, breakpoint } from './utils/window-size.js';
@@ -0,0 +1,14 @@
1
+ /// <reference types="svelte" />
2
+ export declare const windowSize: {
3
+ touch: () => void;
4
+ subscribe(this: void, run: import("svelte/store").Subscriber<{
5
+ width: number;
6
+ height: number;
7
+ scale: number;
8
+ }>, invalidate?: import("svelte/store").Invalidator<{
9
+ width: number;
10
+ height: number;
11
+ scale: number;
12
+ }> | undefined): import("svelte/store").Unsubscriber;
13
+ };
14
+ export declare const breakpoint: import("svelte/store").Readable<string | null>;
@@ -0,0 +1,30 @@
1
+ import { derived, writable } from 'svelte/store';
2
+ const getWindowSize = () => {
3
+ const { width, height, scale } = window?.visualViewport || {
4
+ width: 0,
5
+ height: 0,
6
+ scale: 1,
7
+ };
8
+ return { width, height, scale };
9
+ };
10
+ let _trigger = writable(0);
11
+ export const windowSize = {
12
+ ...derived([_trigger], ([_]) => getWindowSize()),
13
+ touch: () => _trigger.set(Date.now()),
14
+ };
15
+ // init now!
16
+ windowSize.touch();
17
+ // intentionally not debounced
18
+ window?.visualViewport?.addEventListener('resize', windowSize.touch);
19
+ window?.visualViewport?.addEventListener('scroll', windowSize.touch);
20
+ // https://tailwindcss.com/docs/responsive-design
21
+ export const breakpoint = derived([windowSize], ([{ width: w }]) => {
22
+ const list = [
23
+ ['sm', 640],
24
+ ['md', 768],
25
+ ['lg', 1024],
26
+ ['xl', 1280],
27
+ ['2xl', 1536],
28
+ ];
29
+ return list.reduce((m, [k, v]) => (w && w >= v ? k : m), null);
30
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@marianmeres/stuic",
3
- "version": "1.1.0",
3
+ "version": "1.3.0",
4
4
  "scripts": {
5
5
  "dev": "vite dev",
6
6
  "build": "vite build && npm run package",