noph-ui 0.25.0 → 0.25.2

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.
@@ -15,41 +15,39 @@
15
15
  const uid = $props.id()
16
16
  </script>
17
17
 
18
- <label {style} class={['np-host', attributes.class]} bind:this={element}>
19
- <div class="np-container">
20
- {#if !attributes.disabled}
21
- <Ripple forElement={inputEl} class="np-radio-ripple" />
22
- {/if}
23
- <svg class="np-radio-icon" viewBox="0 0 20 20">
24
- <mask id="{uid}-mask">
25
- <rect width="100%" height="100%" fill="white" />
26
- <circle cx="10" cy="10" r="8" fill="black" />
27
- </mask>
28
- <circle class="outer circle" cx="10" cy="10" r="10" mask="url(#{uid}-mask)" />
29
- <circle class="inner circle" cx="10" cy="10" r="5" />
30
- </svg>
31
- {#if group !== undefined}
32
- <input
33
- {...attributes}
34
- bind:this={inputEl}
35
- type="radio"
36
- class="np-input"
37
- {checked}
38
- {defaultChecked}
39
- bind:group
40
- />
41
- {:else}
42
- <input
43
- {...attributes}
44
- bind:this={inputEl}
45
- type="radio"
46
- class="np-input"
47
- {checked}
48
- {defaultChecked}
49
- />
50
- {/if}
51
- </div>
52
- </label>
18
+ <div {style} class={['np-container', attributes.class]} bind:this={element}>
19
+ {#if !attributes.disabled}
20
+ <Ripple forElement={inputEl} class="np-radio-ripple" />
21
+ {/if}
22
+ <svg class="np-radio-icon" viewBox="0 0 20 20">
23
+ <mask id="{uid}-mask">
24
+ <rect width="100%" height="100%" fill="white" />
25
+ <circle cx="10" cy="10" r="8" fill="black" />
26
+ </mask>
27
+ <circle class="outer circle" cx="10" cy="10" r="10" mask="url(#{uid}-mask)" />
28
+ <circle class="inner circle" cx="10" cy="10" r="5" />
29
+ </svg>
30
+ {#if group !== undefined}
31
+ <input
32
+ {...attributes}
33
+ bind:this={inputEl}
34
+ type="radio"
35
+ class="np-input"
36
+ {checked}
37
+ {defaultChecked}
38
+ bind:group
39
+ />
40
+ {:else}
41
+ <input
42
+ {...attributes}
43
+ bind:this={inputEl}
44
+ type="radio"
45
+ class="np-input"
46
+ {checked}
47
+ {defaultChecked}
48
+ />
49
+ {/if}
50
+ </div>
53
51
 
54
52
  <style>
55
53
  :global(.np-radio-ripple) {
@@ -57,6 +55,7 @@
57
55
  inset: unset !important;
58
56
  width: 40px;
59
57
  }
58
+
60
59
  .np-input {
61
60
  opacity: 0;
62
61
  margin: 0;
@@ -65,71 +64,51 @@
65
64
  height: 48px;
66
65
  width: 48px;
67
66
  }
68
- .np-host {
69
- margin: max(0px, (48px - var(--np-radio-icon-size, 20px))/2);
70
- position: relative;
67
+
68
+ .np-container {
69
+ margin: max(0px, (40px - var(--np-radio-icon-size, 20px))/2);
71
70
  display: inline-flex;
72
71
  vertical-align: top;
72
+ -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
73
+ border-radius: var(--np-shape-corner-full);
74
+ place-content: center;
75
+ place-items: center;
76
+ position: relative;
73
77
  width: var(--np-radio-icon-size, 20px);
74
78
  height: var(--np-radio-icon-size, 20px);
75
79
  cursor: pointer;
76
- -webkit-tap-highlight-color: rgba(0, 0, 0, 0);
77
- outline: none;
78
- }
79
-
80
- .np-host:has(input:focus-visible) .np-container {
81
- outline-style: solid;
82
- outline-color: var(--np-color-secondary);
83
- outline-width: 3px;
84
- outline-offset: 12px;
85
- border-radius: 50%;
86
- animation: focusAnimation 0.3s ease forwards;
87
- }
88
- @keyframes focusAnimation {
89
- 0% {
90
- outline-width: 3px;
91
- }
92
- 50% {
93
- outline-width: 6px;
94
- }
95
- 100% {
96
- outline-width: 3px;
97
- }
98
80
  }
99
81
 
100
- .np-host:has(input:disabled) {
82
+ .np-container:has(input:disabled) {
101
83
  cursor: default;
102
84
  }
103
85
 
104
- .np-container {
105
- display: flex;
106
- height: 100%;
107
- border-radius: var(--np-shape-corner-full);
108
- place-content: center;
109
- place-items: center;
110
- width: 100%;
111
- }
112
86
  .np-radio-icon {
113
87
  fill: var(--np-radio-icon-color, var(--np-color-on-surface-variant));
114
88
  inset: 0px;
115
89
  position: absolute;
116
90
  }
117
- .np-host:has(input:checked) .np-radio-icon {
91
+
92
+ .np-container:has(input:checked) .np-radio-icon {
118
93
  fill: var(--np-radio-selected-icon-color, var(--np-color-primary));
119
94
  }
120
- .np-host:has(input:disabled) .np-radio-icon {
95
+
96
+ .np-container:has(input:disabled) .np-radio-icon {
121
97
  fill: var(--np-color-on-surface);
122
98
  opacity: 0.38;
123
99
  }
100
+
124
101
  .inner.circle {
125
102
  opacity: 0;
126
103
  transform-origin: center center;
127
104
  transition: opacity 50ms linear;
128
105
  }
129
- .np-host:has(input:checked) .inner.circle {
106
+
107
+ .np-container:has(input:checked) .inner.circle {
130
108
  animation: 300ms cubic-bezier(0.05, 0.7, 0.1, 1) 0s 1 normal none running inner-circle-grow;
131
109
  opacity: 1;
132
110
  }
111
+
133
112
  @keyframes inner-circle-grow {
134
113
  from {
135
114
  transform: scale(0);
@@ -138,4 +117,23 @@
138
117
  transform: scale(1);
139
118
  }
140
119
  }
120
+
121
+ .np-container:has(input:focus-visible) {
122
+ outline-style: solid;
123
+ outline-color: var(--np-color-secondary);
124
+ outline-width: 3px;
125
+ outline-offset: 2px;
126
+ animation: focusAnimation 0.3s ease forwards;
127
+ }
128
+ @keyframes focusAnimation {
129
+ 0% {
130
+ outline-width: 3px;
131
+ }
132
+ 50% {
133
+ outline-width: 6px;
134
+ }
135
+ 100% {
136
+ outline-width: 3px;
137
+ }
138
+ }
141
139
  </style>
@@ -51,10 +51,17 @@
51
51
  }
52
52
  anchor.addEventListener('pointerenter', showPopover)
53
53
  anchor.addEventListener('pointerleave', hidePopover)
54
- anchor.addEventListener('focus', showPopover)
54
+ anchor.addEventListener('focus', onAnchorFocus)
55
55
  anchor.addEventListener('blur', hidePopover)
56
56
  }
57
57
 
58
+ const onAnchorFocus = (e: FocusEvent) => {
59
+ const target = e.currentTarget as HTMLElement
60
+ if (target.matches(':focus-visible')) {
61
+ showPopover()
62
+ }
63
+ }
64
+
58
65
  const showPopover = () => {
59
66
  element?.showPopover()
60
67
  }
@@ -68,7 +75,7 @@
68
75
  if (anchor) {
69
76
  anchor.removeEventListener('pointerenter', showPopover)
70
77
  anchor.removeEventListener('pointerleave', hidePopover)
71
- anchor.removeEventListener('focus', showPopover)
78
+ anchor.removeEventListener('focus', onAnchorFocus)
72
79
  anchor.removeEventListener('blur', hidePopover)
73
80
  }
74
81
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.25.0",
3
+ "version": "0.25.2",
4
4
  "license": "MIT",
5
5
  "homepage": "https://noph.dev",
6
6
  "repository": {
@@ -58,18 +58,18 @@
58
58
  "@material/material-color-utilities": "^0.3.0",
59
59
  "@playwright/test": "^1.55.0",
60
60
  "@sveltejs/adapter-vercel": "^5.10.2",
61
- "@sveltejs/kit": "^2.37.1",
61
+ "@sveltejs/kit": "^2.39.0",
62
62
  "@sveltejs/package": "^2.5.0",
63
- "@sveltejs/vite-plugin-svelte": "^6.1.4",
63
+ "@sveltejs/vite-plugin-svelte": "^6.2.0",
64
64
  "@types/eslint": "^9.6.1",
65
65
  "eslint": "^9.35.0",
66
66
  "eslint-config-prettier": "^10.1.8",
67
- "eslint-plugin-svelte": "^3.12.2",
68
- "globals": "^16.3.0",
67
+ "eslint-plugin-svelte": "^3.12.3",
68
+ "globals": "^16.4.0",
69
69
  "prettier": "^3.6.2",
70
70
  "prettier-plugin-svelte": "^3.4.0",
71
71
  "publint": "^0.3.12",
72
- "svelte": "^5.38.7",
72
+ "svelte": "^5.38.10",
73
73
  "svelte-check": "^4.3.1",
74
74
  "typescript": "^5.9.2",
75
75
  "typescript-eslint": "^8.43.0",