@threadlabs/looma 0.23.22 → 0.23.23

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/vue/UiButton.vue CHANGED
@@ -4,6 +4,7 @@ import { computed, getCurrentInstance, useTemplateRef, watchSyncEffect } from 'v
4
4
  import type { PropType } from 'vue'
5
5
  import { createDispatch, preserveRootFocus, useComponentHost } from './host'
6
6
  import { checkedProp, propValidityState, vPropValidity } from './props'
7
+ import UiIcon from './UiIcon.vue'
7
8
  import UiSpinner from './UiSpinner.vue'
8
9
 
9
10
  defineOptions({ inheritAttrs: false })
@@ -119,8 +120,8 @@ const propValidityContract = {
119
120
  required: false,
120
121
  target: { attribute: 'variant' },
121
122
  description:
122
- 'Emphasis: how loudly the button asks. solid fills with its tone, outline draws its tone at the edge over a wash of it, ghost carries only text until it is\n hovered, and link is an inline text action that reads as a link. danger is solid in the danger tone, kept for the call sites that name it.',
123
- values: ['outline', 'solid', 'danger', 'ghost', 'link'],
123
+ 'Emphasis: how loudly the button asks. solid fills with its tone, outline draws its tone at the edge over a wash of it, ghost carries only text until it is\n hovered, and link is an inline text action that reads as a link. danger is solid in the danger tone, kept for the call sites that name it. card uses the\n same tone on a full-width action with an icon slot, wrapping content, and a centered action slot.',
124
+ values: ['outline', 'solid', 'danger', 'ghost', 'link', 'card'],
124
125
  default: 'outline',
125
126
  },
126
127
  },
@@ -148,7 +149,9 @@ const props = defineProps({
148
149
  default: 'button',
149
150
  },
150
151
  variant: {
151
- type: null as unknown as PropType<'outline' | 'solid' | 'danger' | 'ghost' | 'link' | null>,
152
+ type: null as unknown as PropType<
153
+ 'outline' | 'solid' | 'danger' | 'ghost' | 'link' | 'card' | null
154
+ >,
152
155
  default: 'outline',
153
156
  },
154
157
  })
@@ -260,13 +263,13 @@ const checkedProps = computed(() => ({
260
263
  'type',
261
264
  acceptedProps,
262
265
  ) as 'button' | 'submit' | 'reset',
263
- variant: checkedProp<'outline' | 'solid' | 'danger' | 'ghost' | 'link'>(
266
+ variant: checkedProp<'outline' | 'solid' | 'danger' | 'ghost' | 'link' | 'card'>(
264
267
  props['variant'],
265
268
  { kind: 'terminal', name: 'keyword' },
266
269
  false,
267
270
  'variant',
268
271
  acceptedProps,
269
- ) as 'outline' | 'solid' | 'danger' | 'ghost' | 'link',
272
+ ) as 'outline' | 'solid' | 'danger' | 'ghost' | 'link' | 'card',
270
273
  }))
271
274
  void checkedProps.value
272
275
  watchSyncEffect(() => {
@@ -448,11 +451,155 @@ const guardedBinding3 = computed(() => {
448
451
  concat(checkedProps.value.loading || checkedProps.value.pending),
449
452
  ))
450
453
  })
