@human-synthesis/norns-ui 0.0.5 → 0.0.7
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 +32 -20
- package/package.json +7 -3
- package/src/auto-import.js +1 -4
- package/src/components/Accordion.n +24 -23
- package/src/components/Autocomplete.n +108 -33
- package/src/components/Collapsible.n +8 -11
- package/src/components/ContextMenu.n +55 -36
- package/src/components/DatePicker.n +19 -31
- package/src/components/DateRangePicker.n +17 -29
- package/src/components/Dialog.n +35 -22
- package/src/components/Dropdown.n +54 -23
- package/src/components/MultiSelect.n +138 -36
- package/src/components/Popover.n +30 -15
- package/src/components/ScrollArea.n +9 -20
- package/src/components/Sheet.n +36 -22
- package/src/components/Tabs.n +39 -13
- package/src/components/TimePicker.n +52 -65
- package/src/components/ToggleButton.n +18 -12
- package/src/components/ToggleButtonGroup.n +31 -11
- package/src/components/Tooltip.n +52 -19
- package/src/index.js +1 -4
- package/src/lib/behaviors/clickOutside.svelte.js +54 -0
- package/src/lib/behaviors/escape.svelte.js +36 -0
- package/src/lib/behaviors/floating.svelte.js +137 -0
- package/src/lib/behaviors/focusTrap.svelte.js +80 -0
- package/src/lib/behaviors/index.js +14 -0
- package/src/lib/behaviors/portal.svelte.js +32 -0
- package/src/lib/behaviors/rovingTabindex.svelte.js +76 -0
- package/src/lib/behaviors/scrollLock.svelte.js +56 -0
- package/src/styles/atoms.css +628 -920
- package/src/styles/tokens.css +33 -0
- package/src/types/Collapsible.d.ts +1 -0
- package/src/types/ContextMenu.d.ts +6 -1
- package/src/types/DatePicker.d.ts +7 -2
- package/src/types/DateRangePicker.d.ts +3 -3
- package/src/types/Dialog.d.ts +4 -0
- package/src/types/Dropdown.d.ts +2 -1
- package/src/types/MultiSelect.d.ts +3 -0
- package/src/types/ScrollArea.d.ts +1 -1
- package/src/types/Sheet.d.ts +3 -0
- package/src/types/Tabs.d.ts +2 -0
- package/src/types/ToggleButton.d.ts +2 -1
- package/src/types/ToggleButtonGroup.d.ts +2 -1
- package/src/types/Tooltip.d.ts +3 -0
- package/src/components/Drawer.n +0 -49
- package/src/components/PreviewCard.n +0 -30
- package/src/components/RichTooltip.n +0 -33
- package/src/types/Drawer.d.ts +0 -18
- package/src/types/PreviewCard.d.ts +0 -16
- package/src/types/RichTooltip.d.ts +0 -16
package/src/styles/tokens.css
CHANGED
|
@@ -145,6 +145,31 @@
|
|
|
145
145
|
--ui-h-sm: 1.75rem; /* 28px */
|
|
146
146
|
--ui-h-md: 2.25rem; /* 36px */
|
|
147
147
|
--ui-h-lg: 2.75rem; /* 44px */
|
|
148
|
+
|
|
149
|
+
/* Square icon-button sizes (close buttons, nav arrows, chevron triggers).
|
|
150
|
+
* Distinct from full button heights above. */
|
|
151
|
+
--ui-icon-btn-sm: 1.5rem; /* 24px */
|
|
152
|
+
--ui-icon-btn-md: 1.75rem; /* 28px */
|
|
153
|
+
--ui-icon-btn-lg: 2.25rem; /* 36px */
|
|
154
|
+
|
|
155
|
+
/* Motion timings — shared so animations feel coordinated. */
|
|
156
|
+
--ui-motion-fast: 150ms;
|
|
157
|
+
--ui-motion-med: 200ms;
|
|
158
|
+
--ui-motion-slow: 300ms;
|
|
159
|
+
--ui-motion-ease: cubic-bezier(0.2, 0, 0, 1);
|
|
160
|
+
|
|
161
|
+
/* Elevation — the only shadow vocabulary in the library.
|
|
162
|
+
* elev-1: subtle (cards, hover-lifts)
|
|
163
|
+
* elev-2: floating menus, popovers, tooltips
|
|
164
|
+
* elev-3: dialogs, sheets
|
|
165
|
+
*/
|
|
166
|
+
--ui-elev-1: 0 1px 2px oklch(0% 0 0 / 0.06), 0 1px 3px oklch(0% 0 0 / 0.04);
|
|
167
|
+
--ui-elev-2: 0 4px 12px -2px oklch(0% 0 0 / 0.08), 0 2px 4px -1px oklch(0% 0 0 / 0.04);
|
|
168
|
+
--ui-elev-3: 0 16px 32px -8px oklch(0% 0 0 / 0.18), 0 4px 8px -4px oklch(0% 0 0 / 0.06);
|
|
169
|
+
|
|
170
|
+
/* Single canonical focus indicator. 2px halo on the surface color + 2px
|
|
171
|
+
* ring color outside it, so the ring stays visible on any background. */
|
|
172
|
+
--ui-focus-ring: 0 0 0 2px var(--color-bg), 0 0 0 4px var(--color-ring);
|
|
148
173
|
}
|
|
149
174
|
|
|
150
175
|
/* === Dark theme ===
|
|
@@ -173,6 +198,14 @@
|
|
|
173
198
|
/* Ring brightens slightly so it stays visible on dark surfaces */
|
|
174
199
|
--color-ring: var(--color-primary-400);
|
|
175
200
|
|
|
201
|
+
/* Dark-mode elevation — true-black shadow on dark bg disappears, so we
|
|
202
|
+
* lean on darker shadow + the existing border to convey depth. */
|
|
203
|
+
--ui-elev-1: 0 1px 2px oklch(0% 0 0 / 0.4);
|
|
204
|
+
--ui-elev-2: 0 4px 12px -2px oklch(0% 0 0 / 0.5), 0 2px 4px -1px oklch(0% 0 0 / 0.3);
|
|
205
|
+
--ui-elev-3: 0 16px 32px -8px oklch(0% 0 0 / 0.6), 0 4px 8px -4px oklch(0% 0 0 / 0.4);
|
|
206
|
+
|
|
207
|
+
--ui-focus-ring: 0 0 0 2px var(--color-bg-elevated), 0 0 0 4px var(--color-ring);
|
|
208
|
+
|
|
176
209
|
/* Feedback — flip to deep tinted bg + light fg */
|
|
177
210
|
--color-success-bg: oklch(28% 0.05 152);
|
|
178
211
|
--color-success-fg: var(--color-success-200);
|
|
@@ -5,7 +5,12 @@ export type ContextMenuItem = {
|
|
|
5
5
|
icon?: string;
|
|
6
6
|
separator?: boolean;
|
|
7
7
|
disabled?: boolean;
|
|
8
|
-
onSelect?: (
|
|
8
|
+
onSelect?: () => void;
|
|
9
|
+
/**
|
|
10
|
+
* NOTE: nested submenus are not supported in 0.0.6+ (the property is
|
|
11
|
+
* accepted but children are ignored). Re-introduce when the upstream
|
|
12
|
+
* design needs them.
|
|
13
|
+
*/
|
|
9
14
|
children?: ContextMenuItem[];
|
|
10
15
|
};
|
|
11
16
|
|
|
@@ -3,11 +3,16 @@ import type { Component } from 'svelte';
|
|
|
3
3
|
export type DatePickerProps = {
|
|
4
4
|
/** ISO date string (YYYY-MM-DD). Bindable. */
|
|
5
5
|
value?: string;
|
|
6
|
+
/** Whether the popover is open. Bindable. */
|
|
7
|
+
open?: boolean;
|
|
6
8
|
min?: string;
|
|
7
9
|
max?: string;
|
|
10
|
+
placeholder?: string;
|
|
8
11
|
disabled?: boolean;
|
|
9
|
-
|
|
10
|
-
|
|
12
|
+
/** Close the popover automatically once a date is picked (default true). */
|
|
13
|
+
closeOnSelect?: boolean;
|
|
14
|
+
/** aria-label override; defaults to "Pick a date". */
|
|
15
|
+
label?: string;
|
|
11
16
|
name?: string;
|
|
12
17
|
id?: string;
|
|
13
18
|
error?: boolean;
|
|
@@ -4,12 +4,12 @@ export type DateRange = { start: string; end: string };
|
|
|
4
4
|
|
|
5
5
|
export type DateRangePickerProps = {
|
|
6
6
|
value?: DateRange;
|
|
7
|
+
/** Whether the popover is open. Bindable. */
|
|
8
|
+
open?: boolean;
|
|
7
9
|
min?: string;
|
|
8
10
|
max?: string;
|
|
11
|
+
placeholder?: string;
|
|
9
12
|
disabled?: boolean;
|
|
10
|
-
required?: boolean;
|
|
11
|
-
/** Form name. The two inputs serialize as `${name}_start` and `${name}_end`. */
|
|
12
|
-
name?: string;
|
|
13
13
|
class?: string;
|
|
14
14
|
};
|
|
15
15
|
|
package/src/types/Dialog.d.ts
CHANGED
|
@@ -5,6 +5,10 @@ export type DialogProps = {
|
|
|
5
5
|
title?: string;
|
|
6
6
|
description?: string;
|
|
7
7
|
hideClose?: boolean;
|
|
8
|
+
/** Close on overlay click and Escape. Default true. */
|
|
9
|
+
dismissable?: boolean;
|
|
10
|
+
/** Used as `aria-label` on the dialog when no `title` is provided. */
|
|
11
|
+
ariaLabel?: string;
|
|
8
12
|
trigger?: Snippet;
|
|
9
13
|
actions?: Snippet;
|
|
10
14
|
children?: Snippet;
|
package/src/types/Dropdown.d.ts
CHANGED
|
@@ -2,9 +2,10 @@ import type { Component, Snippet } from 'svelte';
|
|
|
2
2
|
|
|
3
3
|
export type DropdownItem = {
|
|
4
4
|
label?: string;
|
|
5
|
+
icon?: string;
|
|
5
6
|
separator?: boolean;
|
|
6
7
|
disabled?: boolean;
|
|
7
|
-
onSelect?: (
|
|
8
|
+
onSelect?: () => void;
|
|
8
9
|
};
|
|
9
10
|
|
|
10
11
|
export type DropdownProps = {
|
package/src/types/Sheet.d.ts
CHANGED
|
@@ -4,10 +4,13 @@ export type SheetSide = 'top' | 'right' | 'bottom' | 'left';
|
|
|
4
4
|
|
|
5
5
|
export type SheetProps = {
|
|
6
6
|
open?: boolean;
|
|
7
|
+
/** `'left'` was previously the default for the now-removed `<Drawer>`. */
|
|
7
8
|
side?: SheetSide;
|
|
8
9
|
title?: string;
|
|
9
10
|
description?: string;
|
|
10
11
|
hideClose?: boolean;
|
|
12
|
+
dismissable?: boolean;
|
|
13
|
+
ariaLabel?: string;
|
|
11
14
|
trigger?: Snippet;
|
|
12
15
|
actions?: Snippet;
|
|
13
16
|
children?: Snippet;
|
package/src/types/Tabs.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ export type ToggleButtonProps = {
|
|
|
4
4
|
pressed?: boolean;
|
|
5
5
|
disabled?: boolean;
|
|
6
6
|
icon?: string;
|
|
7
|
-
variant
|
|
7
|
+
/** Any `.btn-*` variant. The toggle visual state is controlled by `data-pressed`. */
|
|
8
|
+
variant?: 'primary' | 'secondary' | 'ghost' | 'danger' | 'link';
|
|
8
9
|
size?: 'sm' | 'md' | 'lg';
|
|
9
10
|
onpressedchange?: (pressed: boolean) => void;
|
|
10
11
|
children?: Snippet;
|
|
@@ -10,9 +10,10 @@ export type ToggleGroupItem = {
|
|
|
10
10
|
|
|
11
11
|
export type ToggleButtonGroupProps = {
|
|
12
12
|
items?: ToggleGroupItem[];
|
|
13
|
-
value?: string | string[];
|
|
13
|
+
value?: string | string[] | undefined;
|
|
14
14
|
multiple?: boolean;
|
|
15
15
|
disabled?: boolean;
|
|
16
|
+
label?: string;
|
|
16
17
|
class?: string;
|
|
17
18
|
};
|
|
18
19
|
|
package/src/types/Tooltip.d.ts
CHANGED
|
@@ -3,8 +3,11 @@ import type { Component, Snippet } from 'svelte';
|
|
|
3
3
|
export type TooltipProps = {
|
|
4
4
|
content?: string;
|
|
5
5
|
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
6
|
+
align?: 'start' | 'center' | 'end';
|
|
6
7
|
sideOffset?: number;
|
|
7
8
|
delay?: number;
|
|
9
|
+
/** Wider, surface-elevated styling for tooltips with markup/multiline content. */
|
|
10
|
+
rich?: boolean;
|
|
8
11
|
trigger?: Snippet;
|
|
9
12
|
children?: Snippet;
|
|
10
13
|
triggerClass?: string;
|
package/src/components/Drawer.n
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
DialogRoot(bind:open)
|
|
2
|
-
+if('trigger')
|
|
3
|
-
DialogTrigger(class!="{triggerClass ?? undefined}")
|
|
4
|
-
| {@render trigger()}
|
|
5
|
-
DialogPortal
|
|
6
|
-
DialogOverlay.dialog-overlay
|
|
7
|
-
DialogContent(class!="{contentClasses}" data-side!="{side}")
|
|
8
|
-
+if('title')
|
|
9
|
-
DialogTitle.dialog-title
|
|
10
|
-
| {title}
|
|
11
|
-
+if('description')
|
|
12
|
-
DialogDescription.dialog-description
|
|
13
|
-
| {description}
|
|
14
|
-
+if('children')
|
|
15
|
-
.sheet-body
|
|
16
|
-
| {@render children()}
|
|
17
|
-
+if('!hideClose')
|
|
18
|
-
DialogClose.dialog-close(aria-label="Close")
|
|
19
|
-
| ✕
|
|
20
|
-
|
|
21
|
-
<script>
|
|
22
|
-
import { Dialog } from 'bits-ui'
|
|
23
|
-
import { cn } from '@human-synthesis/norns-ui/cn'
|
|
24
|
-
|
|
25
|
-
{
|
|
26
|
-
Root: DialogRoot
|
|
27
|
-
Trigger: DialogTrigger
|
|
28
|
-
Portal: DialogPortal
|
|
29
|
-
Overlay: DialogOverlay
|
|
30
|
-
Content: DialogContent
|
|
31
|
-
Title: DialogTitle
|
|
32
|
-
Description: DialogDescription
|
|
33
|
-
Close: DialogClose
|
|
34
|
-
} := Dialog
|
|
35
|
-
|
|
36
|
-
{
|
|
37
|
-
open = $bindable(false)
|
|
38
|
-
side = 'left'
|
|
39
|
-
title
|
|
40
|
-
description
|
|
41
|
-
hideClose = false
|
|
42
|
-
trigger
|
|
43
|
-
children
|
|
44
|
-
triggerClass
|
|
45
|
-
class: extra = ''
|
|
46
|
-
} .= $props()
|
|
47
|
-
|
|
48
|
-
contentClasses := cn 'sheet-content', `sheet-${side}`, extra
|
|
49
|
-
</script>
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
LinkPreviewRoot(openDelay!="{openDelay}")
|
|
2
|
-
LinkPreviewTrigger(href!="{href}" class!="{triggerClass ?? ''}")
|
|
3
|
-
| {@render trigger?.()}
|
|
4
|
-
LinkPreviewContent.popover-content(side!="{side}" align!="{align}" sideOffset!="{sideOffset}" class!="{contentClass}")
|
|
5
|
-
| {@render children?.()}
|
|
6
|
-
|
|
7
|
-
<script>
|
|
8
|
-
import { LinkPreview } from 'bits-ui'
|
|
9
|
-
import { cn } from '@human-synthesis/norns-ui/cn'
|
|
10
|
-
|
|
11
|
-
{
|
|
12
|
-
Root: LinkPreviewRoot
|
|
13
|
-
Trigger: LinkPreviewTrigger
|
|
14
|
-
Content: LinkPreviewContent
|
|
15
|
-
} := LinkPreview
|
|
16
|
-
|
|
17
|
-
{
|
|
18
|
-
href
|
|
19
|
-
side = 'top'
|
|
20
|
-
align = 'center'
|
|
21
|
-
sideOffset = 8
|
|
22
|
-
openDelay = 700
|
|
23
|
-
trigger
|
|
24
|
-
children
|
|
25
|
-
triggerClass
|
|
26
|
-
class: extra = ''
|
|
27
|
-
} := $props()
|
|
28
|
-
|
|
29
|
-
contentClass := cn 'w-72 p-3', extra
|
|
30
|
-
</script>
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
TooltipProvider(delayDuration!="{openDelay}")
|
|
2
|
-
TooltipRoot
|
|
3
|
-
TooltipTrigger(class!="{triggerClass ?? ''}")
|
|
4
|
-
| {@render trigger?.()}
|
|
5
|
-
TooltipPortal
|
|
6
|
-
TooltipContent.popover-content(side!="{side}" align!="{align}" sideOffset!="{sideOffset}" class!="{contentClass}")
|
|
7
|
-
| {@render children?.()}
|
|
8
|
-
|
|
9
|
-
<script>
|
|
10
|
-
import { Tooltip } from 'bits-ui'
|
|
11
|
-
import { cn } from '@human-synthesis/norns-ui/cn'
|
|
12
|
-
|
|
13
|
-
{
|
|
14
|
-
Provider: TooltipProvider
|
|
15
|
-
Root: TooltipRoot
|
|
16
|
-
Trigger: TooltipTrigger
|
|
17
|
-
Portal: TooltipPortal
|
|
18
|
-
Content: TooltipContent
|
|
19
|
-
} := Tooltip
|
|
20
|
-
|
|
21
|
-
{
|
|
22
|
-
side = 'top'
|
|
23
|
-
align = 'center'
|
|
24
|
-
sideOffset = 6
|
|
25
|
-
openDelay = 300
|
|
26
|
-
trigger
|
|
27
|
-
children
|
|
28
|
-
triggerClass
|
|
29
|
-
class: extra = ''
|
|
30
|
-
} := $props()
|
|
31
|
-
|
|
32
|
-
contentClass := cn 'max-w-xs p-3 text-sm', extra
|
|
33
|
-
</script>
|
package/src/types/Drawer.d.ts
DELETED
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import type { Component, Snippet } from 'svelte';
|
|
2
|
-
|
|
3
|
-
export type DrawerSide = 'left' | 'right';
|
|
4
|
-
|
|
5
|
-
export type DrawerProps = {
|
|
6
|
-
open?: boolean;
|
|
7
|
-
side?: DrawerSide;
|
|
8
|
-
title?: string;
|
|
9
|
-
description?: string;
|
|
10
|
-
hideClose?: boolean;
|
|
11
|
-
trigger?: Snippet;
|
|
12
|
-
children?: Snippet;
|
|
13
|
-
triggerClass?: string;
|
|
14
|
-
class?: string;
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
declare const Drawer: Component<DrawerProps>;
|
|
18
|
-
export default Drawer;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Component, Snippet } from 'svelte';
|
|
2
|
-
|
|
3
|
-
export type PreviewCardProps = {
|
|
4
|
-
href?: string;
|
|
5
|
-
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
6
|
-
align?: 'start' | 'center' | 'end';
|
|
7
|
-
sideOffset?: number;
|
|
8
|
-
openDelay?: number;
|
|
9
|
-
trigger?: Snippet;
|
|
10
|
-
children?: Snippet;
|
|
11
|
-
triggerClass?: string;
|
|
12
|
-
class?: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
declare const PreviewCard: Component<PreviewCardProps>;
|
|
16
|
-
export default PreviewCard;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import type { Component, Snippet } from 'svelte';
|
|
2
|
-
|
|
3
|
-
export type RichTooltipProps = {
|
|
4
|
-
side?: 'top' | 'right' | 'bottom' | 'left';
|
|
5
|
-
align?: 'start' | 'center' | 'end';
|
|
6
|
-
sideOffset?: number;
|
|
7
|
-
openDelay?: number;
|
|
8
|
-
closeDelay?: number;
|
|
9
|
-
trigger?: Snippet;
|
|
10
|
-
children?: Snippet;
|
|
11
|
-
triggerClass?: string;
|
|
12
|
-
class?: string;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
declare const RichTooltip: Component<RichTooltipProps>;
|
|
16
|
-
export default RichTooltip;
|