use-wc 1.0.0-pre.34 → 1.0.0-pre.35

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.
@@ -134,7 +134,7 @@
134
134
  --usewc-layout-focus-ring-offset-outside: var(--usewc-space-2);
135
135
  --usewc-layout-focus-ring-offset-inside: var(--usewc-space-none);
136
136
  --usewc-effect-focus-ring-style: solid;
137
- --usewc-transition-focus-ring: 0.05s ease-in-out;
137
+ --usewc-transition-focus-ring: outline 0.05s ease-in-out;
138
138
  --usewc-effect-control-opacity-disabled: 0.5;
139
139
  /* - Link */
140
140
  --usewc-color-link-text-static: var(--usewc-color-blue-500);
@@ -175,8 +175,12 @@
175
175
  --usewc-color-input-segment-background-focus: var(--usewc-color-blue-100);
176
176
  --usewc-color-input-segment-text-focus: var(--usewc-color-gray-700);
177
177
  --usewc-effect-dropdown-trigger-background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M12 16L5.0718 8.5L18.9282 8.5L12 16Z' fill='rgba(255,255,255,0.5' /%3E%3C/svg%3E");
178
+ --usewc-effect-dropdown-trigger-side-background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M16 12L8.5 18.9282L8.5 5.0718Z' fill='rgba(255,255,255,0.5' /%3E%3C/svg%3E");
178
179
  --usewc-effect-dropdown-trigger-background-size: 1em;
179
180
  --usewc-effect-dropdown-trigger-background-blend-mode: difference;
181
+ --usewc-effect-menu-item-checkmark-background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 24 24' fill='none' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M5 13L10 18L19 7' stroke='rgba(255,255,255,0.5)' stroke-width='2' stroke-linecap='round' stroke-linejoin='round'/%3E%3C%2Fsvg%3E");
182
+ --usewc-effect-menu-item-checkmark-background-size: 1em;
183
+ --usewc-effect-menu-item-checkmark-background-blend-mode: difference;
180
184
  /* - Layout */
181
185
  --usewc-layout-input-border: var(--usewc-space-1-relative);
182
186
  --usewc-layout-input-padding-block: calc(var(--usewc-space-4) - var(--usewc-layout-input-border));
@@ -312,6 +316,30 @@
312
316
  --usewc-layout-button-extra-large-font-size: var(--usewc-font-size-24);
313
317
  --usewc-layout-button-extra-large-line-height: var(--usewc-line-height-28);
314
318
 
319
+ /* Menu */
320
+ --usewc-layout-popover-menu-item-padding-inline: var(--usewc-space-4);
321
+ --usewc-layout-popover-menu-item-padding-block: var(--usewc-space-2);
322
+ --usewc-layout-popover-menu-item-line-height: var(--usewc-line-height-24);
323
+ --usewc-color-popover-menu-item-background-static: var(--usewc-color-transparent);
324
+ --usewc-color-popover-menu-item-background-hover: var(--usewc-color-gray-800);
325
+ --usewc-color-popover-menu-item-background-active: var(--usewc-color-gray-800);
326
+ --usewc-effect-popover-menu-item-border-radius: var(--usewc-effect-border-radius-4);
327
+ --usewc-layout-popover-menu-anchor-offset: var(--usewc-space-4);
328
+ --usewc-layout-popover-menu-padding: var(--usewc-space-4);
329
+ --usewc-layout-popover-menu-border: var(--usewc-space-1-relative);
330
+ --usewc-effect-popover-menu-border-style: var(--usewc-effect-border-solid);
331
+ --usewc-color-popover-menu-background: var(--usewc-color-canvas-background);
332
+ --usewc-color-popover-menu-border: var(--usewc-color-gray-600);
333
+ --usewc-effect-popover-menu-border-radius: var(--usewc-effect-border-radius-8);
334
+ --usewc-layout-popover-menu-header-font-size: var(--usewc-font-size-14);
335
+ --usewc-font-popover-menu-header-weight: var(--usewc-font-weight-medium);
336
+ --usewc-color-popover-menu-header-text: var(--usewc-color-gray-400);
337
+ --usewc-font-popover-menu-shortcut: var(--usewc-font-family-monospace);
338
+ --usewc-color-popover-menu-shortcut: var(--usewc-color-gray-400);
339
+ --usewc-color-popover-menu-item-text-static: var(--usewc-color-button-base-text-static);
340
+ --usewc-color-popover-menu-item-text-hover: var(--usewc-color-button-base-text-static);
341
+ --usewc-color-popover-menu-item-text-focus: var(--usewc-color-button-base-text-static);
342
+
315
343
  /* Inline code */
316
344
  --usewc-layout-code-padding-inline: var(--usewc-space-4);
317
345
  --usewc-layout-code-padding-block: var(--usewc-space-none);
@@ -328,7 +356,7 @@
328
356
  --usewc-color-document-text: var(--usewc-color-gray-200);
329
357
  --usewc-color-document-text-muted: var(--usewc-color-gray-300);
330
358
  --usewc-color-document-background: var(--usewc-color-gray-800);
331
- --usewc-color-canvas-background: var(--usewc-color-white);
359
+ --usewc-color-canvas-background: var(--usewc-color-black);
332
360
  --usewc-color-focus-ring: var(--usewc-color-blue-200);
333
361
  --usewc-color-input-background-static: oklch(from var(--usewc-color-gray-100) l c h / 0.025);
334
362
  --usewc-color-input-border-static: var(--usewc-color-gray-600);
@@ -14,9 +14,10 @@
14
14
  font-size: var(--usewc-layout-document-text-size);
15
15
  }
16
16
 
17
- :is(button, a, details summary):not([data-appear-as="native"]):focus-visible,
17
+ :is(button, a, details summary, use-widget):not([data-appear-as="native"]):focus-visible,
18
18
  :is(input, textarea, select, use-date, use-time, use-datetime, use-duration):not([data-appear-as="native"]):focus,
19
19
  input[type="file"]:not([data-appear-as="native"]):focus-visible,
20
+ use-dropdown:not([data-appear-as="native"])::part(trigger):focus-visible,
20
21
  [data-appear-as="input"]:has(input:focus) {
21
22
  outline: var(--usewc-layout-focus-ring-size) var(--usewc-effect-focus-ring-style) var(--usewc-color-focus-ring);
22
23
  outline-offset: var(--usewc-layout-focus-ring-offset-outside);
@@ -32,7 +33,8 @@
32
33
  use-time:not([data-appear-as="native"]),
33
34
  use-datetime:not([data-appear-as="native"]),
34
35
  use-duration:not([data-appear-as="native"])
35
- ) {
36
+ ),
37
+ use-listbox-input:not([data-appear-as="native"])::part(listbox) {
36
38
  border: var(--usewc-layout-input-border) var(--usewc-effect-input-border-style)
37
39
  var(--usewc-color-input-border-static);
38
40
  line-height: var(--usewc-layout-input-line-height);
@@ -71,15 +73,12 @@
71
73
  }
72
74
  }