454
+ let guardedBinding4Previous: any = null
455
+ const guardedBinding4 = computed(() => {
456
+ const candidate: any = ((objectValue: any, indexValue: any) =>
457
+ objectValue === Symbol.for('html-next.invalid-result')
458
+ || indexValue === Symbol.for('html-next.invalid-result')
459
+ ? Symbol.for('html-next.invalid-result')
460
+ : objectValue[indexValue])(
461
+ { true: null, false: checkedProps.value.href },
462
+ concat(
463
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
464
+ ),
465
+ )
466
+ if (candidate === Symbol.for('html-next.invalid-result')) {
467
+ return guardedBinding4Previous
468
+ }
469
+ return guardedBinding4Previous = attribute(((objectValue: any, indexValue: any) =>
470
+ objectValue === Symbol.for('html-next.invalid-result')
471
+ || indexValue === Symbol.for('html-next.invalid-result')
472
+ ? Symbol.for('html-next.invalid-result')
473
+ : objectValue[indexValue])(
474
+ { true: null, false: checkedProps.value.href },
475
+ concat(
476
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
477
+ ),
478
+ ))
479
+ })
480
+ let guardedBinding5Previous: any = null
481
+ const guardedBinding5 = computed(() => {
482
+ const candidate: any = ((objectValue: any, indexValue: any) =>
483
+ objectValue === Symbol.for('html-next.invalid-result')
484
+ || indexValue === Symbol.for('html-next.invalid-result')
485
+ ? Symbol.for('html-next.invalid-result')
486
+ : objectValue[indexValue])(
487
+ { true: 'true', false: null },
488
+ concat(
489
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
490
+ ),
491
+ )
492
+ if (candidate === Symbol.for('html-next.invalid-result')) {
493
+ return guardedBinding5Previous
494
+ }
495
+ return guardedBinding5Previous = typeof (((objectValue: any, indexValue: any) =>
496
+ objectValue === Symbol.for('html-next.invalid-result')
497
+ || indexValue === Symbol.for('html-next.invalid-result')
498
+ ? Symbol.for('html-next.invalid-result')
499
+ : objectValue[indexValue])(
500
+ { true: 'true', false: null },
501
+ concat(
502
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
503
+ ),
504
+ )) === 'boolean'
505
+ ? String(((objectValue: any, indexValue: any) =>
506
+ objectValue === Symbol.for('html-next.invalid-result')
507
+ || indexValue === Symbol.for('html-next.invalid-result')
508
+ ? Symbol.for('html-next.invalid-result')
509
+ : objectValue[indexValue])(
510
+ { true: 'true', false: null },
511
+ concat(
512
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
513
+ ),
514
+ ))
515
+ : attribute(((objectValue: any, indexValue: any) =>
516
+ objectValue === Symbol.for('html-next.invalid-result')
517
+ || indexValue === Symbol.for('html-next.invalid-result')
518
+ ? Symbol.for('html-next.invalid-result')
519
+ : objectValue[indexValue])(
520
+ { true: 'true', false: null },
521
+ concat(
522
+ checkedProps.value.disabled || checkedProps.value.loading || checkedProps.value.pending,
523
+ ),
524
+ ))
525
+ })
526
+ let guardedBinding6Previous: any = null
527
+ const guardedBinding6 = computed(() => {
528
+ const candidate: any = ((objectValue: any, indexValue: any) =>
529
+ objectValue === Symbol.for('html-next.invalid-result')
530
+ || indexValue === Symbol.for('html-next.invalid-result')
531
+ ? Symbol.for('html-next.invalid-result')
532
+ : objectValue[indexValue])(
533
+ { true: '0', false: null },
534
+ concat(
535
+ (checkedProps.value.loading || checkedProps.value.pending) && !checkedProps.value.disabled,
536
+ ),
537
+ )
538
+ if (candidate === Symbol.for('html-next.invalid-result')) {
539
+ return guardedBinding6Previous
540
+ }
541
+ return guardedBinding6Previous = attribute(
542
+ ((objectValue: any, indexValue: any) =>
543
+ objectValue === Symbol.for('html-next.invalid-result')
544
+ || indexValue === Symbol.for('html-next.invalid-result')
545
+ ? Symbol.for('html-next.invalid-result')
546
+ : objectValue[indexValue])(
547
+ { true: '0', false: null },
548
+ concat(
549
+ (checkedProps.value.loading || checkedProps.value.pending)
550
+ && !checkedProps.value.disabled,
551
+ ),
552
+ ),
553
+ )
554
+ })
555
+ let guardedBinding7Previous: any = null
556
+ const guardedBinding7 = computed(() => {
557
+ const candidate: any = ((objectValue: any, indexValue: any) =>
558
+ objectValue === Symbol.for('html-next.invalid-result')
559
+ || indexValue === Symbol.for('html-next.invalid-result')
560
+ ? Symbol.for('html-next.invalid-result')
561
+ : objectValue[indexValue])(
562
+ { true: 'true', false: null },
563
+ concat(checkedProps.value.loading || checkedProps.value.pending),
564
+ )
565
+ if (candidate === Symbol.for('html-next.invalid-result')) {
566
+ return guardedBinding7Previous
567
+ }
568
+ return guardedBinding7Previous = typeof (((objectValue: any, indexValue: any) =>
569
+ objectValue === Symbol.for('html-next.invalid-result')
570
+ || indexValue === Symbol.for('html-next.invalid-result')
571
+ ? Symbol.for('html-next.invalid-result')
572
+ : objectValue[indexValue])(
573
+ { true: 'true', false: null },
574
+ concat(checkedProps.value.loading || checkedProps.value.pending),
575
+ )) === 'boolean'
576
+ ? String(((objectValue: any, indexValue: any) =>
577
+ objectValue === Symbol.for('html-next.invalid-result')
578
+ || indexValue === Symbol.for('html-next.invalid-result')
579
+ ? Symbol.for('html-next.invalid-result')
580
+ : objectValue[indexValue])(
581
+ { true: 'true', false: null },
582
+ concat(checkedProps.value.loading || checkedProps.value.pending),
583
+ ))
584
+ : attribute(((objectValue: any, indexValue: any) =>
585
+ objectValue === Symbol.for('html-next.invalid-result')
586
+ || indexValue === Symbol.for('html-next.invalid-result')
587
+ ? Symbol.for('html-next.invalid-result')
588
+ : objectValue[indexValue])(
589
+ { true: 'true', false: null },
590
+ concat(checkedProps.value.loading || checkedProps.value.pending),
591
+ ))
592
+ })
451
593
  const hydrationNode = hydrationInstance?.vnode.el
