tide-design-system 2.1.7 → 2.1.8
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/.storybook/main.ts +1 -0
- package/dist/css/realm/aero.css +3 -3
- package/dist/css/realm/boatmart.css +1 -1
- package/dist/css/realm/cycle.css +1 -1
- package/dist/css/realm/equipment.css +1 -1
- package/dist/css/realm/pwc.css +1 -1
- package/dist/css/reset.css +7 -0
- package/dist/style.css +1 -1
- package/dist/tide-design-system.cjs +2 -2
- package/dist/tide-design-system.esm.d.ts +40 -22
- package/dist/tide-design-system.esm.js +787 -785
- package/dist/utilities/event.ts +4 -0
- package/dist/utilities/storybook.ts +4 -0
- package/dist/utilities/viewport.ts +44 -0
- package/index.ts +2 -4
- package/package.json +4 -1
- package/src/assets/css/realm/aero.css +3 -3
- package/src/assets/css/realm/boatmart.css +1 -1
- package/src/assets/css/realm/cycle.css +1 -1
- package/src/assets/css/realm/equipment.css +1 -1
- package/src/assets/css/realm/pwc.css +1 -1
- package/src/assets/css/reset.css +7 -0
- package/src/components/TideCard.vue +3 -7
- package/src/components/TideModal.vue +164 -132
- package/src/components/TidePopover.vue +167 -0
- package/src/stories/TideAccordionItem.stories.ts +1 -0
- package/src/stories/TideButtonSegmented.stories.ts +1 -0
- package/src/stories/TideCard.stories.ts +1 -11
- package/src/stories/TideCarousel.stories.ts +1 -0
- package/src/stories/TideModal.stories.ts +68 -6
- package/src/stories/TidePagination.stories.ts +1 -0
- package/src/stories/TidePopover.stories.ts +98 -0
- package/src/stories/TideSwitch.stories.ts +1 -0
- package/src/types/Card.ts +0 -7
- package/src/utilities/event.ts +4 -0
- package/src/utilities/storybook.ts +4 -0
- package/src/utilities/viewport.ts +44 -0
|
@@ -95,6 +95,10 @@ export const doSomething = () => {
|
|
|
95
95
|
alert('Did something.');
|
|
96
96
|
};
|
|
97
97
|
|
|
98
|
+
export const doSomethingElse = () => {
|
|
99
|
+
alert('Did something else.');
|
|
100
|
+
};
|
|
101
|
+
|
|
98
102
|
// Flatten a nested constant into a simple constant.
|
|
99
103
|
export const flatten = (input: Nested): KeyString => {
|
|
100
104
|
const output: KeyString = {};
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { nextTick } from 'vue';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Directly modifies the `<body>` element to apply or remove scroll lock.
|
|
5
|
+
* When `false` is provided, it only unlocks scroll if there are no open
|
|
6
|
+
* HTML dialog elements.
|
|
7
|
+
*/
|
|
8
|
+
export const setScrollLock = async (isLocked: boolean) => {
|
|
9
|
+
const BODY_LOCK_CLASS = 'body-scroll-lock';
|
|
10
|
+
const body = document.body;
|
|
11
|
+
|
|
12
|
+
if (isLocked) {
|
|
13
|
+
if (!body.dataset.scrollLockY) {
|
|
14
|
+
const scrollY = window.scrollY;
|
|
15
|
+
body.dataset.scrollLockY = scrollY.toString();
|
|
16
|
+
body.style.setProperty('--saved-scroll-y', `${scrollY}px`);
|
|
17
|
+
body.classList.add(BODY_LOCK_CLASS);
|
|
18
|
+
}
|
|
19
|
+
} else {
|
|
20
|
+
await nextTick();
|
|
21
|
+
if (!document.querySelector('dialog[open]')) {
|
|
22
|
+
const savedScrollY = parseInt(body.dataset.scrollLockY || '0');
|
|
23
|
+
body.classList.remove(BODY_LOCK_CLASS);
|
|
24
|
+
body.style.removeProperty('--saved-scroll-y');
|
|
25
|
+
window.scrollTo({
|
|
26
|
+
behavior: 'auto',
|
|
27
|
+
top: savedScrollY,
|
|
28
|
+
});
|
|
29
|
+
delete body.dataset.scrollLockY;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
export const TOP_LAYER_ID = 'tideTopLayer';
|
|
35
|
+
|
|
36
|
+
export const initFauxTopLayer = () => {
|
|
37
|
+
let topLayer = document.getElementById(TOP_LAYER_ID);
|
|
38
|
+
if (!topLayer) {
|
|
39
|
+
topLayer = document.createElement('div');
|
|
40
|
+
topLayer.id = TOP_LAYER_ID;
|
|
41
|
+
document.body.appendChild(topLayer);
|
|
42
|
+
}
|
|
43
|
+
topLayer.style.isolation = 'isolate';
|
|
44
|
+
};
|
package/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ import TideSwitch from '@/components/TideSwitch.vue';
|
|
|
32
32
|
import { ALERT } from '@/types/Alert';
|
|
33
33
|
import { BADGE, BADGE_PREMIUM, BADGE_TRUSTED } from '@/types/Badge';
|
|
34
34
|
import { BREAKPOINT, MEDIA } from '@/types/Breakpoint';
|
|
35
|
-
import {
|
|
35
|
+
import { TYPE_CARD } from '@/types/Card';
|
|
36
36
|
import { ELEMENT, ELEMENT_TEXT_AS_ICON } from '@/types/Element';
|
|
37
37
|
import { FORMAT, FORMAT_REGEX } from '@/types/Formatted';
|
|
38
38
|
import { ICON, ICON_REALM } from '@/types/Icon';
|
|
@@ -50,7 +50,7 @@ import type { Alert } from '@/types/Alert';
|
|
|
50
50
|
import type { Badge, BadgePremium, BadgeTrustedYears } from '@/types/Badge';
|
|
51
51
|
import type { BreadCrumb } from '@/types/BreadCrumb';
|
|
52
52
|
import type { Breakpoint, Media } from '@/types/Breakpoint';
|
|
53
|
-
import type {
|
|
53
|
+
import type { CardType } from '@/types/Card';
|
|
54
54
|
import type { Detail } from '@/types/Detail';
|
|
55
55
|
import type { Element, ElementTextAsIcon } from '@/types/Element';
|
|
56
56
|
import type { FacetComponentIdRange, RangeData } from '@/types/FacetRange';
|
|
@@ -107,7 +107,6 @@ export type {
|
|
|
107
107
|
BreadCrumb,
|
|
108
108
|
Breakpoint,
|
|
109
109
|
CardType,
|
|
110
|
-
CardIconPosition,
|
|
111
110
|
CheckboxField,
|
|
112
111
|
CheckboxInput,
|
|
113
112
|
CssUtility,
|
|
@@ -163,7 +162,6 @@ export {
|
|
|
163
162
|
BADGE_PREMIUM,
|
|
164
163
|
BADGE_TRUSTED,
|
|
165
164
|
BREAKPOINT,
|
|
166
|
-
POSITION_CARD_ICON,
|
|
167
165
|
CSS,
|
|
168
166
|
ELEMENT,
|
|
169
167
|
ELEMENT_TEXT_AS_ICON,
|
package/package.json
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
/* Aero Trader Realm Colors */
|
|
2
2
|
:root {
|
|
3
3
|
/* Realm-specific Tonal Palette: Only to be referenced in the assignment of Color Roles below. */
|
|
4
|
-
--tide-realm-aqua: #
|
|
4
|
+
--tide-realm-aqua: #A2DEE5;
|
|
5
5
|
--tide-realm-atmosphere: #3F6EBD;
|
|
6
|
-
--tide-realm-cloud: #
|
|
6
|
+
--tide-realm-cloud: #E3E8F1;
|
|
7
7
|
--tide-realm-sky: #AAD4F0;
|
|
8
|
-
--tide-realm-starry: #
|
|
8
|
+
--tide-realm-starry: #3F6EBD;
|
|
9
9
|
|
|
10
10
|
/* Color Roles: Each realm will assign values to this same series of variables from a combination of the Global and Realm-specific Palettes. */
|
|
11
11
|
--tide-primary: var(--tide-realm-atmosphere);
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
--tide-realm-mist: #DBEDFC;
|
|
6
6
|
--tide-realm-navy-dark: #143353;
|
|
7
7
|
--tide-realm-navy: #1D4977;
|
|
8
|
-
--tide-realm-orange: #
|
|
8
|
+
--tide-realm-orange: #D24614;
|
|
9
9
|
|
|
10
10
|
/* Color Roles: Each realm will assign values to this same series of variables from a combination of the Global and Realm-specific Palettes. */
|
|
11
11
|
--tide-primary: var(--tide-realm-navy);
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
--tide-realm-light-blue: #DFECF2;
|
|
5
5
|
--tide-realm-pure-black: #000000;
|
|
6
6
|
--tide-realm-red: #C50000;
|
|
7
|
-
--tide-realm-steel-blue: #
|
|
7
|
+
--tide-realm-steel-blue: #253E51;
|
|
8
8
|
|
|
9
9
|
/* Color Roles: Each realm will assign values to this same series of variables from a combination of the Global and Realm-specific Palettes. */
|
|
10
10
|
--tide-primary: var(--tide-realm-pure-black);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
/* Realm-specific Tonal Palette: Only to be referenced in the assignment of Color Roles below. */
|
|
4
4
|
--tide-realm-charcoal: #333333;
|
|
5
5
|
--tide-realm-evergreen: #468200;
|
|
6
|
-
--tide-realm-moss: #
|
|
6
|
+
--tide-realm-moss: #EEF6D7;
|
|
7
7
|
--tide-realm-steel: #494949;
|
|
8
8
|
--tide-realm-yellow: #FFCE34;
|
|
9
9
|
|
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
--tide-realm-baby-blue: #86C0F4;
|
|
5
5
|
--tide-realm-blue: #0B72B8;
|
|
6
6
|
--tide-realm-cantaloupe: #ECA26A;
|
|
7
|
-
--tide-realm-foam: #
|
|
7
|
+
--tide-realm-foam: #E0EBF5;
|
|
8
8
|
--tide-realm-midnight-blue: #002344;
|
|
9
9
|
|
|
10
10
|
/* Color Roles: Each realm will assign values to this same series of variables from a combination of the Global and Realm-specific Palettes. */
|
package/src/assets/css/reset.css
CHANGED
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
2
|
import TideIcon from '@/components/TideIcon.vue';
|
|
3
|
-
import {
|
|
3
|
+
import { TYPE_CARD } from '@/types/Card';
|
|
4
4
|
import { SIZE } from '@/types/Size';
|
|
5
5
|
import { CSS } from '@/types/Styles';
|
|
6
6
|
|
|
7
|
-
import type {
|
|
7
|
+
import type { CardType } from '@/types/Card';
|
|
8
8
|
import type { Icon } from '@/types/Icon';
|
|
9
9
|
|
|
10
10
|
type Props = {
|
|
11
11
|
description?: string;
|
|
12
12
|
heading: string;
|
|
13
13
|
icon?: Icon;
|
|
14
|
-
iconPosition: CardIconPosition;
|
|
15
14
|
selected?: boolean;
|
|
16
15
|
type: CardType;
|
|
17
16
|
href?: string;
|
|
@@ -21,7 +20,6 @@
|
|
|
21
20
|
description: undefined,
|
|
22
21
|
href: undefined,
|
|
23
22
|
icon: undefined,
|
|
24
|
-
iconPosition: POSITION_CARD_ICON.LEFT,
|
|
25
23
|
selected: undefined,
|
|
26
24
|
type: TYPE_CARD.INFORMATIONAL,
|
|
27
25
|
});
|
|
@@ -39,9 +37,7 @@
|
|
|
39
37
|
CSS.PADDING.FULL.ONE,
|
|
40
38
|
CSS.WIDTH.FULL,
|
|
41
39
|
CSS.ALIGN.X.LEFT,
|
|
42
|
-
|
|
43
|
-
? CSS.FLEX.DIRECTION.ROW
|
|
44
|
-
: iconPosition === POSITION_CARD_ICON.TOP && CSS.FLEX.DIRECTION.COLUMN,
|
|
40
|
+
CSS.FLEX.DIRECTION.COLUMN,
|
|
45
41
|
type !== TYPE_CARD.INFORMATIONAL && 'hoverable',
|
|
46
42
|
type === TYPE_CARD.SELECTABLE && selected && 'selected',
|
|
47
43
|
]"
|
|
@@ -1,187 +1,219 @@
|
|
|
1
1
|
<script lang="ts" setup>
|
|
2
|
-
import { onMounted, ref, watch } from 'vue';
|
|
2
|
+
import { nextTick, onMounted, ref, watch } from 'vue';
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import TideButtonIcon from '@/components/TideButtonIcon.vue';
|
|
5
|
+
import { BREAKPOINT } from '@/types/Breakpoint';
|
|
5
6
|
import { ICON } from '@/types/Icon';
|
|
7
|
+
import { PRIORITY } from '@/types/Priority';
|
|
6
8
|
import { CSS } from '@/types/Styles';
|
|
9
|
+
import { setScrollLock } from '@/utilities/viewport';
|
|
10
|
+
|
|
11
|
+
import type { Ref } from 'vue';
|
|
7
12
|
|
|
8
13
|
type Props = {
|
|
14
|
+
isBackButton?: boolean;
|
|
15
|
+
isDismissible?: boolean;
|
|
9
16
|
isOpen: boolean;
|
|
10
17
|
title?: string;
|
|
11
18
|
width?: string;
|
|
12
19
|
};
|
|
13
20
|
|
|
14
|
-
const props = defineProps<Props>()
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
const handleClose = () => {
|
|
22
|
-
isOpen.value = false;
|
|
21
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
22
|
+
isBackButton: false,
|
|
23
|
+
isDismissible: true,
|
|
24
|
+
title: undefined,
|
|
25
|
+
width: undefined,
|
|
26
|
+
});
|
|
23
27
|
|
|
24
|
-
|
|
25
|
-
|
|
28
|
+
type Emits = {
|
|
29
|
+
(e: 'close'): void;
|
|
30
|
+
(e: 'back'): void;
|
|
26
31
|
};
|
|
27
32
|
|
|
28
|
-
const
|
|
29
|
-
if (isOpen.value) {
|
|
30
|
-
savedScrollPosition.value = window.scrollY;
|
|
31
|
-
document.body.style.overflow = 'hidden';
|
|
32
|
-
savedScrollPosition.value && window.scrollTo(0, savedScrollPosition.value);
|
|
33
|
+
const emit = defineEmits<Emits>();
|
|
33
34
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
document.body.style.overflow = '';
|
|
35
|
+
const modalContent: Ref<HTMLDivElement | undefined> = ref();
|
|
36
|
+
const modalDialog: Ref<HTMLDialogElement | undefined> = ref();
|
|
37
37
|
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
const triggerNativeDialogOpen = () => {
|
|
39
|
+
modalDialog.value?.showModal();
|
|
40
40
|
};
|
|
41
41
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
event.stopPropagation();
|
|
45
|
-
handleClose();
|
|
46
|
-
}
|
|
47
|
-
};
|
|
48
|
-
|
|
49
|
-
const addOpenListeners = () => {
|
|
50
|
-
window.addEventListener('keydown', handleKeyDown);
|
|
42
|
+
const triggerNativeDialogClose = () => {
|
|
43
|
+
modalDialog.value?.close();
|
|
51
44
|
};
|
|
52
45
|
|
|
53
|
-
const
|
|
54
|
-
|
|
46
|
+
const scrollContentToTop = () => {
|
|
47
|
+
nextTick(() => {
|
|
48
|
+
if (!modalContent.value) return;
|
|
49
|
+
modalContent.value.scrollTop = 0;
|
|
50
|
+
});
|
|
55
51
|
};
|
|
56
52
|
|
|
57
|
-
onMounted(() => {
|
|
58
|
-
updateModalDisplay();
|
|
59
|
-
});
|
|
60
|
-
|
|
61
53
|
watch(
|
|
62
54
|
() => props.isOpen,
|
|
63
55
|
(newValue) => {
|
|
64
|
-
|
|
65
|
-
|
|
56
|
+
if (!modalDialog.value) return;
|
|
57
|
+
if (newValue) {
|
|
58
|
+
triggerNativeDialogOpen();
|
|
59
|
+
scrollContentToTop();
|
|
60
|
+
} else {
|
|
61
|
+
triggerNativeDialogClose();
|
|
62
|
+
}
|
|
63
|
+
setScrollLock(newValue);
|
|
66
64
|
}
|
|
67
65
|
);
|
|
66
|
+
|
|
67
|
+
onMounted(() => {
|
|
68
|
+
if (props.isOpen) {
|
|
69
|
+
triggerNativeDialogOpen();
|
|
70
|
+
}
|
|
71
|
+
});
|
|
68
72
|
</script>
|
|
69
73
|
|
|
70
74
|
<template>
|
|
71
|
-
<
|
|
75
|
+
<dialog
|
|
76
|
+
:class="['tide-modal', CSS.BG.INITIAL, CSS.HEIGHT.FULL, CSS.WIDTH.FULL, CSS.OVERFLOW.XY.HIDDEN]"
|
|
77
|
+
ref="modalDialog"
|
|
78
|
+
:style="{ '--modal-width': props.width }"
|
|
79
|
+
@click.self="emit('close')"
|
|
80
|
+
@close="emit('close')"
|
|
81
|
+
>
|
|
72
82
|
<div
|
|
73
83
|
:class="[
|
|
74
|
-
'tide-modal-
|
|
75
|
-
CSS.
|
|
84
|
+
'tide-modal-body',
|
|
85
|
+
CSS.BG.SURFACE.DEFAULT,
|
|
86
|
+
CSS.BORDER.RADIUS.ONE,
|
|
76
87
|
CSS.DISPLAY.FLEX,
|
|
77
|
-
CSS.
|
|
78
|
-
CSS.
|
|
79
|
-
CSS.
|
|
80
|
-
CSS.POSITIONING.
|
|
88
|
+
CSS.FLEX.DIRECTION.COLUMN,
|
|
89
|
+
CSS.OVERFLOW.XY.HIDDEN,
|
|
90
|
+
CSS.POSITION.ABSOLUTE,
|
|
91
|
+
CSS.POSITIONING.BOTTOM,
|
|
92
|
+
CSS.SHADOW.TOP,
|
|
81
93
|
CSS.WIDTH.FULL,
|
|
82
|
-
CSS.
|
|
83
|
-
|
|
84
|
-
CSS.OVERFLOW.Y.HIDDEN,
|
|
94
|
+
CSS.WIDTH.MAX_FULL,
|
|
95
|
+
CSS.withBreakpoint([CSS.SHADOW.BOTTOM], BREAKPOINT.SM),
|
|
85
96
|
]"
|
|
86
97
|
>
|
|
87
|
-
<
|
|
88
|
-
:class="[
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
98
|
+
<header
|
|
99
|
+
:class="[
|
|
100
|
+
'tide-modal-header',
|
|
101
|
+
CSS.DISPLAY.FLEX,
|
|
102
|
+
CSS.AXIS2.CENTER,
|
|
103
|
+
CSS.GAP.HALF,
|
|
104
|
+
CSS.PADDING.Y.ONE,
|
|
105
|
+
CSS.BORDER.BOTTOM.ONE,
|
|
106
|
+
CSS.BORDER.COLOR.LOW,
|
|
107
|
+
]"
|
|
108
|
+
>
|
|
109
|
+
<TideButtonIcon
|
|
110
|
+
:icon="ICON.CHEVRON_LEFT"
|
|
111
|
+
:priority="PRIORITY.QUATERNARY"
|
|
112
|
+
@click="emit('back')"
|
|
113
|
+
title="Back"
|
|
114
|
+
v-if="isBackButton"
|
|
115
|
+
/>
|
|
116
|
+
|
|
117
|
+
<div
|
|
118
|
+
:class="[CSS.FONT.ROLE.HEADLINE_2]"
|
|
119
|
+
v-text="title"
|
|
120
|
+
/>
|
|
121
|
+
|
|
122
|
+
<TideButtonIcon
|
|
123
|
+
:class="[CSS.FLEX.GROW.OFF, CSS.FLEX.SHRINK.OFF, CSS.MARGIN.LEFT.AUTO]"
|
|
124
|
+
:icon="ICON.CLOSE"
|
|
125
|
+
:priority="PRIORITY.QUATERNARY"
|
|
126
|
+
@click="triggerNativeDialogClose"
|
|
127
|
+
v-if="isDismissible"
|
|
128
|
+
/>
|
|
129
|
+
</header>
|
|
92
130
|
|
|
93
131
|
<div
|
|
94
132
|
:class="[
|
|
95
|
-
'tide-modal',
|
|
96
|
-
CSS.
|
|
97
|
-
CSS.
|
|
98
|
-
CSS.
|
|
99
|
-
CSS.
|
|
100
|
-
CSS.
|
|
101
|
-
CSS.BORDER.RADIUS.ONE,
|
|
102
|
-
CSS.OVERFLOW.XY.HIDDEN,
|
|
103
|
-
CSS.SHADOW.BOTTOM,
|
|
133
|
+
'tide-modal-content',
|
|
134
|
+
CSS.DISPLAY.GRID,
|
|
135
|
+
CSS.OVERFLOW.Y.AUTO,
|
|
136
|
+
CSS.OVERFLOW.X.HIDDEN,
|
|
137
|
+
CSS.WIDTH.FULL,
|
|
138
|
+
CSS.PADDING.Y.TWO,
|
|
104
139
|
]"
|
|
140
|
+
ref="modalContent"
|
|
105
141
|
>
|
|
106
|
-
<
|
|
107
|
-
:class="[
|
|
108
|
-
'tide-modal-header',
|
|
109
|
-
CSS.POSITION.RELATIVE,
|
|
110
|
-
CSS.DISPLAY.FLEX,
|
|
111
|
-
CSS.AXIS2.CENTER,
|
|
112
|
-
CSS.PADDING.Y.ONE,
|
|
113
|
-
CSS.PADDING.X.TWO,
|
|
114
|
-
CSS.BORDER.BOTTOM.ONE,
|
|
115
|
-
CSS.BORDER.COLOR.LOW,
|
|
116
|
-
]"
|
|
117
|
-
>
|
|
118
|
-
<div
|
|
119
|
-
:class="[CSS.FLEX.GROW.ON, CSS.FONT.SIZE.TWENTY, CSS.FONT.WEIGHT.SEVEN_HUNDRED]"
|
|
120
|
-
v-if="title"
|
|
121
|
-
>
|
|
122
|
-
{{ title }}
|
|
123
|
-
</div>
|
|
124
|
-
|
|
125
|
-
<button
|
|
126
|
-
:class="[CSS.POSITION.ABSOLUTE, CSS.POSITIONING.RIGHT, CSS.MARGIN.RIGHT.TWO]"
|
|
127
|
-
@click="handleClose"
|
|
128
|
-
title="Close"
|
|
129
|
-
>
|
|
130
|
-
<TideIcon :icon="ICON.CLOSE" />
|
|
131
|
-
</button>
|
|
132
|
-
</header>
|
|
133
|
-
|
|
134
|
-
<div :class="['tide-modal-content', CSS.PADDING.FULL.TWO, CSS.OVERFLOW.Y.AUTO]">
|
|
135
|
-
<slot />
|
|
136
|
-
</div>
|
|
137
|
-
|
|
138
|
-
<template v-if="$slots.footer">
|
|
139
|
-
<footer
|
|
140
|
-
:class="[
|
|
141
|
-
'tide-bg-surface',
|
|
142
|
-
CSS.POSITION.STICKY,
|
|
143
|
-
CSS.POSITIONING.LEFT,
|
|
144
|
-
CSS.POSITIONING.BOTTOM,
|
|
145
|
-
CSS.DISPLAY.FLEX,
|
|
146
|
-
CSS.AXIS1.END,
|
|
147
|
-
CSS.GAP.ONE,
|
|
148
|
-
CSS.PADDING.X.TWO,
|
|
149
|
-
CSS.PADDING.Y.ONE,
|
|
150
|
-
CSS.SHADOW.TOP,
|
|
151
|
-
]"
|
|
152
|
-
>
|
|
153
|
-
<slot name="footer" />
|
|
154
|
-
</footer>
|
|
155
|
-
</template>
|
|
142
|
+
<slot />
|
|
156
143
|
</div>
|
|
144
|
+
|
|
145
|
+
<footer
|
|
146
|
+
:class="['tide-modal-footer', CSS.AXIS1.END, CSS.DISPLAY.FLEX, CSS.GAP.TWO, CSS.PADDING.Y.ONE, CSS.SHADOW.TOP]"
|
|
147
|
+
v-if="$slots.footer"
|
|
148
|
+
>
|
|
149
|
+
<slot name="footer" />
|
|
150
|
+
</footer>
|
|
157
151
|
</div>
|
|
158
|
-
</
|
|
152
|
+
</dialog>
|
|
159
153
|
</template>
|
|
160
154
|
|
|
161
155
|
<style scoped>
|
|
162
156
|
.tide-modal {
|
|
163
|
-
|
|
164
|
-
max-width:
|
|
165
|
-
max-height:
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
transition: var(--tide-animate);
|
|
169
|
-
|
|
157
|
+
--modal-padding-x: 20px;
|
|
158
|
+
max-width: unset;
|
|
159
|
+
max-height: unset;
|
|
160
|
+
place-items: center;
|
|
161
|
+
display: none;
|
|
162
|
+
transition: all var(--tide-animate) allow-discrete;
|
|
163
|
+
transform: translateY(100%);
|
|
170
164
|
}
|
|
171
|
-
|
|
172
|
-
|
|
165
|
+
.tide-modal:open {
|
|
166
|
+
display: grid;
|
|
167
|
+
transform: translateY(0%);
|
|
168
|
+
}
|
|
169
|
+
.tide-modal::backdrop {
|
|
170
|
+
background-color: transparent;
|
|
171
|
+
transition: all var(--tide-animate) allow-discrete;
|
|
173
172
|
backdrop-filter: blur(0px);
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
173
|
+
}
|
|
174
|
+
.tide-modal:open::backdrop {
|
|
175
|
+
background-color: var(--tide-transparent-400);
|
|
176
|
+
backdrop-filter: blur(4px);
|
|
177
|
+
}
|
|
178
|
+
@starting-style {
|
|
179
|
+
.tide-modal:open {
|
|
180
|
+
display: grid;
|
|
181
|
+
transform: translateY(100%);
|
|
182
|
+
}
|
|
183
|
+
.tide-modal:open::backdrop {
|
|
184
|
+
background-color: transparent;
|
|
185
|
+
backdrop-filter: blur(4px);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
.tide-modal-body {
|
|
189
|
+
width: var(--modal-width, 576px);
|
|
190
|
+
max-height: calc(100% - var(--tide-spacing-2));
|
|
177
191
|
}
|
|
178
192
|
|
|
179
|
-
.
|
|
180
|
-
|
|
193
|
+
.tide-modal-header,
|
|
194
|
+
.tide-modal-footer {
|
|
195
|
+
padding-inline: var(--modal-padding-x);
|
|
196
|
+
}
|
|
197
|
+
.tide-modal-content {
|
|
198
|
+
grid-template-columns: var(--modal-padding-x) 1fr var(--modal-padding-x);
|
|
199
|
+
}
|
|
200
|
+
:where(.tide-modal-content):deep(> :where(*)) {
|
|
201
|
+
grid-column: 2;
|
|
181
202
|
}
|
|
182
203
|
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
204
|
+
@media (max-width: 767px) {
|
|
205
|
+
.tide-modal-body {
|
|
206
|
+
border-bottom-left-radius: 0;
|
|
207
|
+
border-bottom-right-radius: 0;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
@media (min-width: 768px) {
|
|
211
|
+
.tide-modal {
|
|
212
|
+
--modal-padding-x: var(--tide-spacing-2);
|
|
213
|
+
}
|
|
214
|
+
.tide-modal-body {
|
|
215
|
+
max-height: 85%;
|
|
216
|
+
bottom: initial;
|
|
217
|
+
}
|
|
186
218
|
}
|
|
187
219
|
</style>
|