73
75
 
76
+ use-listbox-input:not([data-appear-as="native"])::part(listbox) {
77
+ padding: var(--usewc-layout-popover-menu-padding);
78
+ }
79
+
74
80
  select:not([data-appear-as="native"]) {
75
81
  appearance: none;
76
- padding-inline-end: calc(var(--usewc-layout-input-padding-inline) * 2 + var(--usewc-layout-selector-width));
77
- background-image: var(--usewc-effect-dropdown-trigger-background-image, none);
78
- /* TODO use logical position */
79
- background-position: right var(--usewc-layout-input-padding-inline) center;
80
- background-repeat: no-repeat;
81
- background-size: var(--usewc-effect-dropdown-trigger-background-size, 1em);
82
- background-blend-mode: var(--usewc-effect-dropdown-trigger-background-blend-mode, none);
83
82
  }
84
83
 
85
84
  [data-appear-as="input"] {
@@ -212,6 +211,7 @@
212
211
  }
213
212
 
214
213
  :is(button:not([data-appear-as]), [data-appear-as="button"]),
214
+ use-dropdown,
215
215
  input[type="file"]:not([data-appear-as]) {
216
216
  &:where(:not(button)),
217
217
  &::file-selector-button {
@@ -233,7 +233,8 @@
233
233
  --usewc-theme-color-button-background-active: var(--usewc-color-button-base-background-active);
234
234
  --usewc-theme-color-button-border-active: var(--usewc-color-button-base-border-active);
235
235
 
236
- &:not([type="file"]),
236
+ &::part(trigger),
237
+ &:not([type="file"], use-dropdown),
237
238
  &::file-selector-button {
238
239
  display: inline-flex;
239
240
  align-items: center;
@@ -254,18 +255,24 @@
254
255
  var(--usewc-theme-color-button-border-static);
255
256
  }
256
257
 
258
+ &:is(use-dropdown) {
259
+ display: contents;
260
+ }
261
+
257
262
  &::file-selector-button {
258
263
  margin-inline-end: var(--usewc-layout-input-gap-inline);
259
264
  }
260
265
 
261
- &:is(:hover, :focus-visible):not([type="file"]),
266
+ &:is(:hover, :focus-visible):not([type="file"], use-dropdown),
267
+ &::part(trigger):is(:hover, :focus-visible),
262
268
  &:is(:hover, :focus-visible)::file-selector-button {
263
269
  background: var(--usewc-theme-color-button-background-hover);
264
270
  border-color: var(--usewc-theme-color-button-border-hover);
265
271
  color: var(--usewc-theme-color-button-text-hover);
266
272
  }
267
273
 
268
- &:active:not([type="file"]),
274
+ &:active:not([type="file"], use-dropdown),
275
+ &:active::part(trigger),
269
276
  &:active::file-selector-button {
270
277
  background: var(--usewc-theme-color-button-background-active);
271
278
  border-color: var(--usewc-theme-color-button-border-active);
@@ -523,4 +530,152 @@
523
530
  gap: var(--usewc-layout-input-segment-padding-inline);
524
531
  }
525
532
  }
533
+
534
+ select:not([data-appear-as="native"]),
535
+ use-dropdown::part(trigger),
536
+ use-dropdown use-dropdown::part(trigger) {
537
+ padding-inline-end: calc(var(--usewc-layout-input-padding-inline) * 2 + var(--usewc-layout-selector-width));
538
+ background-image: var(--usewc-effect-dropdown-trigger-background-image, none);
539
+ /* TODO use logical position */
540
+ background-position: right var(--usewc-layout-input-padding-inline) center;
541
+ background-repeat: no-repeat;
542
+ background-size: var(--usewc-effect-dropdown-trigger-background-size, 1em);
543
+ background-blend-mode: var(--usewc-effect-dropdown-trigger-background-blend-mode, none);
544
+ }
545
+
546
+ use-dropdown use-dropdown::part(trigger) {
547
+ background-image: var(--usewc-effect-dropdown-trigger-side-background-image);
548
+ background-position: right center;
549
+ }
550
+
551
+ select:not([data-appear-as="native"]),
552
+ use-dropdown::part(trigger),
553
+ use-dropdown use-dropdown::part(trigger) {
554
+ anchor-name: --use-popover-trigger;
555
+ }
556
+
557
+ use-dropdown::part(trigger-icon-default),
558
+ use-option::part(selected-indicator-default) {
559
+ display: none;
560
+ }
561
+
562
+ use-dropdown::part(menu) {
563
+ border: var(--usewc-layout-popover-menu-border) var(--usewc-effect-popover-menu-border-style)
564
+ var(--usewc-color-popover-menu-border);
565
+ padding: var(--usewc-layout-popover-menu-padding);
566
+ background: var(--usewc-color-popover-menu-background);
567
+ border-radius: var(--usewc-effect-popover-menu-border-radius);
568
+ margin: unset;
569
+ }
570
+
571
+ use-dropdown::part(menu) {
572
+ inset: unset;
573
+ position: fixed;
574
+ position-anchor: --use-popover-trigger;
575
+ inset-block-start: calc(anchor(end) + var(--usewc-layout-popover-menu-anchor-offset));
576
+ inset-inline-start: anchor(start);
577
+ position-try-fallbacks:
578
+ flip-block,
579
+ flip-inline,
580
+ flip-inline flip-block;
581
+ }
582
+
583
+ use-option,
584
+ use-dropdown :is([role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"]),
585
+ use-dropdown use-dropdown::part(trigger) {
586
+ border: none;
587
+ text-align: start;
588
+ cursor: default;
589
+ display: flex;
590
+ flex-direction: row;
591
+ justify-content: start;
592
+ gap: var(--usewc-layout-popover-menu-item-padding-inline);
593
+ line-height: var(--usewc-layout-popover-menu-item-line-height);
594
+ padding-inline: var(--usewc-layout-popover-menu-item-padding-inline);
595
+ padding-block: var(--usewc-layout-popover-menu-item-padding-block);
596
+ background-color: var(--usewc-color-popover-menu-item-background-static);
597
+ border-radius: var(--usewc-effect-popover-menu-item-border-radius);
598
+ color: var(--usewc-color-popover-menu-item-text-static);
599
+ text-decoration: none;
600
+
601
+ > *:last-child:not(:first-child) {
602
+ flex: 0 0 auto;
603
+ margin-inline-start: auto;
604
+ }
605
+ }
606
+
607
+ use-listbox-input:is(:hover, :focus) use-option:state(active) {
608
+ background-color: var(--usewc-color-popover-menu-item-background-active);
609
+ }
610
+
611
+ use-dropdown :is([role="menuitem"], [role="menuitemcheckbox"], [role="menuitemradio"], use-dropdown),
612
+ use-listbox-input {
613
+ &:not(use-dropdown):hover,
614
+ &::part(trigger):hover {
615
+ background-color: var(--usewc-color-popover-menu-item-background-hover);
616
+ color: var(--usewc-color-popover-menu-item-text-hover);
617
+ }
618
+
619
+ &:focus-visible,
620
+ &::part(trigger):focus-visible {
621
+ background-color: var(--usewc-color-popover-menu-item-background-static);
622
+ outline: var(--usewc-layout-focus-ring-size) var(--usewc-effect-focus-ring-style) var(--usewc-color-focus-ring);
623
+ outline-offset: var(--usewc-layout-focus-ring-offset-inside);
624
+ transition: var(--usewc-transition-focus-ring);
625
+ color: var(--usewc-color-popover-menu-item-text-focus);
626
+ }
627
+ }
628
+
629
+ use-listbox-input,
630
+ use-dropdown :is([role="menuitemcheckbox"], [role="menuitemradio"]) {
631
+ use-option,
632
+ &:has(+ :is([role="menuitemcheckbox"], [role="menuitemradio"])),
633
+ & + :is(:is([role="menuitemcheckbox"], [role="menuitemradio"])) {
634
+ padding-inline-start: calc(var(--usewc-layout-input-padding-inline) * 2 + var(--usewc-layout-selector-width));
635
+ }
636
+ }
637
+
638
+ use-dropdown,
639
+ use-listbox-input {
640
+ [role="group"][aria-label] {
641
+ &::before {
642
+ content: attr(aria-label);
643
+ padding: var(--usewc-layout-popover-menu-padding);
644
+ font-size: var(--usewc-layout-popover-menu-header-font-size);
645
+ font-weight: var(--usewc-effect-popover-menu-header-font-weight);
646
+ color: var(--usewc-color-popover-menu-header-text);
647
+ }
648
+ }
649
+
650
+ kbd {
651
+ font-family: var(--usewc-font-popover-menu-shortcut);
652
+ color: var(--usewc-color-popover-menu-shortcut);
653
+ margin-inline-start: auto;
654
+ }
655
+
656
+ hr {
657
+ border: 0;
658
+ border-block-start: var(--usewc-layout-popover-menu-border) var(--usewc-effect-popover-menu-border-style)
659
+ var(--usewc-color-popover-menu-border);
660
+ margin-block: var(--usewc-layout-popover-menu-padding);
661
+ }
662
+ }
663
+
664
+ use-dropdown use-dropdown::part(menu) {
665
+ margin-inline-start: 0.5rem;
666
+ inset-block-start: calc(
667
+ anchor(start) - var(--usewc-layout-popover-menu-padding) - var(--usewc-layout-popover-menu-border)
668
+ );
669
+ inset-inline-start: anchor(end);
670
+ }
671
+
672
+ use-dropdown [aria-checked="true"],
673
+ use-option:state(selected) {
674
+ background-image: var(--usewc-effect-menu-item-checkmark-background-image, none);
675
+ /* TODO use logical position */
676
+ background-position: left var(--usewc-layout-input-padding-inline) center;
677
+ background-repeat: no-repeat;
678
+ background-size: var(--usewc-effect-menu-item-checkmark-background-size, 1em);
679
+ background-blend-mode: var(--usewc-effect-menu-item-checkmark-background-blend-mode, none);
680
+ }
526
681
  }
package/dist/use-wc.mjs CHANGED
@@ -672,7 +672,9 @@ let UseDropdown = class UseDropdown extends LitElement {
672
672
  >
673
673
  <slot name="trigger-content">
674
674
  <slot part="trigger-label" name="trigger-label">${this.label}</slot>
675
- <slot part="trigger-icon" name="trigger-icon">${this.#triggerIconText}</slot>
675
+ <slot part="trigger-icon" name="trigger-icon">
676
+ <span part="trigger-icon-default" aria-hidden="true">${this.#triggerIconText}</span>
677
+ </slot>
676
678
  </slot>
677
679
  </button>
678
680
  <div
@@ -1068,6 +1070,13 @@ let UseListboxInput = class UseListboxInput extends LitElement {
1068
1070
  get value() {
1069
1071
  return this.#value;
1070
1072
  }
1073
+ #handleMouseOver(event) {
1074
+ const option = event.target?.closest("use-option");
1075
+ if (option && !option.disabled) this.activeOption = option;
1076
+ }
1077
+ #handleFocus() {
1078
+ if (!this.activeOption) this.activeOption = this.firstSelected ?? this.options.at(0) ?? null;
1079
+ }
1071
1080
  #handleKeyDown(event) {
1072
1081
  if (this.disabled) return;
1073
1082
  if (["Enter", " "].includes(event.key) && this.activeOption) {
@@ -1083,12 +1092,12 @@ let UseListboxInput = class UseListboxInput extends LitElement {
1083
1092
  case "ArrowUp":
1084
1093
  event.preventDefault();
1085
1094
  event.stopPropagation();
1086
- if (activeIndex > 0) moveTo = options.at(activeIndex - 1);
1095
+ moveTo = activeIndex > 0 ? options.at(activeIndex - 1) : options.at(-1);
1087
1096
  break;
1088
1097
  case "ArrowDown":
1089
1098
  event.preventDefault();
1090
1099
  event.stopPropagation();
1091
- moveTo = options.at(activeIndex + 1);
1100
+ moveTo = activeIndex < options.length - 1 ? options.at(activeIndex + 1) : options.at(0);
1092
1101
  break;
1093
1102
  case "Home":
1094
1103
  event.preventDefault();
@@ -1111,6 +1120,8 @@ let UseListboxInput = class UseListboxInput extends LitElement {
1111
1120
  tabindex=${0}
1112
1121
  @click=${this.#handleClick}
1113
1122
  @keydown=${this.#handleKeyDown}
1123
+ @focus=${this.#handleFocus}
1124
+ @mouseover=${this.#handleMouseOver}
1114
1125
  >
1115
1126
  <slot></slot>
1116
1127
  </div>
@@ -1131,9 +1142,7 @@ let UseListboxInput = class UseListboxInput extends LitElement {
1131
1142
  opacity: 0.5;
1132
1143
  }
1133
1144
 
1134
- /* https://github.com/w3c/csswg-drafts/issues/5893 */
1135
- [part="listbox"]:not(:hover):focus-visible ::slotted(use-option:state(active)),
1136
- ::slotted(use-option:not(:state(disabled)):hover) {
1145
+ ::slotted(use-option:state(active)) {
1137
1146
  background-color: light-dark(rgba(0, 0, 0, 0.1), rgba(255, 255, 255, 0.1));
1138
1147
  }
1139
1148
  `;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "use-wc",
3
- "version": "1.0.0-pre.34",
3
+ "version": "1.0.0-pre.35",
4
4
  "private": false,
5
5
  "homepage": "https://usewc.com",
6
6
  "bugs": "https://github.com/dang-rabbits/use-wc/issues",