noph-ui 0.4.12 → 0.6.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.
package/README.md CHANGED
@@ -56,22 +56,24 @@ Beta (No breaking changes expected)
56
56
 
57
57
  - Buttons
58
58
  - Cards
59
- - Checkbox
59
+ - Checkbox (Docs missing)
60
60
  - Divider
61
61
  - Icon buttons
62
+ - Lists (Docs missing)
62
63
  - Progress indicators
64
+ - Radio (Docs missing)
63
65
  - Ripple
64
66
  - Segmented buttons
65
67
  - Snackbar
66
- - Radio
67
- - Text fields
68
+ - Text fields (Textarea Docs missing)
68
69
 
69
70
  In progress (Breaking changes expected)
70
71
 
71
72
  - Chips
72
- - Lists
73
- - Menus
74
- - Tooltips
73
+ - Dialogs (Fullscreen + Docs missing)
74
+ - Menus (Positioning missing + Docs missing)
75
+ - Navigation Rail (Badge is missing)
76
+ - Tooltips (Positioning missing)
75
77
 
76
78
  Pending
77
79
 
@@ -0,0 +1,117 @@
1
+ <script lang="ts">
2
+ import Divider from '../divider/Divider.svelte'
3
+ import type { DialogProps } from './types.ts'
4
+
5
+ let {
6
+ element = $bindable(),
7
+ showPopover = $bindable(),
8
+ hidePopover = $bindable(),
9
+ children,
10
+ headline,
11
+ icon,
12
+ supportingText,
13
+ buttons,
14
+ divider,
15
+ ...attributes
16
+ }: DialogProps = $props()
17
+
18
+ showPopover = () => {
19
+ element?.showPopover()
20
+ }
21
+
22
+ hidePopover = () => {
23
+ element?.hidePopover()
24
+ }
25
+ </script>
26
+
27
+ <form bind:this={element} class="np-dialog" popover="auto" role="dialog" {...attributes}>
28
+ {#if icon}
29
+ <div class="np-dialog-icon">
30
+ {@render icon()}
31
+ </div>
32
+ {/if}
33
+ <h1 class="np-dialog-headline" style={icon ? 'text-align: center' : ''}>{headline}</h1>
34
+ {#if supportingText}
35
+ <p class="np-dialog-supporting-text">{supportingText}</p>
36
+ {/if}
37
+ {#if divider}
38
+ <Divider style="margin-top: 1rem" --np-divider-color="var(--np-color-outline)" />
39
+ {/if}
40
+ {#if children}
41
+ {@render children()}
42
+ {/if}
43
+ {#if buttons}
44
+ <div class="np-dialog-buttons">
45
+ {@render buttons()}
46
+ </div>
47
+ {/if}
48
+ </form>
49
+
50
+ <style>
51
+ .np-dialog {
52
+ border: 0;
53
+ min-width: 280px;
54
+ max-width: 560px;
55
+ background-color: var(--np-color-surface);
56
+ color: var(--np-color-on-surface);
57
+ padding: 1.5rem;
58
+ border-radius: var(--np-shape-corner-extra-large);
59
+ box-shadow: var(--np-elevation-3);
60
+ transition:
61
+ display 0.2s allow-discrete,
62
+ overlay 0.2s allow-discrete,
63
+ opacity 0.2s linear;
64
+ opacity: 0;
65
+ z-index: 1;
66
+ }
67
+ .np-dialog:popover-open {
68
+ opacity: 1;
69
+ @starting-style {
70
+ opacity: 0;
71
+ }
72
+ }
73
+ .np-dialog::backdrop {
74
+ background-color: var(--np-color-scrim);
75
+ opacity: 0;
76
+ transition:
77
+ display 0.2s allow-discrete,
78
+ overlay 0.2s allow-discrete,
79
+ opacity 0.2s linear;
80
+ }
81
+ .np-dialog:popover-open::backdrop {
82
+ opacity: 0.38;
83
+ }
84
+
85
+ @starting-style {
86
+ .np-dialog:popover-open::backdrop {
87
+ opacity: 0;
88
+ }
89
+ }
90
+ .np-dialog-icon {
91
+ color: var(--np-color-secondary);
92
+ display: flex;
93
+ justify-content: center;
94
+ margin-bottom: 1rem;
95
+ }
96
+ .np-dialog-headline {
97
+ margin: 0 0 1rem 0;
98
+ padding: 0;
99
+ line-height: 2rem;
100
+ font-size: 1.5rem;
101
+ font-weight: 400;
102
+ }
103
+ .np-dialog-buttons {
104
+ display: flex;
105
+ justify-content: flex-end;
106
+ gap: 0.5rem;
107
+ margin-top: 1.5rem;
108
+ }
109
+ .np-dialog-supporting-text {
110
+ margin: 0;
111
+ padding: 0;
112
+ line-height: 1.25rem;
113
+ font-size: 0.875rem;
114
+ font-weight: 400;
115
+ color: var(--np-color-on-surface-variant);
116
+ }
117
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { DialogProps } from './types.ts';
2
+ declare const Dialog: import("svelte").Component<DialogProps, {}, "element" | "showPopover" | "hidePopover">;
3
+ type Dialog = ReturnType<typeof Dialog>;
4
+ export default Dialog;
@@ -0,0 +1 @@
1
+ export { default as Dialog } from './Dialog.svelte';
@@ -0,0 +1 @@
1
+ export { default as Dialog } from './Dialog.svelte';
@@ -0,0 +1,12 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLFormAttributes } from 'svelte/elements';
3
+ export interface DialogProps extends Omit<HTMLFormAttributes, 'class' | 'popover'> {
4
+ icon?: Snippet;
5
+ headline: string;
6
+ supportingText?: string;
7
+ divider?: boolean;
8
+ buttons?: Snippet;
9
+ element?: HTMLElement;
10
+ showPopover?: () => void;
11
+ hidePopover?: () => void;
12
+ }
@@ -0,0 +1 @@
1
+ export {};
package/dist/index.d.ts CHANGED
@@ -2,9 +2,11 @@ export * from './button/index.js';
2
2
  export * from './card/index.js';
3
3
  export * from './checkbox/index.js';
4
4
  export * from './chip/index.js';
5
+ export * from './dialogs/index.js';
5
6
  export * from './divider/index.js';
6
7
  export * from './list/index.js';
7
8
  export * from './menu/index.js';
9
+ export * from './navigation-rail/index.js';
8
10
  export * from './progress/index.js';
9
11
  export * from './radio/index.js';
10
12
  export * from './ripple/index.js';
package/dist/index.js CHANGED
@@ -2,9 +2,11 @@ export * from './button/index.js';
2
2
  export * from './card/index.js';
3
3
  export * from './checkbox/index.js';
4
4
  export * from './chip/index.js';
5
+ export * from './dialogs/index.js';
5
6
  export * from './divider/index.js';
6
7
  export * from './list/index.js';
7
8
  export * from './menu/index.js';
9
+ export * from './navigation-rail/index.js';
8
10
  export * from './progress/index.js';
9
11
  export * from './radio/index.js';
10
12
  export * from './ripple/index.js';
@@ -112,7 +112,9 @@
112
112
  }
113
113
  .np-menu:popover-open {
114
114
  opacity: 1;
115
- @starting-style {
115
+ }
116
+ @starting-style {
117
+ .np-menu:popover-open {
116
118
  opacity: 0;
117
119
  }
118
120
  }
@@ -0,0 +1,100 @@
1
+ <script lang="ts">
2
+ import type { HTMLAnchorAttributes, HTMLButtonAttributes } from 'svelte/elements'
3
+ import type { NavigationAction } from './types.ts'
4
+ import Ripple from '../ripple/Ripple.svelte'
5
+
6
+ let { selected, icon, label, ...attributes }: NavigationAction = $props()
7
+ let touchEl: HTMLSpanElement | undefined = $state()
8
+
9
+ const isButton = (obj: unknown): obj is HTMLButtonAttributes => {
10
+ return (obj as HTMLAnchorAttributes).href === undefined
11
+ }
12
+ const isLink = (obj: unknown): obj is HTMLAnchorAttributes => {
13
+ return (obj as HTMLAnchorAttributes).href !== undefined
14
+ }
15
+ </script>
16
+
17
+ {#snippet content()}
18
+ <div class="np-navigation-action-icon">
19
+ <Ripple forElement={touchEl} />
20
+ {@render icon()}
21
+ </div>
22
+ <div class="np-navigation-action-label">{label}</div>
23
+ <span class="np-touch" bind:this={touchEl}></span>
24
+ {/snippet}
25
+
26
+ {#if isButton(attributes)}
27
+ <button
28
+ {...attributes as HTMLButtonAttributes}
29
+ class:np-navigation-action-selected={selected}
30
+ class="np-navigation-action {attributes.class}"
31
+ >
32
+ {@render content()}
33
+ </button>
34
+ {:else if isLink(attributes)}
35
+ <a {...attributes} class="np-navigation-action {attributes.class}">
36
+ {@render content()}
37
+ </a>
38
+ {/if}
39
+
40
+ <style>
41
+ .np-navigation-action {
42
+ cursor: pointer;
43
+ border: 0;
44
+ background: none;
45
+ align-items: center;
46
+ gap: 0.25rem;
47
+ display: flex;
48
+ flex-direction: column;
49
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
50
+ }
51
+ .np-navigation-action-icon {
52
+ position: relative;
53
+ color: var(--np-color-on-surface-variant);
54
+ display: flex;
55
+ border-radius: var(--np-shape-corner-full);
56
+ justify-content: center;
57
+ width: 3.5rem;
58
+ height: 2rem;
59
+ align-items: center;
60
+ }
61
+ .np-navigation-action-label {
62
+ font-size: 0.75rem;
63
+ line-height: 1rem;
64
+ font-weight: 500;
65
+ transition: all;
66
+ color: var(--np-color-on-surface-variant);
67
+ }
68
+ .np-navigation-action-selected .np-navigation-action-icon {
69
+ color: var(--np-color-secondary-container);
70
+ --np-icon-settings: 'FILL' 1, 'wght' 400, 'GRAD' 0, 'opsz' 24;
71
+ }
72
+ .np-navigation-action-icon::before {
73
+ content: '';
74
+ position: absolute;
75
+ width: 100%;
76
+ height: 100%;
77
+ opacity: 0;
78
+ transform: scaleX(0.32);
79
+ transition-duration: 0.2s;
80
+ transition-property: transform, opacity;
81
+ transition-timing-function: linear;
82
+ background-color: var(--np-color-on-secondary-container);
83
+ border-radius: 100px;
84
+ z-index: -1;
85
+ }
86
+ .np-navigation-action-selected .np-navigation-action-icon::before {
87
+ opacity: 1;
88
+ transform: scaleX(1);
89
+ }
90
+
91
+ .np-navigation-action-selected .np-navigation-action-label {
92
+ font-weight: 700;
93
+ color: var(--np-color-on-surface);
94
+ }
95
+ .np-touch {
96
+ height: 56px;
97
+ position: absolute;
98
+ width: 80px;
99
+ }
100
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { NavigationAction } from './types.ts';
2
+ declare const NavigationAction: any;
3
+ type NavigationAction = ReturnType<typeof NavigationAction>;
4
+ export default NavigationAction;
@@ -0,0 +1,23 @@
1
+ <script lang="ts">
2
+ import type { NavigationRail } from './types.ts'
3
+
4
+ let { children, ...attributes }: NavigationRail = $props()
5
+ </script>
6
+
7
+ <nav {...attributes} class="navigation-rail">
8
+ {#if children}
9
+ {@render children()}
10
+ {/if}
11
+ </nav>
12
+
13
+ <style>
14
+ .navigation-rail {
15
+ z-index: 8;
16
+ display: flex;
17
+ flex-direction: column;
18
+ justify-content: space-between;
19
+ width: 80px;
20
+ gap: 0.75rem;
21
+ background-color: var(--np-color-surface);
22
+ }
23
+ </style>
@@ -0,0 +1,4 @@
1
+ import type { NavigationRail } from './types.ts';
2
+ declare const NavigationRail: any;
3
+ type NavigationRail = ReturnType<typeof NavigationRail>;
4
+ export default NavigationRail;
@@ -0,0 +1 @@
1
+ export { default as NavigationRail } from './NavigationRail.svelte';
@@ -0,0 +1 @@
1
+ export { default as NavigationRail } from './NavigationRail.svelte';
@@ -0,0 +1,15 @@
1
+ import type { Snippet } from 'svelte';
2
+ import type { HTMLAnchorAttributes, HTMLAttributes, HTMLButtonAttributes } from 'svelte/elements';
3
+ export type NavigationRail = HTMLAttributes<HTMLElement>;
4
+ interface NavigationActionButton extends HTMLButtonAttributes {
5
+ icon: Snippet;
6
+ label: string;
7
+ selected?: boolean;
8
+ }
9
+ interface NavigationActionLink extends HTMLAnchorAttributes {
10
+ icon: Snippet;
11
+ label: string;
12
+ selected?: boolean;
13
+ }
14
+ export type NavigationAction = NavigationActionButton | NavigationActionLink;
15
+ export {};
@@ -0,0 +1 @@
1
+ export {};
package/dist/types.d.ts CHANGED
@@ -5,6 +5,7 @@ export * from './chip/types.ts';
5
5
  export * from './divider/types.js';
6
6
  export * from './list/types.ts';
7
7
  export * from './menu/types.ts';
8
+ export * from './navigation-rail/types.ts';
8
9
  export * from './progress/types.js';
9
10
  export * from './radio/types.ts';
10
11
  export * from './ripple/types.ts';
package/dist/types.js CHANGED
@@ -5,6 +5,7 @@ export * from './chip/types.ts';
5
5
  export * from './divider/types.js';
6
6
  export * from './list/types.ts';
7
7
  export * from './menu/types.ts';
8
+ export * from './navigation-rail/types.ts';
8
9
  export * from './progress/types.js';
9
10
  export * from './radio/types.ts';
10
11
  export * from './ripple/types.ts';
package/package.json CHANGED
@@ -1,93 +1,92 @@
1
1
  {
2
- "name": "noph-ui",
3
- "version": "0.4.12",
4
- "license": "MIT",
5
- "homepage": "https://noph.dev",
6
- "repository": {
7
- "type": "git",
8
- "url": "git+https://github.com/cnolte/noph-ui"
9
- },
10
- "author": {
11
- "name": "cnolte"
12
- },
13
- "keywords": [
14
- "svelte",
15
- "svelte 5",
16
- "material",
17
- "material 3",
18
- "material you",
19
- "m3",
20
- "ui",
21
- "frontend",
22
- "design-system",
23
- "ui-library",
24
- "theming"
25
- ],
26
- "scripts": {
27
- "dev": "vite dev",
28
- "build": "vite build && npm run package",
29
- "preview": "vite preview",
30
- "package": "svelte-kit sync && svelte-package && publint",
31
- "prepublishOnly": "npm run package",
32
- "test": "npm run test:integration && npm run test:unit",
33
- "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
34
- "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
35
- "lint": "prettier --check . && eslint .",
36
- "format": "prettier --write .",
37
- "test:integration": "playwright test",
38
- "test:unit": "vitest"
39
- },
40
- "exports": {
41
- ".": {
42
- "types": "./dist/index.d.ts",
43
- "svelte": "./dist/index.js"
44
- },
45
- "./icons": {
46
- "types": "./dist/icons/index.d.ts",
47
- "svelte": "./dist/icons/index.js"
48
- },
49
- "./types": {
50
- "types": "./dist/types.d.ts"
51
- },
52
- "./defaultTheme": {
53
- "import": "./dist/themes/defaultTheme.css",
54
- "require": "./dist/themes/defaultTheme.css"
55
- }
56
- },
57
- "sideEffects": [
58
- "**/*.css"
59
- ],
60
- "files": [
61
- "dist",
62
- "!dist/**/*.test.*",
63
- "!dist/**/*.spec.*"
64
- ],
65
- "peerDependencies": {
66
- "svelte": "^5.0.0"
67
- },
68
- "devDependencies": {
69
- "@material/material-color-utilities": "^0.3.0",
70
- "@playwright/test": "^1.49.1",
71
- "@sveltejs/adapter-vercel": "^5.5.2",
72
- "@sveltejs/kit": "^2.12.1",
73
- "@sveltejs/package": "^2.3.7",
74
- "@sveltejs/vite-plugin-svelte": "^5.0.2",
75
- "@types/eslint": "^9.6.1",
76
- "eslint": "^9.17.0",
77
- "eslint-config-prettier": "^9.1.0",
78
- "eslint-plugin-svelte": "^2.46.1",
79
- "globals": "^15.13.0",
80
- "prettier": "^3.4.2",
81
- "prettier-plugin-svelte": "^3.3.2",
82
- "publint": "^0.2.12",
83
- "svelte": "^5.14.3",
84
- "svelte-check": "^4.1.1",
85
- "typescript": "^5.7.2",
86
- "typescript-eslint": "^8.18.1",
87
- "vite": "^6.0.3",
88
- "vitest": "^2.1.8"
89
- },
90
- "svelte": "./dist/index.js",
91
- "types": "./dist/index.d.ts",
92
- "type": "module"
93
- }
2
+ "name": "noph-ui",
3
+ "version": "0.6.0",
4
+ "license": "MIT",
5
+ "homepage": "https://noph.dev",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/cnolte/noph-ui"
9
+ },
10
+ "author": {
11
+ "name": "cnolte"
12
+ },
13
+ "keywords": [
14
+ "svelte",
15
+ "svelte 5",
16
+ "material",
17
+ "material 3",
18
+ "material you",
19
+ "m3",
20
+ "ui",
21
+ "frontend",
22
+ "design-system",
23
+ "ui-library",
24
+ "theming"
25
+ ],
26
+ "exports": {
27
+ ".": {
28
+ "types": "./dist/index.d.ts",
29
+ "svelte": "./dist/index.js"
30
+ },
31
+ "./icons": {
32
+ "types": "./dist/icons/index.d.ts",
33
+ "svelte": "./dist/icons/index.js"
34
+ },
35
+ "./types": {
36
+ "types": "./dist/types.d.ts"
37
+ },
38
+ "./defaultTheme": {
39
+ "import": "./dist/themes/defaultTheme.css",
40
+ "require": "./dist/themes/defaultTheme.css"
41
+ }
42
+ },
43
+ "sideEffects": [
44
+ "**/*.css"
45
+ ],
46
+ "files": [
47
+ "dist",
48
+ "!dist/**/*.test.*",
49
+ "!dist/**/*.spec.*"
50
+ ],
51
+ "peerDependencies": {
52
+ "svelte": "^5.0.0"
53
+ },
54
+ "devDependencies": {
55
+ "@material/material-color-utilities": "^0.3.0",
56
+ "@playwright/test": "^1.49.1",
57
+ "@sveltejs/adapter-vercel": "^5.5.2",
58
+ "@sveltejs/kit": "^2.12.1",
59
+ "@sveltejs/package": "^2.3.7",
60
+ "@sveltejs/vite-plugin-svelte": "^5.0.2",
61
+ "@types/eslint": "^9.6.1",
62
+ "eslint": "^9.17.0",
63
+ "eslint-config-prettier": "^9.1.0",
64
+ "eslint-plugin-svelte": "^2.46.1",
65
+ "globals": "^15.13.0",
66
+ "prettier": "^3.4.2",
67
+ "prettier-plugin-svelte": "^3.3.2",
68
+ "publint": "^0.2.12",
69
+ "svelte": "^5.14.3",
70
+ "svelte-check": "^4.1.1",
71
+ "typescript": "^5.7.2",
72
+ "typescript-eslint": "^8.18.1",
73
+ "vite": "^6.0.3",
74
+ "vitest": "^2.1.8"
75
+ },
76
+ "svelte": "./dist/index.js",
77
+ "types": "./dist/index.d.ts",
78
+ "type": "module",
79
+ "scripts": {
80
+ "dev": "vite dev",
81
+ "build": "vite build && npm run package",
82
+ "preview": "vite preview",
83
+ "package": "svelte-kit sync && svelte-package && publint",
84
+ "test": "npm run test:integration && npm run test:unit",
85
+ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
86
+ "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
87
+ "lint": "prettier --check . && eslint .",
88
+ "format": "prettier --write .",
89
+ "test:integration": "playwright test",
90
+ "test:unit": "vitest"
91
+ }
92
+ }