452
594
  if (
453
595
  typeof window !== 'undefined' && hydrationNode != null
454
596
  && (!(hydrationNode instanceof Element)
455
- || hydrationNode.localName !== ((checkedProps.value.as === 'a') ? 'a' : ('button')))
597
+ || hydrationNode.localName
598
+ !== ((checkedProps.value.variant === 'card' && checkedProps.value.as === 'a')
599
+ ? 'a'
600
+ : ((checkedProps.value.variant === 'card')
601
+ ? 'button'
602
+ : ((checkedProps.value.as === 'a') ? 'a' : ('button')))))
456
603
  ) {
457
604
  throw Object.assign(new Error('HR005: Server markup for <ui-button> has an incompatible root.'), {
458
605
  name: 'HtmlDiagnosticError',
@@ -554,7 +701,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
554
701
 
555
702
  <template>
556
703
  <a
557
- v-if="checkedProps.as === 'a'"
704
+ v-if="checkedProps.variant === 'card' && checkedProps.as === 'a'"
558
705
  data-component="ui-button"
559
706
  v-bind="nativeAttrs($attrs)"
560
707
  :href="guarded"
@@ -580,6 +727,84 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
580
727
  :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
581
728
  :data-ui-button-state="hostState || undefined"
582
729
  ref="@html-next/root"
730
+ ><span class="card-icon"><UiSpinner
731
+ v-if="checkedProps.loading || checkedProps.pending"
732
+ size="sm"
733
+ />
734
+ <template v-if="!(checkedProps.loading || checkedProps.pending)"><slot
735
+ name="icon"
736
+ /></template></span>
737
+ <span class="card-content"><slot /></span>
738
+ <span class="card-action"><slot name="action"><UiIcon
739
+ name="chevron-right"
740
+ aria-hidden="true"
741
+ /></slot></span></a>
742
+ <button
743
+ v-else-if="checkedProps.variant === 'card'"
744
+ data-component="ui-button"
745
+ v-bind="nativeAttrs($attrs)"
746
+ :type="checkedProps.type ?? undefined"
747
+ :disabled="checkedProps.disabled ?? undefined"
748
+ :aria-disabled="guardedBinding3"
749
+ :aria-busy="checkedProps.loading || checkedProps.pending"
750
+ v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
751
+ :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
752
+ :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
753
+ :data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
754
+ :data-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
755
+ :data-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
756
+ :data-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
757
+ :data-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
758
+ :data-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
759
+ :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
760
+ :data-stretch="reflectedProp('stretch', 'stretch', checkedProps.stretch, undefined, false)"
761
+ :data-target="reflectedProp('target', 'target', checkedProps.target, undefined, false)"
762
+ :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
763
+ :data-type="reflectedProp('type', 'type', checkedProps.type, undefined, false)"
764
+ :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
765
+ :data-ui-button-state="hostState || undefined"
766
+ ref="@html-next/root"
767
+ >
768
+ <span class="card-icon"><UiSpinner
769
+ v-if="checkedProps.loading || checkedProps.pending"
770
+ size="sm"
771
+ />
772
+ <template v-if="!(checkedProps.loading || checkedProps.pending)"><slot
773
+ name="icon"
774
+ /></template></span>
775
+ <span class="card-content"><slot /></span>
776
+ <span class="card-action"><slot name="action"><UiIcon
777
+ name="chevron-right"
778
+ aria-hidden="true"
779
+ /></slot></span>
780
+ </button>
781
+ <a
782
+ v-else-if="checkedProps.as === 'a'"
783
+ data-component="ui-button"
784
+ v-bind="nativeAttrs($attrs)"
785
+ :href="guardedBinding4"
786
+ :target="checkedProps.target ?? undefined"
787
+ :rel="checkedProps.rel ?? undefined"
788
+ :aria-disabled="guardedBinding5"
789
+ :aria-busy="checkedProps.loading || checkedProps.pending"
790
+ :tabindex="guardedBinding6"
791
+ v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
792
+ :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
793
+ :data-as="reflectedProp('as', 'as', checkedProps.as, undefined, false)"
794
+ :data-disabled="reflectedProp('disabled', 'disabled', checkedProps.disabled, undefined, false)"
795
+ :data-href="reflectedProp('href', 'href', checkedProps.href, undefined, false)"
796
+ :data-loading="reflectedProp('loading', 'loading', checkedProps.loading, undefined, false)"
797
+ :data-pending="reflectedProp('pending', 'pending', checkedProps.pending, undefined, false)"
798
+ :data-rel="reflectedProp('rel', 'rel', checkedProps.rel, undefined, false)"
799
+ :data-shape="reflectedProp('shape', 'shape', checkedProps.shape, undefined, false)"
800
+ :data-size="reflectedProp('size', 'size', checkedProps.size, undefined, false)"
801
+ :data-stretch="reflectedProp('stretch', 'stretch', checkedProps.stretch, undefined, false)"
802
+ :data-target="reflectedProp('target', 'target', checkedProps.target, undefined, false)"
803
+ :data-tone="reflectedProp('tone', 'tone', checkedProps.tone, undefined, false)"
804
+ :data-type="reflectedProp('type', 'type', checkedProps.type, undefined, false)"
805
+ :data-variant="reflectedProp('variant', 'variant', checkedProps.variant, undefined, false)"
806
+ :data-ui-button-state="hostState || undefined"
807
+ ref="@html-next/root"
583
808
  ><span v-if="checkedProps.loading || checkedProps.pending" class="spinner-wrap"><UiSpinner
584
809
  size="sm"
585
810
  /></span>
@@ -590,7 +815,7 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
590
815
  v-bind="nativeAttrs($attrs)"
591
816
  :type="checkedProps.type ?? undefined"
592
817
  :disabled="checkedProps.disabled ?? undefined"
593
- :aria-disabled="guardedBinding3"
818
+ :aria-disabled="guardedBinding7"
594
819
  :aria-busy="checkedProps.loading || checkedProps.pending"
595
820
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
596
821
  :data-align="reflectedProp('align', 'align', checkedProps.align, undefined, false)"
@@ -790,6 +1015,42 @@ function concat<T extends unknown[]>(...values: T): ConcatResult<T> {
790
1015
  font-size: var(--ui-font-size-md);
791
1016
  }
792
1017
 
1018
+ /* Card actions inherit Button's palette and behavior; only their shared layout changes.
1019
+ The icon may contain any decorative composition. Empty icons remove their column. */
1020
+ [data-component~="ui-button"][data-ui-button-state~="variant=card"] {
1021
+ display: grid;
1022
+ grid-template-columns: auto minmax(0, 1fr) auto;
1023
+ align-items: start;
1024
+ gap: var(--ui-space-3);
1025
+ inline-size: 100%;
1026
+ min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-md));
1027
+ text-align: start;
1028
+ white-space: normal;
1029
+ box-shadow: none;
1030
+ background-image: none;
1031
+ }
1032
+ [data-component~="ui-button"][data-ui-button-state~="variant=card"][data-ui-button-state~="size=lg"] {
1033
+ min-block-size: max(var(--ui-control-min-block-size), var(--ui-control-size-lg));
1034
+ }
1035
+ [data-component~="ui-button"][data-ui-button-state~="variant=card"]:has(.card-icon:empty) {
1036
+ grid-template-columns: minmax(0, 1fr) auto;
1037
+ }
1038
+ .card-icon {
1039
+ display: flex;
1040
+ align-items: flex-start;
1041
+ }
1042
+ .card-icon:empty {
1043
+ display: none;
1044
+ }
1045
+ .card-content {
1046
+ min-inline-size: 0;
1047
+ }
1048
+ .card-action {
1049
+ display: flex;
1050
+ align-items: center;
1051
+ align-self: center;
1052
+ }
1053
+
793
1054
  /* A link is never :enabled, so interactive states test "not unavailable" instead: for a button that
794
1055
  is exactly :enabled, at the same specificity, and it also matches a link that can be followed. */
795
1056
  [data-component~="ui-button"]:hover:not(:disabled, [aria-disabled="true"]) {
@@ -44,7 +44,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
44
44
  default: boolean;
45
45
  };
46
46
  }>> & Readonly<{}>, {
47
- variant: "row" | "card" | null;
47
+ variant: "card" | "row" | null;
48
48
  current: boolean | null;
49
49
  wrap: boolean | null;
50
50
  highlighted: boolean | null;
@@ -35,7 +35,7 @@ declare const __VLS_base: import("vue").DefineComponent<import("vue").ExtractPro
35
35
  };
