@human-synthesis/norns-ui 0.0.7 → 0.0.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@human-synthesis/norns-ui",
3
- "version": "0.0.7",
3
+ "version": "0.0.9",
4
4
  "description": "UI library for the Norns ecosystem — Pug + Civet components on Tailwind v4.",
5
5
  "license": "MIT",
6
6
  "author": "Daniel Teodoroiu (https://humansynthesis.ai)",
@@ -55,6 +55,7 @@ export function presetUI() {
55
55
  // 0.0.4 — display layer
56
56
  Icon: c('Icon'),
57
57
  Card: c('Card'),
58
+ Window: c('Window'),
58
59
  Surface: c('Surface'),
59
60
  Banner: c('Banner'),
60
61
  Badge: c('Badge'),
@@ -32,7 +32,7 @@
32
32
  | {@render actions()}
33
33
  +if('!hideClose')
34
34
  button.dialog-close(type="button" aria-label="Close" onclick!="{onClose}")
35
- |
35
+ Icon(name="lucide:x" size="size-3.5")
36
36
 
37
37
  <script>
38
38
  import { cn } from '@human-synthesis/norns-ui/cn'
@@ -40,6 +40,7 @@
40
40
  import { scrollLock } from '@human-synthesis/norns-ui/behaviors/scrollLock.svelte.js'
41
41
  import { focusTrap } from '@human-synthesis/norns-ui/behaviors/focusTrap.svelte.js'
42
42
  import { escape } from '@human-synthesis/norns-ui/behaviors/escape.svelte.js'
43
+ import Icon from './Icon.n'
43
44
 
44
45
  {
45
46
  open = $bindable(false)
@@ -0,0 +1,44 @@
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
+ Icon(name="lucide:x" size="size-3.5")
11
+ section.norns-window-body(class!="{bodyClasses}")
12
+ | {@render children?.()}
13
+
14
+ <script>
15
+ import { cn } from '@human-synthesis/norns-ui/cn'
16
+ import Icon from './Icon.n'
17
+
18
+ // Layout-only window: chrome (header + close + custom actions) wrapping
19
+ // a body slot. Sizing is the caller's responsibility — pass dimensions
20
+ // via `class` (e.g. `class="w-[520px] h-[380px]"`) or compose inside a
21
+ // parent that constrains the box (a SvelteFlow node, a fixed panel,
22
+ // a flex child, etc).
23
+ //
24
+ // Header layout: title on the left (truncated), then a flex row of
25
+ // caller-provided action elements (via the `actions` snippet), then an
26
+ // optional `lucide:x` close button when `onClose` is supplied. The
27
+ // close button is rendered after the snippet so the snippet can
28
+ // position icons / chips alongside it.
29
+ //
30
+ // `hideHeader` removes the entire header bar (useful for windows that
31
+ // already have their own custom chrome but still want the rounded shell).
32
+ {
33
+ title = ''
34
+ hideHeader = false
35
+ onClose
36
+ actions
37
+ children
38
+ class: extra = ''
39
+ bodyClass = ''
40
+ } := $props()
41
+
42
+ classes := cn 'norns-window', extra
43
+ bodyClasses := cn 'norns-window-body', bodyClass
44
+ </script>
@@ -652,6 +652,70 @@
652
652
  box-shadow: var(--ui-focus-ring);
653
653
  }
654
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
+
655
719
  /* ============================================================ */
656
720
  /* Banner */
657
721
  /* ============================================================ */