@human-synthesis/norns-ui 0.0.6 → 0.0.8
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/package.json +1 -1
- package/src/auto-import.js +1 -0
- package/src/components/Window.n +43 -0
- package/src/styles/atoms.css +70 -1
package/package.json
CHANGED
package/src/auto-import.js
CHANGED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
.norns-window(class!="{classes}")
|
|
2
|
+
+if('!hideHeader')
|
|
3
|
+
header.norns-window-header
|
|
4
|
+
.norns-window-title.truncate {title}
|
|
5
|
+
.norns-window-actions
|
|
6
|
+
+if('actions')
|
|
7
|
+
| {@render actions()}
|
|
8
|
+
+if('onClose')
|
|
9
|
+
button.norns-window-close(type="button" aria-label="Close" onclick!="{onClose}")
|
|
10
|
+
| ✕
|
|
11
|
+
section.norns-window-body(class!="{bodyClasses}")
|
|
12
|
+
| {@render children?.()}
|
|
13
|
+
|
|
14
|
+
<script>
|
|
15
|
+
import { cn } from '@human-synthesis/norns-ui/cn'
|
|
16
|
+
|
|
17
|
+
// Layout-only window: chrome (header + close + custom actions) wrapping
|
|
18
|
+
// a body slot. Sizing is the caller's responsibility — pass dimensions
|
|
19
|
+
// via `class` (e.g. `class="w-[520px] h-[380px]"`) or compose inside a
|
|
20
|
+
// parent that constrains the box (a SvelteFlow node, a fixed panel,
|
|
21
|
+
// a flex child, etc).
|
|
22
|
+
//
|
|
23
|
+
// Header layout: title on the left (truncated), then a flex row of
|
|
24
|
+
// caller-provided action elements (via the `actions` snippet), then an
|
|
25
|
+
// optional `✕` close button when `onClose` is supplied. The close button
|
|
26
|
+
// is rendered after the snippet so the snippet can position icons / chips
|
|
27
|
+
// alongside it.
|
|
28
|
+
//
|
|
29
|
+
// `hideHeader` removes the entire header bar (useful for windows that
|
|
30
|
+
// already have their own custom chrome but still want the rounded shell).
|
|
31
|
+
{
|
|
32
|
+
title = ''
|
|
33
|
+
hideHeader = false
|
|
34
|
+
onClose
|
|
35
|
+
actions
|
|
36
|
+
children
|
|
37
|
+
class: extra = ''
|
|
38
|
+
bodyClass = ''
|
|
39
|
+
} := $props()
|
|
40
|
+
|
|
41
|
+
classes := cn 'norns-window', extra
|
|
42
|
+
bodyClasses := cn 'norns-window-body', bodyClass
|
|
43
|
+
</script>
|
package/src/styles/atoms.css
CHANGED
|
@@ -32,11 +32,16 @@
|
|
|
32
32
|
background-color: var(--color-bg);
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
+
/* Respect prefers-reduced-motion without nuking decorative animations
|
|
36
|
+
* entirely: cap iterations to 1 (so infinite loops like the shiny
|
|
37
|
+
* sweep, sparkle, gradient shift play once and stop instead of
|
|
38
|
+
* looping), and shrink incidental transitions. Finite animations
|
|
39
|
+
* (ripple, copy-pop, toast-in, banner-in) keep their natural duration
|
|
40
|
+
* so users still see the state change they signal. */
|
|
35
41
|
@media (prefers-reduced-motion: reduce) {
|
|
36
42
|
*,
|
|
37
43
|
*::before,
|
|
38
44
|
*::after {
|
|
39
|
-
animation-duration: 0.01ms !important;
|
|
40
45
|
animation-iteration-count: 1 !important;
|
|
41
46
|
transition-duration: 0.01ms !important;
|
|
42
47
|
scroll-behavior: auto !important;
|
|
@@ -647,6 +652,70 @@
|
|
|
647
652
|
box-shadow: var(--ui-focus-ring);
|
|
648
653
|
}
|
|
649
654
|
|
|
655
|
+
/* ============================================================ */
|
|
656
|
+
/* Window */
|
|
657
|
+
/* ============================================================ */
|
|
658
|
+
.norns-window {
|
|
659
|
+
display: flex;
|
|
660
|
+
flex-direction: column;
|
|
661
|
+
background-color: var(--color-bg-elevated);
|
|
662
|
+
color: var(--color-fg);
|
|
663
|
+
border: 1px solid var(--color-border);
|
|
664
|
+
border-radius: var(--ui-radius-lg);
|
|
665
|
+
overflow: hidden;
|
|
666
|
+
box-shadow: var(--ui-elev-1, 0 1px 2px rgb(0 0 0 / 0.04));
|
|
667
|
+
}
|
|
668
|
+
.norns-window-header {
|
|
669
|
+
flex-shrink: 0;
|
|
670
|
+
display: flex;
|
|
671
|
+
align-items: center;
|
|
672
|
+
justify-content: space-between;
|
|
673
|
+
gap: 0.5rem;
|
|
674
|
+
padding: 0.4rem 0.625rem;
|
|
675
|
+
border-bottom: 1px solid var(--color-border);
|
|
676
|
+
background-color: var(--color-bg-subtle);
|
|
677
|
+
user-select: none;
|
|
678
|
+
cursor: move;
|
|
679
|
+
}
|
|
680
|
+
.norns-window-title {
|
|
681
|
+
flex: 1;
|
|
682
|
+
min-width: 0;
|
|
683
|
+
font-size: 0.85rem;
|
|
684
|
+
font-weight: 600;
|
|
685
|
+
color: var(--color-fg);
|
|
686
|
+
}
|
|
687
|
+
.norns-window-actions {
|
|
688
|
+
display: flex;
|
|
689
|
+
align-items: center;
|
|
690
|
+
gap: 0.25rem;
|
|
691
|
+
flex-shrink: 0;
|
|
692
|
+
}
|
|
693
|
+
.norns-window-close {
|
|
694
|
+
display: inline-flex;
|
|
695
|
+
align-items: center;
|
|
696
|
+
justify-content: center;
|
|
697
|
+
width: 1.25rem;
|
|
698
|
+
height: 1.25rem;
|
|
699
|
+
border-radius: var(--ui-radius-sm);
|
|
700
|
+
background: transparent;
|
|
701
|
+
color: var(--color-fg-muted);
|
|
702
|
+
border: 0;
|
|
703
|
+
cursor: pointer;
|
|
704
|
+
font-size: 0.85rem;
|
|
705
|
+
line-height: 1;
|
|
706
|
+
padding: 0;
|
|
707
|
+
}
|
|
708
|
+
.norns-window-close:hover {
|
|
709
|
+
background: var(--color-bg-muted);
|
|
710
|
+
color: var(--color-fg);
|
|
711
|
+
}
|
|
712
|
+
.norns-window-body {
|
|
713
|
+
flex: 1;
|
|
714
|
+
min-height: 0;
|
|
715
|
+
overflow: auto;
|
|
716
|
+
background-color: var(--color-bg);
|
|
717
|
+
}
|
|
718
|
+
|
|
650
719
|
/* ============================================================ */
|
|
651
720
|
/* Banner */
|
|
652
721
|
/* ============================================================ */
|