36
36
  }>> & Readonly<{}>, {
37
37
  tone: "neutral" | "danger" | null;
38
- variant: "plain" | "card" | "divided" | null;
38
+ variant: "card" | "plain" | "divided" | null;
39
39
  heading: string | null;
40
40
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
41
41
  declare const __VLS_export: __VLS_WithSlots<typeof __VLS_base, __VLS_Slots>;
@@ -1,5 +1,9 @@
1
1
  import type { PropType } from 'vue';
2
2
  declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
3
+ emphasis: {
4
+ type: PropType<"normal" | "strong" | null>;
5
+ default: string;
6
+ };
3
7
  orientation: {
4
8
  type: PropType<"horizontal" | "vertical" | null>;
5
9
  default: string;
@@ -13,6 +17,10 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
13
17
  default: boolean;
14
18
  };
15
19
  }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
20
+ emphasis: {
21
+ type: PropType<"normal" | "strong" | null>;
22
+ default: string;
23
+ };
16
24
  orientation: {
17
25
  type: PropType<"horizontal" | "vertical" | null>;
18
26
  default: string;
@@ -28,6 +36,7 @@ declare const __VLS_export: import("vue").DefineComponent<import("vue").ExtractP
28
36
  }>> & Readonly<{}>, {
29
37
  selected: boolean | null;
30
38
  orientation: "vertical" | "horizontal" | null;
39
+ emphasis: "strong" | "normal" | null;
31
40
  selectable: boolean | null;
32
41
  }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
