noph-ui 0.12.3 → 0.12.5

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
@@ -65,7 +65,7 @@ Beta (No breaking changes expected)
65
65
  - Ripple
66
66
  - Segmented buttons
67
67
  - Snackbar
68
- - Text fields (Theming missing)
68
+ - Text fields
69
69
 
70
70
  In progress (Breaking changes expected)
71
71
 
@@ -75,7 +75,7 @@ In progress (Breaking changes expected)
75
75
  - Navigation Drawer (Docs missing)
76
76
  - Navigation Rail (Badge is missing + Docs missing)
77
77
  - Tooltips (Positioning missing)
78
- - Select (iOS issues)
78
+ - Select (Docs missing)
79
79
 
80
80
  Pending
81
81
 
@@ -45,23 +45,6 @@
45
45
 
46
46
  $effect(() => {
47
47
  if (anchor && element) {
48
- element.addEventListener('toggle', (event) => {
49
- const { newState, currentTarget } = event as ToggleEvent & {
50
- currentTarget: EventTarget & HTMLDivElement
51
- }
52
- if (newState === 'open') {
53
- const rect = currentTarget.getBoundingClientRect()
54
- const viewportHeight = window.innerHeight
55
-
56
- if (rect.bottom > viewportHeight) {
57
- const maxHeight = viewportHeight - rect.top - 18
58
- currentTarget.style.maxHeight = `${maxHeight}px`
59
- }
60
- }
61
- if (newState === 'closed') {
62
- currentTarget.style.maxHeight = '80dvh'
63
- }
64
- })
65
48
  if (!('anchorName' in document.documentElement.style)) {
66
49
  anchor.addEventListener('click', () => {
67
50
  refreshValues()
@@ -83,12 +66,27 @@
83
66
  </script>
84
67
 
85
68
  <svelte:window bind:innerHeight onresize={refreshValues} />
86
-
87
69
  <div
88
70
  {...attributes}
89
71
  bind:this={element}
90
72
  bind:clientWidth
91
73
  bind:clientHeight
74
+ ontoggle={(event) => {
75
+ const { newState, currentTarget } = event
76
+ if (newState === 'open') {
77
+ const rect = currentTarget.getBoundingClientRect()
78
+ const viewportHeight = innerHeight
79
+
80
+ if (rect.bottom > viewportHeight && rect.top < viewportHeight / 2) {
81
+ const maxHeight = viewportHeight - rect.top - 18
82
+ currentTarget.style.maxHeight = `${maxHeight}px`
83
+ }
84
+ }
85
+ if (newState === 'closed') {
86
+ currentTarget.style.maxHeight = '80dvh'
87
+ }
88
+ attributes.ontoggle?.(event)
89
+ }}
92
90
  popover="auto"
93
91
  class={['np-menu', attributes.class]}
94
92
  role="menu"
@@ -115,7 +113,7 @@
115
113
  opacity: 0;
116
114
  justify-self: var(--np-menu-justify-self, anchor-center);
117
115
  position-area: var(--np-menu-position-area, bottom center);
118
- position-try-fallbacks: --np-menu-position-fallback;
116
+ position-try: most-height flip-block;
119
117
  }
120
118
 
121
119
  .np-menu:popover-open {
@@ -124,8 +122,4 @@
124
122
  opacity: 0;
125
123
  }
126
124
  }
127
- @position-try --np-menu-position-fallback {
128
- position-area: var(--np-menu-position-area-fallback, top center);
129
- position-area: var(--np-menu-position-area-fallback, top center);
130
- }
131
125
  </style>
@@ -34,6 +34,7 @@
34
34
  let selectElement: HTMLSelectElement | undefined = $state()
35
35
  let menuElement: HTMLDivElement | undefined = $state()
36
36
  let field: HTMLDivElement | undefined = $state()
37
+ let clientWidth = $state(0)
37
38
  let menuId = $state(`--select-${crypto.randomUUID()}`)
38
39
  let menuOpen = $state(false)
39
40
  let selectedLabel = $derived.by<string>(() => {
@@ -88,11 +89,11 @@
88
89
  aria-label={attributes['aria-label'] || label}
89
90
  data-testid={attributes['data-testid']}
90
91
  bind:this={field}
92
+ bind:clientWidth
91
93
  autofocus={disabled ? false : autofocus}
92
94
  onclick={(event) => {
93
95
  event.preventDefault()
94
96
  menuElement?.showPopover()
95
- menuElement?.style.setProperty('min-width', `${field?.clientWidth}px`)
96
97
  }}
97
98
  onkeydown={(event) => {
98
99
  if (event.key === 'Tab') {
@@ -101,7 +102,6 @@
101
102
  event.preventDefault()
102
103
  if (event.key === 'ArrowDown' || event.key === 'ArrowUp' || event.key === 'Enter') {
103
104
  menuElement?.showPopover()
104
- menuElement?.style.setProperty('min-width', `${field?.clientWidth}px`)
105
105
  ;(menuElement?.firstElementChild as HTMLElement)?.focus()
106
106
  }
107
107
  }
@@ -161,7 +161,8 @@
161
161
  errorTextRaw = currentTarget.validationMessage
162
162
  }
163
163
  if (isFirstInvalidControlInForm(currentTarget.form, currentTarget)) {
164
- currentTarget.focus()
164
+ field?.focus()
165
+ menuElement?.showPopover()
165
166
  }
166
167
  }}
167
168
  bind:value
@@ -198,12 +199,15 @@
198
199
  </div>
199
200
 
200
201
  <Menu
201
- style="position-anchor:{menuId}"
202
+ style="position-anchor:{menuId};min-width:{clientWidth}px;"
202
203
  popover="manual"
203
204
  --np-menu-justify-self="none"
204
205
  --np-menu-position-area-fallback="top span-right"
205
206
  --np-menu-position-area="bottom span-right"
206
207
  --np-menu-margin="2px 0"
208
+ --np-menu-container-shape={variant === 'outlined'
209
+ ? 'var(--np-outlined-select-text-field-container-shape)'
210
+ : 'var(--np-filled-select-text-field-container-shape)'}
207
211
  anchor={element}
208
212
  ontoggle={({ newState }) => {
209
213
  if (newState === 'open') {
@@ -293,7 +297,7 @@
293
297
  }
294
298
  .background {
295
299
  background: var(
296
- --np-text-field-filled-background-color,
300
+ --np-filled-select-text-field-container-color,
297
301
  var(--np-color-surface-container-highest)
298
302
  );
299
303
  }
@@ -319,14 +323,32 @@
319
323
  position: relative;
320
324
  }
321
325
  .outlined .container-overflow {
322
- border-start-start-radius: var(--np-shape-corner-extra-small);
323
- border-start-end-radius: var(--np-shape-corner-extra-small);
324
- border-end-end-radius: var(--np-shape-corner-extra-small);
325
- border-end-start-radius: var(--np-shape-corner-extra-small);
326
+ border-start-start-radius: var(
327
+ --np-outlined-select-text-field-container-shape,
328
+ var(--np-shape-corner-extra-small)
329
+ );
330
+ border-start-end-radius: var(
331
+ --np-outlined-select-text-field-container-shape,
332
+ var(--np-shape-corner-extra-small)
333
+ );
334
+ border-end-end-radius: var(
335
+ --np-outlined-select-text-field-container-shape,
336
+ var(--np-shape-corner-extra-small)
337
+ );
338
+ border-end-start-radius: var(
339
+ --np-outlined-select-text-field-container-shape,
340
+ var(--np-shape-corner-extra-small)
341
+ );
326
342
  }
327
343
  .container-overflow {
328
- border-start-start-radius: var(--np-shape-corner-extra-small);
329
- border-start-end-radius: var(--np-shape-corner-extra-small);
344
+ border-start-start-radius: var(
345
+ --np-filled-select-text-field-container-shape,
346
+ var(--np-shape-corner-extra-small)
347
+ );
348
+ border-start-end-radius: var(
349
+ --np-filled-select-text-field-container-shape,
350
+ var(--np-shape-corner-extra-small)
351
+ );
330
352
  border-end-end-radius: var(--np-shape-corner-none);
331
353
  border-end-start-radius: var(--np-shape-corner-none);
332
354
  display: flex;
@@ -63,10 +63,10 @@
63
63
 
64
64
  <label
65
65
  style={(variant === 'outlined'
66
- ? '--top-space:1rem;--bottom-space:1rem;--floating-label-top:-0.5rem;--floating-label-left:-2.25rem;--_focus-outline-width:3px;'
66
+ ? '--_label-text-color:var(--np-outlined-text-field-label-text-color);--top-space:1rem;--bottom-space:1rem;--floating-label-top:-0.5rem;--floating-label-left:-2.25rem;--_focus-outline-width:3px;'
67
67
  : !label?.length
68
- ? '--top-space:1rem;--bottom-space:1rem;'
69
- : '') + style}
68
+ ? '--_label-text-color:var(--np-filled-text-field-label-text-color);--top-space:1rem;--bottom-space:1rem; '
69
+ : '--_label-text-color:var(--np-filled-text-field-label-text-color); ') + style}
70
70
  class={['text-field', attributes.class]}
71
71
  bind:this={element}
72
72
  >
@@ -197,7 +197,10 @@
197
197
  width: 100%;
198
198
  }
199
199
  .active-indicator::after {
200
- border-bottom-color: var(--np-color-primary);
200
+ border-bottom-color: var(
201
+ --np-filled-text-field-focus-active-indicator-color,
202
+ var(--np-color-primary)
203
+ );
201
204
  border-bottom-width: 3px;
202
205
  }
203
206
  .error .active-indicator::before {
@@ -213,7 +216,7 @@
213
216
  }
214
217
  .background {
215
218
  background: var(
216
- --np-text-field-filled-background-color,
219
+ --np-filled-text-field-container-color,
217
220
  var(--np-color-surface-container-highest)
218
221
  );
219
222
  }
@@ -239,14 +242,32 @@
239
242
  position: relative;
240
243
  }
241
244
  .outlined .container-overflow {
242
- border-start-start-radius: var(--np-shape-corner-extra-small);
243
- border-start-end-radius: var(--np-shape-corner-extra-small);
244
- border-end-end-radius: var(--np-shape-corner-extra-small);
245
- border-end-start-radius: var(--np-shape-corner-extra-small);
245
+ border-start-start-radius: var(
246
+ --np-outlined-text-field-container-shape,
247
+ var(--np-shape-corner-extra-small)
248
+ );
249
+ border-start-end-radius: var(
250
+ --np-outlined-text-field-container-shape,
251
+ var(--np-shape-corner-extra-small)
252
+ );
253
+ border-end-end-radius: var(
254
+ --np-outlined-text-field-container-shape,
255
+ var(--np-shape-corner-extra-small)
256
+ );
257
+ border-end-start-radius: var(
258
+ --np-outlined-text-field-container-shape,
259
+ var(--np-shape-corner-extra-small)
260
+ );
246
261
  }
247
262
  .container-overflow {
248
- border-start-start-radius: var(--np-shape-corner-extra-small);
249
- border-start-end-radius: var(--np-shape-corner-extra-small);
263
+ border-start-start-radius: var(
264
+ --np-filled-text-field-container-shape,
265
+ var(--np-shape-corner-extra-small)
266
+ );
267
+ border-start-end-radius: var(
268
+ --np-filled-text-field-container-shape,
269
+ var(--np-shape-corner-extra-small)
270
+ );
250
271
  border-end-end-radius: var(--np-shape-corner-none);
251
272
  border-end-start-radius: var(--np-shape-corner-none);
252
273
  display: flex;
@@ -543,7 +564,7 @@
543
564
  }
544
565
  .field:has(input:focus-visible) .label,
545
566
  .field:has(textarea:focus-visible) .label {
546
- color: var(--np-color-primary);
567
+ color: var(--_label-text-color, var(--np-color-primary));
547
568
  }
548
569
  .error .label,
549
570
  .error:has(input:focus-visible) .label,
@@ -698,7 +719,7 @@
698
719
 
699
720
  .field:has(input:focus-visible) .np-outline,
700
721
  .field:has(textarea:focus-visible) .np-outline {
701
- border-color: var(--np-color-primary);
722
+ border-color: var(--np-outlined-text-field-focus-outline-color, var(--np-color-primary));
702
723
  color: var(--np-color-primary);
703
724
  }
704
725
  .error .np-outline,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "noph-ui",
3
- "version": "0.12.3",
3
+ "version": "0.12.5",
4
4
  "license": "MIT",
5
5
  "homepage": "https://noph.dev",
6
6
  "repository": {