srcdev-nuxt-components 9.5.5 → 9.5.7
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/.claude/skills/component-compliance-checklist.md +6 -2
- package/.claude/skills/components/action-menu.md +21 -15
- package/.claude/skills/components/deep-expanding-menu.md +18 -6
- package/.claude/skills/components/display-tooltip-defined.md +2 -1
- package/.claude/skills/components/display-tooltip.md +10 -4
- package/.claude/skills/components/navigation-items.md +1 -0
- package/.claude/skills/components/opening-hours.md +12 -0
- package/.claude/skills/components/pop-over.md +11 -8
- package/.claude/skills/components/price-list.md +10 -1
- package/.claude/skills/components/responsive-header.md +25 -0
- package/.claude/skills/components/select-menu.md +18 -8
- package/.claude/skills/components/site-header.md +2 -0
- package/.claude/skills/components/ui-block-decorated.md +7 -0
- package/.claude/skills/composable-anchored-popover.md +108 -0
- package/.claude/skills/composable-tooltips-guide.md +3 -1
- package/.claude/skills/index.md +1 -0
- package/.claude/skills/storybook-add-story.md +14 -0
- package/.vscode/srcdev-component-responsive-header.code-snippets +3 -1
- package/.vscode/srcdev-component-site-header.code-snippets +3 -1
- package/app/assets/styles/setup/06.utility-classes/animations/_animation-scroller-x.css +5 -3
- package/app/assets/styles/setup/06.utility-classes/animations/_auto-rotate.css +5 -3
- package/app/assets/styles/setup/06.utility-classes/animations/_entry-exit-blur.css +5 -3
- package/app/assets/styles/setup/06.utility-classes/animations/_entry-slide-in.css +5 -3
- package/app/assets/styles/setup/06.utility-classes/animations/_entry-zoom-reveal.css +5 -3
- package/app/components/01.atoms/animations/entry/CONSUMER-STYLING.md +6 -2
- package/app/components/01.atoms/display-tooltip/CONSUMER-STYLING.md +15 -3
- package/app/components/01.atoms/display-tooltip/DisplayTooltip.vue +62 -3
- package/app/components/01.atoms/display-tooltip/tests/DisplayTooltip.spec.ts +36 -1
- package/app/components/01.atoms/display-tooltip/tests/__snapshots__/DisplayTooltip.spec.ts.snap +1 -1
- package/app/components/01.atoms/navigation/skip-links/SkipLinks.vue +1 -1
- package/app/components/01.atoms/pop-over/CONSUMER-STYLING.md +9 -3
- package/app/components/01.atoms/pop-over/PopOver.vue +70 -9
- package/app/components/01.atoms/pop-over/tests/PopOver.spec.ts +53 -0
- package/app/components/01.atoms/pop-over/tests/__snapshots__/PopOver.spec.ts.snap +1 -1
- package/app/components/01.atoms/ui-block-decorated/CONSUMER-STYLING.md +12 -4
- package/app/components/01.atoms/ui-block-decorated/UiBlockDecorated.vue +20 -16
- package/app/components/01.atoms/ui-block-decorated/stories/UiBlockDecorated.stories.ts +124 -96
- package/app/components/02.molecules/action-menu/ActionMenu.vue +41 -16
- package/app/components/02.molecules/action-menu/CONSUMER-STYLING.md +16 -3
- package/app/components/02.molecules/action-menu/tests/ActionMenu.spec.ts +28 -0
- package/app/components/02.molecules/action-menu/tests/__snapshots__/ActionMenu.spec.ts.snap +3 -3
- package/app/components/02.molecules/display-tooltip-defined/DisplayTooltipDefined.vue +2 -1
- package/app/components/02.molecules/display-tooltip-defined/stories/DisplayTooltipDefined.stories.ts +7 -4
- package/app/components/02.molecules/display-tooltip-defined/tests/DisplayTooltipDefined.spec.ts +20 -1
- package/app/components/02.molecules/display-tooltip-defined/tests/__snapshots__/DisplayTooltipDefined.spec.ts.snap +1 -1
- package/app/components/02.molecules/navigation/deep-expanding-menu/CONSUMER-STYLING.md +18 -4
- package/app/components/02.molecules/navigation/deep-expanding-menu/DeepExpandingMenu.vue +87 -16
- package/app/components/02.molecules/navigation/deep-expanding-menu/tests/DeepExpandingMenu.spec.ts +83 -1
- package/app/components/02.molecules/navigation/deep-expanding-menu/tests/__snapshots__/DeepExpandingMenu.spec.ts.snap +2 -2
- package/app/components/02.molecules/navigation/site-navigation/SiteNavigation.vue +1 -1
- package/app/components/02.molecules/navigation/tab-navigation/TabNavigation.vue +1 -1
- package/app/components/02.molecules/opening-hours/CONSUMER-STYLING.md +11 -1
- package/app/components/02.molecules/opening-hours/OpeningHours.vue +71 -43
- package/app/components/02.molecules/opening-hours/stories/OpeningHours.stories.ts +138 -6
- package/app/components/02.molecules/opening-hours/tests/OpeningHours.spec.ts +53 -0
- package/app/components/02.molecules/opening-hours/tests/__snapshots__/OpeningHours.spec.ts.snap +1 -1
- package/app/components/02.molecules/opening-hours/tests/buildOpeningHoursSpecification.spec.ts +37 -1
- package/app/components/02.molecules/price-list/CONSUMER-STYLING.md +17 -5
- package/app/components/02.molecules/price-list/PriceList.vue +32 -9
- package/app/components/02.molecules/price-list/stories/PriceList.stories.ts +125 -29
- package/app/components/02.molecules/price-list/tests/PriceList.spec.ts +20 -0
- package/app/components/02.molecules/select-menu/CONSUMER-STYLING.md +17 -5
- package/app/components/02.molecules/select-menu/SelectMenu.vue +51 -16
- package/app/components/02.molecules/select-menu/tests/SelectMenu.spec.ts +36 -0
- package/app/components/03.organisms/google-reviews/stories/GoogleReviews.stories.ts +9 -4
- package/app/components/03.organisms/responsive-header/CONSUMER-STYLING.md +14 -0
- package/app/components/03.organisms/responsive-header/NavigationItems.vue +23 -14
- package/app/components/03.organisms/responsive-header/ResponsiveHeader.vue +58 -30
- package/app/components/03.organisms/responsive-header/stories/ResponsiveHeader.stories.ts +149 -18
- package/app/components/03.organisms/responsive-header/tests/.nuxt/app.config.mjs +21 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/components.d.ts +66 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/imports.d.ts +30 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/manifest/meta/test.json +1 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/app.config.d.ts +35 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/build.d.ts +23 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/builder-env.d.ts +1 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/components.d.ts +71 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/imports.d.ts +386 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/middleware.d.ts +11 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/modules.d.ts +79 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/nitro-layouts.d.ts +17 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/nitro-nuxt.d.ts +64 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/plugins.d.ts +29 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/runtime-config.d.ts +32 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/shared-imports.d.ts +10 -0
- package/app/components/03.organisms/responsive-header/tests/.nuxt/types/vue-shim.d.ts +0 -0
- package/app/components/03.organisms/responsive-header/tests/NavigationItems.spec.ts +16 -0
- package/app/components/03.organisms/responsive-header/tests/ResponsiveHeader.spec.ts +91 -6
- package/app/components/03.organisms/responsive-header/tests/__snapshots__/ResponsiveHeader.spec.ts.snap +9 -9
- package/app/components/03.organisms/responsive-header/tests/node_modules/.cache/nuxt/chrome-workspace.json +1 -0
- package/app/components/03.organisms/site-header/SiteHeader.vue +8 -0
- package/app/components/03.organisms/site-header/tests/__snapshots__/SiteHeader.spec.ts.snap +1 -1
- package/app/composables/tests/useAnchoredPopover.spec.ts +231 -0
- package/app/composables/tests/useTooltips.spec.ts +69 -0
- package/app/composables/useAnchoredPopover.ts +183 -0
- package/app/composables/useTooltips.ts +37 -20
- package/app/utils/opening-hours.ts +23 -2
- package/package.json +1 -1
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
@media (prefers-reduced-motion: no-preference) {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
2
|
+
@supports (animation-timeline: view()) {
|
|
3
|
+
.entry-exit-blur {
|
|
4
|
+
animation: entryExitBlurAnimation linear both;
|
|
5
|
+
animation-timeline: view();
|
|
6
|
+
}
|
|
5
7
|
}
|
|
6
8
|
}
|
|
7
9
|
@keyframes entryExitBlurAnimation {
|
|
@@ -8,8 +8,10 @@
|
|
|
8
8
|
}
|
|
9
9
|
|
|
10
10
|
@media (prefers-reduced-motion: no-preference) {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
11
|
+
@supports (animation-timeline: view()) {
|
|
12
|
+
.entry-slide-in {
|
|
13
|
+
animation: entrySlideInAnimation forwards;
|
|
14
|
+
animation-timeline: view(70% 5%);
|
|
15
|
+
}
|
|
14
16
|
}
|
|
15
17
|
}
|
|
@@ -10,8 +10,10 @@
|
|
|
10
10
|
}
|
|
11
11
|
|
|
12
12
|
@media (prefers-reduced-motion: no-preference) {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
@supports (animation-timeline: view()) {
|
|
14
|
+
.entry-zoom-reveal {
|
|
15
|
+
animation: entryZoomRevealAnimation both;
|
|
16
|
+
animation-timeline: view(70% 5%);
|
|
17
|
+
}
|
|
16
18
|
}
|
|
17
19
|
}
|
|
@@ -31,8 +31,12 @@ any passthrough classes.
|
|
|
31
31
|
## Motion
|
|
32
32
|
|
|
33
33
|
- All three classes only animate inside `@media (prefers-reduced-motion: no-preference)`.
|
|
34
|
-
- They use `animation-timeline: view(...)` (scroll-driven)
|
|
35
|
-
|
|
34
|
+
- They use `animation-timeline: view(...)` (scroll-driven), inside an
|
|
35
|
+
`@supports (animation-timeline: view())` guard, so a browser without scroll-driven animations
|
|
36
|
+
(Safari before 26, Firefox) shows the content in place with no animation.
|
|
37
|
+
|
|
38
|
+
> Changed 2026-10-05: the guard is new. Before it, an unsupported browser ran the animation with a
|
|
39
|
+
> zero duration and kept its end keyframe, which for `entry-exit-blur` left the content blurred.
|
|
36
40
|
|
|
37
41
|
---
|
|
38
42
|
|
|
@@ -17,6 +17,8 @@
|
|
|
17
17
|
| `--display-tooltip-popover-width` | `30rem` | Popover panel width |
|
|
18
18
|
| `--display-tooltip-popover-padding` | `1.2rem` | Popover panel content padding |
|
|
19
19
|
| `--display-tooltip-popover-content-gap` | `1.2rem` | Gap between stacked children in the `tooltipContent` slot |
|
|
20
|
+
| `--display-tooltip-popover-font-size` | `1.4rem` | Popover text size (`DisplayTooltipDefined` sets its own per-element sizes) |
|
|
21
|
+
| `--display-tooltip-popover-line-height` | `1.4` | Popover text line height |
|
|
20
22
|
| `--display-tooltip-popover-outline-width` | `0.1rem` | Popover panel outline (border) width |
|
|
21
23
|
| `--display-tooltip-popover-outline-colour` | `var(--slate-02)` | Popover panel outline (border) colour |
|
|
22
24
|
| `--display-tooltip-popover-text-colour` | `var(--slate-09)` | Popover panel text colour |
|
|
@@ -24,6 +26,7 @@
|
|
|
24
26
|
| `--display-tooltip-popover-border-radius` | `0.8rem` | Popover panel corner radius |
|
|
25
27
|
| `--display-tooltip-popover-shadow` | `0 0.4rem 1.6rem rgba(0,0,0,.12)` | Popover panel elevation shadow |
|
|
26
28
|
| `--display-tooltip-popover-offset` | `0.1rem` | Gap between the trigger and the popover panel |
|
|
29
|
+
| `--display-tooltip-popover-z-index` | `999999` | Panel stacking order in browsers without CSS anchor positioning. Ignored where the panel renders in the top layer |
|
|
27
30
|
| `--display-tooltip-close-button-colour` | `var(--slate-09)` | Close button text colour (used by `DisplayTooltipDefined`) |
|
|
28
31
|
| `--display-tooltip-close-button-border-width` | `0.1rem` | Close button border width |
|
|
29
32
|
| `--display-tooltip-close-button-border-colour` | `var(--slate-03)` | Close button border colour |
|
|
@@ -61,13 +64,22 @@ Set the tokens above on an element you own (a page or section class, or a class
|
|
|
61
64
|
|
|
62
65
|
## Notes
|
|
63
66
|
|
|
67
|
+
- Direct children of the `tooltipContent` slot have their block margins reset to `0` (inside
|
|
68
|
+
`:where()`, so any margin you set on them still wins): the gap token is the only spacing between
|
|
69
|
+
them. Before 2026-10-05 a slotted `<p>` kept its browser `1em` margins on top of the padding.
|
|
70
|
+
|
|
64
71
|
- The trigger button is vertically centred on the first line of `triggerContent` text, using
|
|
65
72
|
`--display-tooltip-trigger-icon-box-size`, `-padding` and `-border-width` to work out its height.
|
|
66
73
|
Give `--display-tooltip-trigger-padding` a single length (e.g. `0.4rem`): a two-value shorthand
|
|
67
74
|
breaks that calculation, and the button is square anyway.
|
|
68
|
-
- Built on the native Popover API
|
|
69
|
-
(
|
|
70
|
-
|
|
75
|
+
- Built on the native Popover API and CSS anchor positioning, with fallbacks: without anchor
|
|
76
|
+
positioning (e.g. Safari 17–18) the panel is placed with `position: fixed` from the trigger's
|
|
77
|
+
measured position and flips left (`.display-tooltip-popover[data-placement="left"]`) when there's
|
|
78
|
+
no room on the right. Without the Popover API (Safari 16) it opens and closes in JS, shows via
|
|
79
|
+
`.display-tooltip-popover-open` (style it in a separate rule from `:popover-open`: a selector list
|
|
80
|
+
containing `:popover-open` is dropped whole where unsupported), isn't in the top layer (so the
|
|
81
|
+
z-index token applies), and an ancestor with `transform`, `filter` or `contain` can misplace it.
|
|
82
|
+
The trigger's `aria-expanded` tracks the open state in every browser.
|
|
71
83
|
- The `.display-tooltip-close-button` styled here is rendered by `DisplayTooltipDefined`, not this
|
|
72
84
|
component directly — `DisplayTooltip` only provides the `tooltipContent` slot, so a plain
|
|
73
85
|
`DisplayTooltip` usage supplies its own close affordance if it wants one (give it
|
|
@@ -1,20 +1,38 @@
|
|
|
1
1
|
<template>
|
|
2
|
-
<div
|
|
2
|
+
<div
|
|
3
|
+
ref="rootRef"
|
|
4
|
+
class="display-tooltip-core"
|
|
5
|
+
:class="[elementClasses]"
|
|
6
|
+
:style="{ '--_anchor-name': tooltipAnchorName }"
|
|
7
|
+
>
|
|
3
8
|
<div class="display-tooltip-trigger-wrapper body-md">
|
|
4
9
|
<slot v-if="$slots.triggerContent" name="triggerContent"></slot>
|
|
5
10
|
<button
|
|
11
|
+
ref="triggerRef"
|
|
6
12
|
:popovertarget="tooltipId"
|
|
7
13
|
popovertargetaction="toggle"
|
|
8
14
|
class="display-tooltip-trigger-button"
|
|
9
15
|
:class="{ hide: hideTrigger }"
|
|
10
16
|
:aria-label="triggerAriaLabel"
|
|
17
|
+
:aria-expanded="isOpen"
|
|
18
|
+
@click="handleTriggerClick"
|
|
11
19
|
>
|
|
12
20
|
<Icon name="fa7-solid:circle-question" class="display-tooltip-trigger-icon" aria-hidden="true" />
|
|
13
21
|
</button>
|
|
14
22
|
</div>
|
|
15
|
-
<div
|
|
23
|
+
<div
|
|
24
|
+
:id="tooltipId"
|
|
25
|
+
ref="popoverRef"
|
|
26
|
+
popover
|
|
27
|
+
class="display-tooltip-popover"
|
|
28
|
+
:class="{ 'display-tooltip-popover-open': usesFallbackPopover && isOpen }"
|
|
29
|
+
:style="positionStyle"
|
|
30
|
+
:data-placement="popoverPlacement"
|
|
31
|
+
@beforetoggle="handleBeforeToggle"
|
|
32
|
+
@toggle="handleToggle"
|
|
33
|
+
>
|
|
16
34
|
<div class="display-tooltip-popover-content">
|
|
17
|
-
<slot name="tooltipContent"></slot>
|
|
35
|
+
<slot name="tooltipContent" :close="hide"></slot>
|
|
18
36
|
</div>
|
|
19
37
|
</div>
|
|
20
38
|
</div>
|
|
@@ -39,6 +57,21 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
39
57
|
const tooltipId = computed(() => (props.tooltipId.length ? props.tooltipId : `nuxt-tooltip-${useId()}`));
|
|
40
58
|
const tooltipAnchorName = `--tooltip-anchor-${useId()}`;
|
|
41
59
|
|
|
60
|
+
const rootRef = ref<HTMLElement | null>(null);
|
|
61
|
+
const triggerRef = ref<HTMLElement | null>(null);
|
|
62
|
+
const popoverRef = ref<HTMLElement | null>(null);
|
|
63
|
+
|
|
64
|
+
const {
|
|
65
|
+
isOpen,
|
|
66
|
+
usesFallbackPopover,
|
|
67
|
+
positionStyle,
|
|
68
|
+
popoverPlacement,
|
|
69
|
+
hide,
|
|
70
|
+
handleTriggerClick,
|
|
71
|
+
handleBeforeToggle,
|
|
72
|
+
handleToggle,
|
|
73
|
+
} = useAnchoredPopover({ rootRef, triggerRef, popoverRef, side: "right" });
|
|
74
|
+
|
|
42
75
|
const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
|
|
43
76
|
|
|
44
77
|
watch(
|
|
@@ -141,6 +174,13 @@ watch(
|
|
|
141
174
|
display: flex;
|
|
142
175
|
flex-direction: column;
|
|
143
176
|
gap: var(--display-tooltip-popover-content-gap, 1.2rem);
|
|
177
|
+
font-size: var(--display-tooltip-popover-font-size, 1.4rem);
|
|
178
|
+
line-height: var(--display-tooltip-popover-line-height, 1.4);
|
|
179
|
+
|
|
180
|
+
/* Gap is the only spacing between slotted elements; :where keeps consumer margins winning. */
|
|
181
|
+
> :where(*) {
|
|
182
|
+
margin-block: 0;
|
|
183
|
+
}
|
|
144
184
|
|
|
145
185
|
.display-tooltip-close-button {
|
|
146
186
|
all: unset;
|
|
@@ -174,6 +214,25 @@ watch(
|
|
|
174
214
|
opacity: 0;
|
|
175
215
|
}
|
|
176
216
|
}
|
|
217
|
+
|
|
218
|
+
/* Kept apart from :popover-open, which would invalidate a shared selector list where unsupported. */
|
|
219
|
+
&.display-tooltip-popover-open {
|
|
220
|
+
display: flex;
|
|
221
|
+
opacity: 1;
|
|
222
|
+
flex-direction: column;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
@supports not (anchor-name: --a) {
|
|
226
|
+
position: fixed;
|
|
227
|
+
top: var(--_anchor-top, 0px);
|
|
228
|
+
left: calc(var(--_anchor-right, 0px) + var(--display-tooltip-popover-offset, 0.1rem));
|
|
229
|
+
z-index: var(--display-tooltip-popover-z-index, 999999);
|
|
230
|
+
|
|
231
|
+
&[data-placement="left"] {
|
|
232
|
+
left: auto;
|
|
233
|
+
right: calc(var(--_anchor-left-inverse, 0px) + var(--display-tooltip-popover-offset, 0.1rem));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
177
236
|
}
|
|
178
237
|
}
|
|
179
238
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { describe, it, expect } from "vitest";
|
|
1
|
+
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
2
|
import { mountSuspended } from "@nuxt/test-utils/runtime";
|
|
3
3
|
import DisplayTooltip from "../DisplayTooltip.vue";
|
|
4
4
|
|
|
@@ -72,4 +72,39 @@ describe("DisplayTooltip", () => {
|
|
|
72
72
|
expect(wrapper.classes()).not.toContain("initial-class");
|
|
73
73
|
expect(wrapper.classes()).toContain("updated-class");
|
|
74
74
|
});
|
|
75
|
+
|
|
76
|
+
describe("without the Popover API", () => {
|
|
77
|
+
beforeEach(() => {
|
|
78
|
+
Object.defineProperty(HTMLElement.prototype, "showPopover", { value: undefined, writable: true, configurable: true });
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
afterEach(() => {
|
|
82
|
+
delete (HTMLElement.prototype as unknown as Record<string, unknown>)["showPopover"];
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
it("opens and closes from the trigger", async () => {
|
|
86
|
+
const wrapper = await mountSuspended(DisplayTooltip);
|
|
87
|
+
const trigger = wrapper.find(".display-tooltip-trigger-button");
|
|
88
|
+
const popover = wrapper.find(".display-tooltip-popover");
|
|
89
|
+
|
|
90
|
+
await trigger.trigger("click");
|
|
91
|
+
expect(popover.classes()).toContain("display-tooltip-popover-open");
|
|
92
|
+
expect(trigger.attributes("aria-expanded")).toBe("true");
|
|
93
|
+
|
|
94
|
+
await trigger.trigger("click");
|
|
95
|
+
expect(popover.classes()).not.toContain("display-tooltip-popover-open");
|
|
96
|
+
expect(trigger.attributes("aria-expanded")).toBe("false");
|
|
97
|
+
});
|
|
98
|
+
|
|
99
|
+
it("passes a close function to the tooltipContent slot", async () => {
|
|
100
|
+
const wrapper = await mountSuspended(DisplayTooltip, {
|
|
101
|
+
slots: {
|
|
102
|
+
tooltipContent: `<template #tooltipContent="{ close }"><button class="custom-close" @click="close">Done</button></template>`,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
await wrapper.find(".display-tooltip-trigger-button").trigger("click");
|
|
106
|
+
await wrapper.find(".custom-close").trigger("click");
|
|
107
|
+
expect(wrapper.find(".display-tooltip-popover").classes()).not.toContain("display-tooltip-popover-open");
|
|
108
|
+
});
|
|
109
|
+
});
|
|
75
110
|
});
|
package/app/components/01.atoms/display-tooltip/tests/__snapshots__/DisplayTooltip.spec.ts.snap
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
exports[`DisplayTooltip > renders correct HTML structure 1`] = `
|
|
4
4
|
"<div class="display-tooltip-core" style="--_anchor-name: --tooltip-anchor-v-0-0;">
|
|
5
5
|
<div class="display-tooltip-trigger-wrapper body-md">
|
|
6
|
-
<!--v-if--><button popovertarget="fixed-id" popovertargetaction="toggle" class="display-tooltip-trigger-button" aria-label="Toggle the popover"><span class="iconify i-fa7-solid:circle-question display-tooltip-trigger-icon" aria-hidden="true"></span></button>
|
|
6
|
+
<!--v-if--><button popovertarget="fixed-id" popovertargetaction="toggle" class="display-tooltip-trigger-button" aria-label="Toggle the popover" aria-expanded="false"><span class="iconify i-fa7-solid:circle-question display-tooltip-trigger-icon" aria-hidden="true"></span></button>
|
|
7
7
|
</div>
|
|
8
8
|
<div id="fixed-id" popover="" class="display-tooltip-popover">
|
|
9
9
|
<div class="display-tooltip-popover-content"></div>
|
|
@@ -81,7 +81,7 @@ watch(
|
|
|
81
81
|
color: var(--skip-links-text-colour, white);
|
|
82
82
|
text-decoration: none;
|
|
83
83
|
padding: var(--skip-links-link-padding-block, 0.8rem) var(--skip-links-link-padding-inline, 1.2rem);
|
|
84
|
-
|
|
84
|
+
white-space: nowrap;
|
|
85
85
|
|
|
86
86
|
&:focus-visible {
|
|
87
87
|
outline: var(--skip-links-focus-outline-width, 2px) solid var(--skip-links-focus-outline-colour, white);
|
|
@@ -15,6 +15,7 @@
|
|
|
15
15
|
| `--pop-over-text-colour` | `var(--slate-09)` | Popover panel text colour |
|
|
16
16
|
| `--pop-over-shadow` | `0 0.4rem 1.6rem rgba(0,0,0,.12)` | Popover panel elevation shadow |
|
|
17
17
|
| `--pop-over-transition-duration` | `200ms` | Open/close fade duration |
|
|
18
|
+
| `--pop-over-z-index` | `999999` | Panel stacking order in browsers without CSS anchor positioning. Ignored where the panel renders in the top layer |
|
|
18
19
|
| `--pop-over-content-padding` | `1.6rem` | Padding around the `content` slot |
|
|
19
20
|
| `--pop-over-content-padding-block-start` | `3.2rem` | Extra top padding so content clears the close button |
|
|
20
21
|
| `--pop-over-close-button-offset` | `0.8rem` | Distance of the close button from the panel's top/right edges |
|
|
@@ -54,9 +55,14 @@ Set the tokens above on an element you own (a page or section class, or a class
|
|
|
54
55
|
|
|
55
56
|
## Notes
|
|
56
57
|
|
|
57
|
-
- Built on the native Popover API
|
|
58
|
-
(
|
|
59
|
-
|
|
58
|
+
- Built on the native Popover API and CSS anchor positioning, with fallbacks: without anchor
|
|
59
|
+
positioning (e.g. Safari 17–18) the panel is placed with `position: fixed` from the trigger's
|
|
60
|
+
measured position, and `.pop-over-popover[data-placement]` holds the resolved side (the
|
|
61
|
+
`placement` prop's side, or its opposite when that has no room). Without the Popover API
|
|
62
|
+
(Safari 16) it opens and closes in JS and shows via `.pop-over-popover-open` (style it in a
|
|
63
|
+
separate rule from `:popover-open`: a selector list containing `:popover-open` is dropped whole
|
|
64
|
+
where unsupported). It isn't in the top layer there, so the z-index token applies, and an
|
|
65
|
+
ancestor with `transform`, `filter` or `contain` can misplace it.
|
|
60
66
|
- `placement` (`"top" | "right" | "bottom" | "left"`, default `"right"`) picks which side of the
|
|
61
67
|
trigger the panel opens on; each side gets a `position-try-fallbacks` so the browser flips it
|
|
62
68
|
automatically if it would overflow the viewport.
|
|
@@ -1,6 +1,12 @@
|
|
|
1
1
|
<template>
|
|
2
2
|
<ClientOnly>
|
|
3
|
-
<div
|
|
3
|
+
<div
|
|
4
|
+
ref="rootRef"
|
|
5
|
+
class="pop-over"
|
|
6
|
+
:class="[elementClasses]"
|
|
7
|
+
:style="{ '--_anchor-name': anchorName }"
|
|
8
|
+
:data-placement="placement"
|
|
9
|
+
>
|
|
4
10
|
<button
|
|
5
11
|
ref="triggerRef"
|
|
6
12
|
:popovertarget="popoverId"
|
|
@@ -8,11 +14,24 @@
|
|
|
8
14
|
type="button"
|
|
9
15
|
class="pop-over-trigger"
|
|
10
16
|
:aria-label="triggerAriaLabel || undefined"
|
|
17
|
+
:aria-expanded="isOpen"
|
|
18
|
+
@click="handleTriggerClick"
|
|
11
19
|
>
|
|
12
20
|
<slot name="trigger"></slot>
|
|
13
21
|
</button>
|
|
14
22
|
|
|
15
|
-
<div
|
|
23
|
+
<div
|
|
24
|
+
:id="popoverId"
|
|
25
|
+
ref="popoverRef"
|
|
26
|
+
popover
|
|
27
|
+
class="pop-over-popover"
|
|
28
|
+
:class="{ 'pop-over-popover-open': usesFallbackPopover && isOpen }"
|
|
29
|
+
:style="positionStyle"
|
|
30
|
+
:data-placement="popoverPlacement"
|
|
31
|
+
:aria-label="popoverAriaLabel || undefined"
|
|
32
|
+
@beforetoggle="handleBeforeToggle"
|
|
33
|
+
@toggle="handleToggle"
|
|
34
|
+
>
|
|
16
35
|
<button
|
|
17
36
|
ref="closeButtonRef"
|
|
18
37
|
:popovertarget="popoverId"
|
|
@@ -20,6 +39,7 @@
|
|
|
20
39
|
type="button"
|
|
21
40
|
class="pop-over-close-button"
|
|
22
41
|
:aria-label="closeButtonAriaLabel"
|
|
42
|
+
@click="hide"
|
|
23
43
|
>
|
|
24
44
|
<Icon name="lucide:x" class="pop-over-close-button-icon" aria-hidden="true" />
|
|
25
45
|
</button>
|
|
@@ -55,17 +75,28 @@ const id = useId();
|
|
|
55
75
|
const popoverId = `pop-over-${id}`;
|
|
56
76
|
const anchorName = `--pop-over-anchor-${id}`;
|
|
57
77
|
|
|
78
|
+
const rootRef = ref<HTMLDivElement | null>(null);
|
|
58
79
|
const triggerRef = ref<HTMLButtonElement | null>(null);
|
|
59
80
|
const popoverRef = ref<HTMLDivElement | null>(null);
|
|
60
81
|
const closeButtonRef = ref<HTMLButtonElement | null>(null);
|
|
61
82
|
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
83
|
+
// Focus moves to the close button on open; closing returns it to the trigger in every mode.
|
|
84
|
+
const {
|
|
85
|
+
isOpen,
|
|
86
|
+
usesFallbackPopover,
|
|
87
|
+
positionStyle,
|
|
88
|
+
popoverPlacement,
|
|
89
|
+
hide,
|
|
90
|
+
handleTriggerClick,
|
|
91
|
+
handleBeforeToggle,
|
|
92
|
+
handleToggle,
|
|
93
|
+
} = useAnchoredPopover({
|
|
94
|
+
rootRef,
|
|
95
|
+
triggerRef,
|
|
96
|
+
popoverRef,
|
|
97
|
+
side: () => props.placement,
|
|
98
|
+
onOpen: () => closeButtonRef.value?.focus(),
|
|
99
|
+
});
|
|
69
100
|
|
|
70
101
|
const { elementClasses, resetElementClasses } = useStyleClassPassthrough(props.styleClassPassthrough);
|
|
71
102
|
|
|
@@ -128,6 +159,12 @@ watch(
|
|
|
128
159
|
}
|
|
129
160
|
}
|
|
130
161
|
|
|
162
|
+
/* Kept apart from :popover-open, which would invalidate a shared selector list where unsupported. */
|
|
163
|
+
&.pop-over-popover-open {
|
|
164
|
+
display: block;
|
|
165
|
+
opacity: 1;
|
|
166
|
+
}
|
|
167
|
+
|
|
131
168
|
.pop-over-close-button {
|
|
132
169
|
all: unset;
|
|
133
170
|
cursor: pointer;
|
|
@@ -196,6 +233,30 @@ watch(
|
|
|
196
233
|
left: anchor(left);
|
|
197
234
|
position-try-fallbacks: flip-block;
|
|
198
235
|
}
|
|
236
|
+
|
|
237
|
+
/* After the placement rules above, so the resolved (possibly flipped) side wins over their insets. */
|
|
238
|
+
@supports not (anchor-name: --a) {
|
|
239
|
+
.pop-over-popover {
|
|
240
|
+
position: fixed;
|
|
241
|
+
z-index: var(--pop-over-z-index, 999999);
|
|
242
|
+
|
|
243
|
+
&[data-placement="right"] {
|
|
244
|
+
inset: var(--_anchor-top, 0px) auto auto calc(var(--_anchor-right, 0px) + var(--pop-over-gap, 1rem));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
&[data-placement="left"] {
|
|
248
|
+
inset: var(--_anchor-top, 0px) calc(var(--_anchor-left-inverse, 0px) + var(--pop-over-gap, 1rem)) auto auto;
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
&[data-placement="bottom"] {
|
|
252
|
+
inset: calc(var(--_anchor-bottom, 0px) + var(--pop-over-gap, 1rem)) auto auto var(--_anchor-left, 0px);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
&[data-placement="top"] {
|
|
256
|
+
inset: auto auto calc(var(--_anchor-top-inverse, 0px) + var(--pop-over-gap, 1rem)) var(--_anchor-left, 0px);
|
|
257
|
+
}
|
|
258
|
+
}
|
|
259
|
+
}
|
|
199
260
|
}
|
|
200
261
|
}
|
|
201
262
|
</style>
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { describe, it, expect, beforeEach, afterEach, vi } from "vitest";
|
|
2
2
|
import { mountSuspended } from "@nuxt/test-utils/runtime";
|
|
3
3
|
import PopOver from "../PopOver.vue";
|
|
4
|
+
import { nextTick } from "vue";
|
|
4
5
|
|
|
5
6
|
interface PopOverInstance {
|
|
6
7
|
popoverId: string;
|
|
@@ -192,4 +193,56 @@ describe("PopOver", () => {
|
|
|
192
193
|
expect(wrapper.find(".pop-over").classes()).toContain("updated-class");
|
|
193
194
|
});
|
|
194
195
|
});
|
|
196
|
+
|
|
197
|
+
describe("Without the Popover API", () => {
|
|
198
|
+
beforeEach(() => {
|
|
199
|
+
Object.defineProperty(HTMLElement.prototype, "showPopover", { value: undefined, writable: true, configurable: true });
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
it("opens from the trigger and closes from the close button, returning focus to the trigger", async () => {
|
|
203
|
+
wrapper = await mountSuspended(PopOver, {
|
|
204
|
+
slots: { trigger: "<span>Open</span>", content: "<p>Body</p>" },
|
|
205
|
+
attachTo: document.body,
|
|
206
|
+
});
|
|
207
|
+
const trigger = wrapper.find(".pop-over-trigger");
|
|
208
|
+
const popover = wrapper.find(".pop-over-popover");
|
|
209
|
+
|
|
210
|
+
await trigger.trigger("click");
|
|
211
|
+
await nextTick();
|
|
212
|
+
expect(popover.classes()).toContain("pop-over-popover-open");
|
|
213
|
+
expect(trigger.attributes("aria-expanded")).toBe("true");
|
|
214
|
+
expect(document.activeElement).toBe(wrapper.find(".pop-over-close-button").element);
|
|
215
|
+
|
|
216
|
+
await wrapper.find(".pop-over-close-button").trigger("click");
|
|
217
|
+
expect(popover.classes()).not.toContain("pop-over-popover-open");
|
|
218
|
+
expect(document.activeElement).toBe(trigger.element);
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
describe("Without anchor positioning", () => {
|
|
223
|
+
const originalCSS = globalThis.CSS;
|
|
224
|
+
|
|
225
|
+
beforeEach(() => {
|
|
226
|
+
Object.defineProperty(globalThis, "CSS", { value: { supports: () => false }, writable: true, configurable: true });
|
|
227
|
+
});
|
|
228
|
+
|
|
229
|
+
afterEach(() => {
|
|
230
|
+
Object.defineProperty(globalThis, "CSS", { value: originalCSS, writable: true, configurable: true });
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
it("places the popover on the current placement prop's side", async () => {
|
|
234
|
+
wrapper = await createWrapper({ placement: "left" });
|
|
235
|
+
const vm = wrapper.vm as unknown as PopOverInstance;
|
|
236
|
+
const popover = wrapper.find(".pop-over-popover");
|
|
237
|
+
|
|
238
|
+
vm.handleToggle(Object.assign(new Event("toggle"), { newState: "open" }));
|
|
239
|
+
await nextTick();
|
|
240
|
+
expect(popover.attributes("data-placement")).toBe("left");
|
|
241
|
+
|
|
242
|
+
await wrapper.setProps({ placement: "top" });
|
|
243
|
+
vm.handleToggle(Object.assign(new Event("toggle"), { newState: "open" }));
|
|
244
|
+
await nextTick();
|
|
245
|
+
expect(popover.attributes("data-placement")).toBe("top");
|
|
246
|
+
});
|
|
247
|
+
});
|
|
195
248
|
});
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
2
|
|
|
3
3
|
exports[`PopOver > renders correct HTML structure 1`] = `
|
|
4
|
-
"<div class="pop-over" style="--_anchor-name: --pop-over-anchor-v-0-0;" data-placement="right"><button popovertarget="pop-over-v-0-0" popovertargetaction="toggle" type="button" class="pop-over-trigger"><span>Open</span></button>
|
|
4
|
+
"<div class="pop-over" style="--_anchor-name: --pop-over-anchor-v-0-0;" data-placement="right"><button popovertarget="pop-over-v-0-0" popovertargetaction="toggle" type="button" class="pop-over-trigger" aria-expanded="false"><span>Open</span></button>
|
|
5
5
|
<div id="pop-over-v-0-0" popover="" class="pop-over-popover"><button popovertarget="pop-over-v-0-0" popovertargetaction="hide" type="button" class="pop-over-close-button" aria-label="Close"><span class="iconify i-lucide:x pop-over-close-button-icon" aria-hidden="true"></span></button>
|
|
6
6
|
<div class="pop-over-content">
|
|
7
7
|
<p>Details</p>
|
|
@@ -4,17 +4,25 @@
|
|
|
4
4
|
|
|
5
5
|
Each strength level (border 1-6, shadow 1-6, inner shadow 1-4) has its own token, defaulting to a
|
|
6
6
|
built-in elevation/border scale. Only the tokens for the strength levels actually in use need
|
|
7
|
-
overriding.
|
|
7
|
+
overriding. To recolour every level at once, set the colour tokens instead.
|
|
8
|
+
|
|
9
|
+
The colour tokens are private-wrapped (`--_border-colour`, `--_shadow-colour`, `--_inner-shadow-colour`)
|
|
10
|
+
because each is reused across every strength level; set the public token, not the `--_` one.
|
|
8
11
|
|
|
9
12
|
| Token | Default | Controls |
|
|
10
13
|
|---|---|---|
|
|
11
|
-
| `--ui-block-decorated-border-
|
|
12
|
-
| `--ui-block-decorated-shadow-
|
|
13
|
-
| `--ui-block-decorated-inner-shadow-
|
|
14
|
+
| `--ui-block-decorated-border-colour` | `var(--theme-border)` | Border colour for every strength level |
|
|
15
|
+
| `--ui-block-decorated-shadow-colour` | `#000` | Drop shadow colour for every strength level; each level mixes in its own opacity (8% .. 18%) |
|
|
16
|
+
| `--ui-block-decorated-inner-shadow-colour` | `--ui-block-decorated-shadow-colour` | Inner shadow colour for every strength level (8% .. 14% opacity) |
|
|
17
|
+
| `--ui-block-decorated-border-1` .. `-6` | `1px` .. `6px solid` the border colour | Whole border at each strength level |
|
|
18
|
+
| `--ui-block-decorated-shadow-1` .. `-6` | `0 1px 2px` .. `0 24px 32px` in the shadow colour | Whole drop shadow at each strength level |
|
|
19
|
+
| `--ui-block-decorated-inner-shadow-1` .. `-4` | `inset 0 1px 2px` .. `inset 0 6px 8px` in the inner shadow colour | Whole inset shadow at each strength level |
|
|
14
20
|
| `--ui-block-decorated-inner-shadow-highlight` | `inset 0 1px 0 rgba(255,255,255,0.15)` | Highlight layered on top of every inner shadow strength |
|
|
15
21
|
|
|
16
22
|
```css
|
|
17
23
|
.my-page {
|
|
24
|
+
--ui-block-decorated-border-colour: #7c3aed;
|
|
25
|
+
--ui-block-decorated-shadow-colour: #7c3aed;
|
|
18
26
|
--ui-block-decorated-shadow-3: 0 6px 12px rgba(0, 0, 0, 0.2);
|
|
19
27
|
--ui-block-decorated-border-2: 2px dashed hotpink;
|
|
20
28
|
}
|
|
@@ -43,48 +43,52 @@ watch(
|
|
|
43
43
|
<style lang="css">
|
|
44
44
|
@layer components {
|
|
45
45
|
.ui-block-decorated {
|
|
46
|
+
--_border-colour: var(--ui-block-decorated-border-colour, var(--theme-border));
|
|
47
|
+
--_shadow-colour: var(--ui-block-decorated-shadow-colour, #000);
|
|
48
|
+
--_inner-shadow-colour: var(--ui-block-decorated-inner-shadow-colour, var(--_shadow-colour));
|
|
49
|
+
|
|
46
50
|
/*
|
|
47
51
|
* Border strength classes
|
|
48
52
|
*/
|
|
49
53
|
&.ui-block-decorated-border-1 {
|
|
50
|
-
border: var(--ui-block-decorated-border-1, 1px solid var(--
|
|
54
|
+
border: var(--ui-block-decorated-border-1, 1px solid var(--_border-colour));
|
|
51
55
|
}
|
|
52
56
|
&.ui-block-decorated-border-2 {
|
|
53
|
-
border: var(--ui-block-decorated-border-2, 2px solid var(--
|
|
57
|
+
border: var(--ui-block-decorated-border-2, 2px solid var(--_border-colour));
|
|
54
58
|
}
|
|
55
59
|
&.ui-block-decorated-border-3 {
|
|
56
|
-
border: var(--ui-block-decorated-border-3, 3px solid var(--
|
|
60
|
+
border: var(--ui-block-decorated-border-3, 3px solid var(--_border-colour));
|
|
57
61
|
}
|
|
58
62
|
&.ui-block-decorated-border-4 {
|
|
59
|
-
border: var(--ui-block-decorated-border-4, 4px solid var(--
|
|
63
|
+
border: var(--ui-block-decorated-border-4, 4px solid var(--_border-colour));
|
|
60
64
|
}
|
|
61
65
|
&.ui-block-decorated-border-5 {
|
|
62
|
-
border: var(--ui-block-decorated-border-5, 5px solid var(--
|
|
66
|
+
border: var(--ui-block-decorated-border-5, 5px solid var(--_border-colour));
|
|
63
67
|
}
|
|
64
68
|
&.ui-block-decorated-border-6 {
|
|
65
|
-
border: var(--ui-block-decorated-border-6, 6px solid var(--
|
|
69
|
+
border: var(--ui-block-decorated-border-6, 6px solid var(--_border-colour));
|
|
66
70
|
}
|
|
67
71
|
|
|
68
72
|
/*
|
|
69
73
|
* Shadow strength classes
|
|
70
74
|
*/
|
|
71
75
|
&.ui-block-decorated-shadow-1 {
|
|
72
|
-
box-shadow: var(--ui-block-decorated-shadow-1, 0 1px 2px
|
|
76
|
+
box-shadow: var(--ui-block-decorated-shadow-1, 0 1px 2px color-mix(in srgb, var(--_shadow-colour) 8%, transparent));
|
|
73
77
|
}
|
|
74
78
|
&.ui-block-decorated-shadow-2 {
|
|
75
|
-
box-shadow: var(--ui-block-decorated-shadow-2, 0 2px 4px
|
|
79
|
+
box-shadow: var(--ui-block-decorated-shadow-2, 0 2px 4px color-mix(in srgb, var(--_shadow-colour) 10%, transparent));
|
|
76
80
|
}
|
|
77
81
|
&.ui-block-decorated-shadow-3 {
|
|
78
|
-
box-shadow: var(--ui-block-decorated-shadow-3, 0 4px 8px
|
|
82
|
+
box-shadow: var(--ui-block-decorated-shadow-3, 0 4px 8px color-mix(in srgb, var(--_shadow-colour) 12%, transparent));
|
|
79
83
|
}
|
|
80
84
|
&.ui-block-decorated-shadow-4 {
|
|
81
|
-
box-shadow: var(--ui-block-decorated-shadow-4, 0 8px 16px
|
|
85
|
+
box-shadow: var(--ui-block-decorated-shadow-4, 0 8px 16px color-mix(in srgb, var(--_shadow-colour) 14%, transparent));
|
|
82
86
|
}
|
|
83
87
|
&.ui-block-decorated-shadow-5 {
|
|
84
|
-
box-shadow: var(--ui-block-decorated-shadow-5, 0 16px 24px
|
|
88
|
+
box-shadow: var(--ui-block-decorated-shadow-5, 0 16px 24px color-mix(in srgb, var(--_shadow-colour) 16%, transparent));
|
|
85
89
|
}
|
|
86
90
|
&.ui-block-decorated-shadow-6 {
|
|
87
|
-
box-shadow: var(--ui-block-decorated-shadow-6, 0 24px 32px
|
|
91
|
+
box-shadow: var(--ui-block-decorated-shadow-6, 0 24px 32px color-mix(in srgb, var(--_shadow-colour) 18%, transparent));
|
|
88
92
|
}
|
|
89
93
|
|
|
90
94
|
/*
|
|
@@ -115,25 +119,25 @@ watch(
|
|
|
115
119
|
|
|
116
120
|
&.ui-block-decorated-inner-shadow-1::before {
|
|
117
121
|
box-shadow:
|
|
118
|
-
var(--ui-block-decorated-inner-shadow-1, inset 0 1px 2px
|
|
122
|
+
var(--ui-block-decorated-inner-shadow-1, inset 0 1px 2px color-mix(in srgb, var(--_inner-shadow-colour) 8%, transparent)),
|
|
119
123
|
var(--ui-block-decorated-inner-shadow-highlight, inset 0 1px 0 rgba(255, 255, 255, 0.15));
|
|
120
124
|
}
|
|
121
125
|
|
|
122
126
|
&.ui-block-decorated-inner-shadow-2::before {
|
|
123
127
|
box-shadow:
|
|
124
|
-
var(--ui-block-decorated-inner-shadow-2, inset 0 2px 4px
|
|
128
|
+
var(--ui-block-decorated-inner-shadow-2, inset 0 2px 4px color-mix(in srgb, var(--_inner-shadow-colour) 10%, transparent)),
|
|
125
129
|
var(--ui-block-decorated-inner-shadow-highlight, inset 0 1px 0 rgba(255, 255, 255, 0.15));
|
|
126
130
|
}
|
|
127
131
|
|
|
128
132
|
&.ui-block-decorated-inner-shadow-3::before {
|
|
129
133
|
box-shadow:
|
|
130
|
-
var(--ui-block-decorated-inner-shadow-3, inset 0 4px 6px
|
|
134
|
+
var(--ui-block-decorated-inner-shadow-3, inset 0 4px 6px color-mix(in srgb, var(--_inner-shadow-colour) 12%, transparent)),
|
|
131
135
|
var(--ui-block-decorated-inner-shadow-highlight, inset 0 1px 0 rgba(255, 255, 255, 0.15));
|
|
132
136
|
}
|
|
133
137
|
|
|
134
138
|
&.ui-block-decorated-inner-shadow-4::before {
|
|
135
139
|
box-shadow:
|
|
136
|
-
var(--ui-block-decorated-inner-shadow-4, inset 0 6px 8px
|
|
140
|
+
var(--ui-block-decorated-inner-shadow-4, inset 0 6px 8px color-mix(in srgb, var(--_inner-shadow-colour) 14%, transparent)),
|
|
137
141
|
var(--ui-block-decorated-inner-shadow-highlight, inset 0 1px 0 rgba(255, 255, 255, 0.15));
|
|
138
142
|
}
|
|
139
143
|
}
|