33
42
  declare const _default: typeof __VLS_export;
@@ -8,6 +8,15 @@ defineOptions({ inheritAttrs: false })
8
8
 
9
9
  const propValidityContract = {
10
10
  props: {
11
+ emphasis: {
12
+ type: { kind: 'terminal', name: 'keyword' },
13
+ required: false,
14
+ target: { attribute: 'emphasis' },
15
+ description:
16
+ 'Normal uses the decorative divider color; strong uses the stronger enclosing-edge color for clearer separation.',
17
+ values: ['normal', 'strong'],
18
+ default: 'normal',
19
+ },
11
20
  orientation: {
12
21
  type: { kind: 'terminal', name: 'keyword' },
13
22
  required: false,
@@ -36,6 +45,7 @@ const propValidityContract = {
36
45
  },
37
46
  } as const
38
47
  const props = defineProps({
48
+ emphasis: { type: null as unknown as PropType<'normal' | 'strong' | null>, default: 'normal' },
39
49
  orientation: {
40
50
  type: null as unknown as PropType<'horizontal' | 'vertical' | null>,
41
51
  default: 'horizontal',
@@ -44,11 +54,19 @@ const props = defineProps({
44
54
  selected: { type: null as unknown as PropType<boolean | null>, default: false },
45
55
  })
46
56
  const acceptedProps: Record<string, unknown> = {
57
+ emphasis: 'normal',
47
58
  orientation: 'horizontal',
48
59
  selectable: false,
49
60
  selected: false,
50
61
  }
51
62
  const checkedProps = computed(() => ({
63
+ emphasis: checkedProp<'normal' | 'strong'>(
64
+ props['emphasis'],
65
+ { kind: 'terminal', name: 'keyword' },
66
+ false,
67
+ 'emphasis',
68
+ acceptedProps,
69
+ ) as 'normal' | 'strong',
52
70
  orientation: checkedProp<'horizontal' | 'vertical'>(
53
71
  props['orientation'],
54
72
  { kind: 'terminal', name: 'keyword' },
@@ -129,6 +147,9 @@ if (
129
147
  /** The values the styles' :host-state() rules test. */
130
148
  const hostState = computed(() =>
131
149
  [
150
+ checkedProps.value.emphasis && 'emphasis',
151
+ checkedProps.value.emphasis != null
152
+ && `emphasis=${encodeURIComponent(checkedProps.value.emphasis)}`,
132
153
  checkedProps.value.selectable && 'selectable',
133
154
  checkedProps.value.selected && 'selected',
134
155
  ].filter(Boolean).join(' ')
@@ -141,6 +162,7 @@ const hostState = computed(() =>
141
162
  v-bind="nativeAttrs($attrs)"
142
163
  :aria-orientation="checkedProps.orientation ?? undefined"
143
164
  v-prop-validity="{ contract: propValidityContract, values: { ...props } }"
165
+ :data-emphasis="reflectedProp('emphasis', 'emphasis', checkedProps.emphasis, undefined, false)"
144
166
  :data-orientation="reflectedProp('orientation', 'orientation', checkedProps.orientation, undefined, false)"
145
167
  :data-selectable="reflectedProp('selectable', 'selectable', checkedProps.selectable, undefined, false)"
146
168
  :data-selected="reflectedProp('selected', 'selected', checkedProps.selected, undefined, false)"
@@ -162,14 +184,18 @@ const hostState = computed(() =>
162
184
  margin: 0;
163
185
  border: 0;
164
186
  border-block-start: var(--ui-border-width) solid
165
- var(--ui-separator-color, var(--ui-border-divider));
187
+ var(--ui-separator-color, var(--_separator-color, var(--ui-border-divider)));
188
+ }
189
+
190
+ [data-component~="ui-separator"][data-ui-separator-state~="emphasis=strong"] {
191
+ --_separator-color: var(--ui-border-strong);
166
192
  }
167
193
 
168
194
  [data-component~="ui-separator"][aria-orientation="vertical"] {
169
195
  block-size: auto;
170
196
  border-block-start: 0;
171
197
  border-inline-start: var(--ui-border-width) solid
172
- var(--ui-separator-color, var(--ui-border-divider));
198
+ var(--ui-separator-color, var(--_separator-color, var(--ui-border-divider)));
173
199
  }
174
200
 
175
201
  [data-component~="ui-separator"][data-ui-separator-state~="selectable"] {