tide-design-system 2.0.22 → 2.0.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/.eslintrc.cjs +90 -0
- package/.storybook/main.ts +60 -0
- package/.storybook/preview.ts +252 -0
- package/dist/css/grid-layout.css +7 -3
- package/dist/tide-design-system.js +45 -39
- package/index.ts +122 -0
- package/package.json +8 -12
- package/src/assets/css/animation.css +14 -0
- package/src/assets/css/dynamic-buttons.css +79 -0
- package/src/assets/css/dynamic-utilities.css +39 -0
- package/src/assets/css/grid-layout.css +71 -0
- package/src/assets/css/main.css +5 -0
- package/src/assets/css/realm/aero.css +42 -0
- package/src/assets/css/realm/atv.css +43 -0
- package/src/assets/css/realm/boatmart.css +42 -0
- package/src/assets/css/realm/cycle.css +42 -0
- package/src/assets/css/realm/equip.css +42 -0
- package/src/assets/css/realm/pwc.css +42 -0
- package/src/assets/css/realm/rv.css +50 -0
- package/src/assets/css/realm/snow.css +42 -0
- package/src/assets/css/realm/truck.css +42 -0
- package/src/assets/css/reset.css +79 -0
- package/src/assets/css/storybook.css +9 -0
- package/src/assets/css/utilities.css +1602 -0
- package/src/assets/css/variables.css +118 -0
- package/src/assets/svg/icons/IconAccountBalance.svg +5 -0
- package/src/assets/svg/icons/IconAdd.svg +3 -0
- package/src/assets/svg/icons/IconAiDescription.svg +7 -0
- package/src/assets/svg/icons/IconAlignSpace.svg +3 -0
- package/src/assets/svg/icons/IconApplePay.svg +5 -0
- package/src/assets/svg/icons/IconArrowBack.svg +3 -0
- package/src/assets/svg/icons/IconArrowForward.svg +3 -0
- package/src/assets/svg/icons/IconArrowRight.svg +3 -0
- package/src/assets/svg/icons/IconAssignment.svg +5 -0
- package/src/assets/svg/icons/IconAwardStar.svg +5 -0
- package/src/assets/svg/icons/IconBookmark.svg +5 -0
- package/src/assets/svg/icons/IconCalendarMonth.svg +5 -0
- package/src/assets/svg/icons/IconCall.svg +5 -0
- package/src/assets/svg/icons/IconCheck.svg +3 -0
- package/src/assets/svg/icons/IconChevronLeft.svg +3 -0
- package/src/assets/svg/icons/IconChevronRight.svg +3 -0
- package/src/assets/svg/icons/IconClear.svg +5 -0
- package/src/assets/svg/icons/IconClose.svg +3 -0
- package/src/assets/svg/icons/IconCycle.svg +5 -0
- package/src/assets/svg/icons/IconDelete.svg +5 -0
- package/src/assets/svg/icons/IconDiamond.svg +5 -0
- package/src/assets/svg/icons/IconDraft.svg +3 -0
- package/src/assets/svg/icons/IconEdit.svg +5 -0
- package/src/assets/svg/icons/IconError.svg +5 -0
- package/src/assets/svg/icons/IconExpandContent.svg +3 -0
- package/src/assets/svg/icons/IconExpandLess.svg +3 -0
- package/src/assets/svg/icons/IconExpandMore.svg +3 -0
- package/src/assets/svg/icons/IconFacebook.svg +5 -0
- package/src/assets/svg/icons/IconFavorite.svg +5 -0
- package/src/assets/svg/icons/IconFavoriteFilled.svg +5 -0
- package/src/assets/svg/icons/IconFormatBold.svg +5 -0
- package/src/assets/svg/icons/IconFormatItalic.svg +3 -0
- package/src/assets/svg/icons/IconFormatListBulleted.svg +5 -0
- package/src/assets/svg/icons/IconForum.svg +5 -0
- package/src/assets/svg/icons/IconGavel.svg +5 -0
- package/src/assets/svg/icons/IconGoogle.svg +18 -0
- package/src/assets/svg/icons/IconGooglePay.svg +5 -0
- package/src/assets/svg/icons/IconGrid.svg +3 -0
- package/src/assets/svg/icons/IconHeight.svg +3 -0
- package/src/assets/svg/icons/IconHelp.svg +5 -0
- package/src/assets/svg/icons/IconInfo.svg +5 -0
- package/src/assets/svg/icons/IconInsertText.svg +5 -0
- package/src/assets/svg/icons/IconInstagram.svg +5 -0
- package/src/assets/svg/icons/IconIosShare.svg +5 -0
- package/src/assets/svg/icons/IconLayout.svg +5 -0
- package/src/assets/svg/icons/IconLinkedIn.svg +5 -0
- package/src/assets/svg/icons/IconLocalShipping.svg +5 -0
- package/src/assets/svg/icons/IconLock.svg +5 -0
- package/src/assets/svg/icons/IconMail.svg +5 -0
- package/src/assets/svg/icons/IconMenu.svg +3 -0
- package/src/assets/svg/icons/IconMoreHoriz.svg +5 -0
- package/src/assets/svg/icons/IconNotifications.svg +5 -0
- package/src/assets/svg/icons/IconOpenInNew.svg +5 -0
- package/src/assets/svg/icons/IconPalette.svg +5 -0
- package/src/assets/svg/icons/IconPaypal.svg +5 -0
- package/src/assets/svg/icons/IconPerson.svg +5 -0
- package/src/assets/svg/icons/IconPhotoCamera.svg +5 -0
- package/src/assets/svg/icons/IconPinterest.svg +5 -0
- package/src/assets/svg/icons/IconPlayArrow.svg +3 -0
- package/src/assets/svg/icons/IconRemove.svg +3 -0
- package/src/assets/svg/icons/IconRoundedCorners.svg +5 -0
- package/src/assets/svg/icons/IconRuler.svg +3 -0
- package/src/assets/svg/icons/IconSearch.svg +5 -0
- package/src/assets/svg/icons/IconSeating.svg +3 -0
- package/src/assets/svg/icons/IconSell.svg +5 -0
- package/src/assets/svg/icons/IconShare.svg +5 -0
- package/src/assets/svg/icons/IconShoppingCart.svg +5 -0
- package/src/assets/svg/icons/IconSms.svg +5 -0
- package/src/assets/svg/icons/IconStar.svg +5 -0
- package/src/assets/svg/icons/IconSwapVert.svg +5 -0
- package/src/assets/svg/icons/IconThreeDRotation.svg +18 -0
- package/src/assets/svg/icons/IconTrophy.svg +5 -0
- package/src/assets/svg/icons/IconTune.svg +5 -0
- package/src/assets/svg/icons/IconTwitter.svg +5 -0
- package/src/assets/svg/icons/IconVideocam.svg +5 -0
- package/src/assets/svg/icons/IconViewInAr.svg +5 -0
- package/src/assets/svg/icons/IconVisibility.svg +5 -0
- package/src/assets/svg/icons/IconVolumeOff.svg +5 -0
- package/src/assets/svg/icons/IconVolumeOn.svg +5 -0
- package/src/assets/svg/icons/IconWarning.svg +5 -0
- package/src/assets/svg/icons/IconWeight.svg +3 -0
- package/src/assets/svg/icons/IconWidth.svg +3 -0
- package/src/assets/svg/icons/IconYoutube.svg +5 -0
- package/src/components/TideAccordionItem.vue +105 -0
- package/src/components/TideAlert.vue +124 -0
- package/src/components/TideBackgroundImage.vue +44 -0
- package/src/components/TideBadge.vue +30 -0
- package/src/components/TideBadgePremium.vue +31 -0
- package/src/components/TideBadgeTrustedPartner.vue +38 -0
- package/src/components/TideBreadCrumbs.vue +53 -0
- package/src/components/TideButton.vue +67 -0
- package/src/components/TideButtonIcon.vue +52 -0
- package/src/components/TideButtonPagination.vue +71 -0
- package/src/components/TideCard.vue +19 -0
- package/src/components/TideCarousel.vue +188 -0
- package/src/components/TideChipAction.vue +48 -0
- package/src/components/TideChipFilter.vue +55 -0
- package/src/components/TideChipInput.vue +44 -0
- package/src/components/TideColumns.vue +53 -0
- package/src/components/TideDivider.vue +24 -0
- package/src/components/TideIcon.vue +58 -0
- package/src/components/TideImage.vue +44 -0
- package/src/components/TideIndicator.vue +57 -0
- package/src/components/TideInputCheckbox.vue +145 -0
- package/src/components/TideInputRadio.vue +87 -0
- package/src/components/TideInputSelect.vue +204 -0
- package/src/components/TideInputText.vue +292 -0
- package/src/components/TideInputTextarea.vue +196 -0
- package/src/components/TideLink.vue +66 -0
- package/src/components/TideModal.vue +187 -0
- package/src/components/TidePagination.vue +67 -0
- package/src/components/TideSeoLinks.vue +58 -0
- package/src/components/TideTabs.vue +89 -0
- package/src/components/TideToggle.vue +95 -0
- package/src/docs/development.md +51 -0
- package/src/docs/integration.md +79 -0
- package/src/docs/storybook.md +39 -0
- package/src/stories/DemoCssUtilities.stories.ts +154 -0
- package/src/stories/DemoCssUtilitiesByTextInput.stories.ts +61 -0
- package/src/stories/FoundationsBorder.stories.ts +230 -0
- package/src/stories/FoundationsGap.stories.ts +180 -0
- package/src/stories/FoundationsMargin.stories.ts +155 -0
- package/src/stories/FoundationsPadding.stories.ts +108 -0
- package/src/stories/FoundationsShadow.stories.ts +84 -0
- package/src/stories/FoundationsTypography.stories.ts +172 -0
- package/src/stories/Template.stories.ts +71 -0
- package/src/stories/TideAccordionItem.stories.ts +68 -0
- package/src/stories/TideAlert.stories.ts +58 -0
- package/src/stories/TideBackgroundImage.stories.ts +53 -0
- package/src/stories/TideBadge.stories.ts +31 -0
- package/src/stories/TideBadgePremium.stories.ts +31 -0
- package/src/stories/TideBadgeTrustedPartner.stories.ts +33 -0
- package/src/stories/TideBreadCrumbs.stories.ts +43 -0
- package/src/stories/TideButton.stories.ts +118 -0
- package/src/stories/TideButtonIcon.stories.ts +103 -0
- package/src/stories/TideButtonPagination.stories.ts +99 -0
- package/src/stories/TideCard.stories.ts +38 -0
- package/src/stories/TideCarousel.stories.ts +130 -0
- package/src/stories/TideChipAction.stories.ts +46 -0
- package/src/stories/TideChipFilter.stories.ts +59 -0
- package/src/stories/TideChipInput.stories.ts +42 -0
- package/src/stories/TideColumns.stories.ts +90 -0
- package/src/stories/TideDivider.stories.ts +46 -0
- package/src/stories/TideIcon.stories.ts +29 -0
- package/src/stories/TideIndicator.stories.ts +31 -0
- package/src/stories/TideInputCheckbox.stories.ts +86 -0
- package/src/stories/TideInputRadio.stories.ts +71 -0
- package/src/stories/TideInputSelect.stories.ts +145 -0
- package/src/stories/TideInputText.stories.ts +181 -0
- package/src/stories/TideInputTextarea.stories.ts +116 -0
- package/src/stories/TideLink.stories.ts +137 -0
- package/src/stories/TideModal.stories.ts +122 -0
- package/src/stories/TidePagination.stories.ts +83 -0
- package/src/stories/TideSeoLinks.stories.ts +67 -0
- package/src/stories/TideTabs.stories.ts +100 -0
- package/src/stories/TideToggle.stories.ts +69 -0
- package/src/stories/Welcome.mdx +17 -0
- package/src/types/Alert.ts +8 -0
- package/src/types/Badge.ts +21 -0
- package/src/types/BreadCrumb.ts +5 -0
- package/src/types/Detail.ts +4 -0
- package/src/types/Element.ts +13 -0
- package/src/types/FacetRange.ts +84 -0
- package/src/types/Field.ts +54 -0
- package/src/types/Form.ts +58 -0
- package/src/types/Formatted.ts +22 -0
- package/src/types/Icon.ts +87 -0
- package/src/types/Link.ts +5 -0
- package/src/types/ListingMedia.ts +43 -0
- package/src/types/Orientation.ts +6 -0
- package/src/types/Priority.ts +11 -0
- package/src/types/Raw.ts +5 -0
- package/src/types/Realm.ts +13 -0
- package/src/types/RealmConfig.ts +14 -0
- package/src/types/Select.ts +10 -0
- package/src/types/Size.ts +6 -0
- package/src/types/Storybook.ts +219 -0
- package/src/types/Styles.ts +590 -0
- package/src/types/Tab.ts +5 -0
- package/src/types/Target.ts +6 -0
- package/src/types/TextInput.ts +16 -0
- package/src/types/Validation.ts +24 -0
- package/src/utilities/format.ts +184 -0
- package/src/utilities/storybook.ts +295 -0
- package/src/utilities/validation.ts +197 -0
- package/tests/utilities-format.spec.ts +430 -0
- package/tsconfig.app.json +14 -0
- package/tsconfig.config.json +12 -0
- package/tsconfig.json +22 -0
- package/tsconfig.vitest.json +10 -0
- package/vite.config.ts +43 -0
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { onMounted, ref, watch } from 'vue';
|
|
3
|
+
|
|
4
|
+
import TideIcon from '@/components/TideIcon.vue';
|
|
5
|
+
import { CSS } from '@/types/Styles';
|
|
6
|
+
import { ICON } from '@/types/Icon';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
isOpen: boolean;
|
|
10
|
+
title?: string;
|
|
11
|
+
width?: string;
|
|
12
|
+
};
|
|
13
|
+
|
|
14
|
+
const props = defineProps<Props>();
|
|
15
|
+
|
|
16
|
+
const emit = defineEmits(['close']);
|
|
17
|
+
|
|
18
|
+
const isOpen = ref(props.isOpen);
|
|
19
|
+
const savedScrollPosition = ref<number | null>(null); // TODO: replace body scroll lock with global structure?
|
|
20
|
+
|
|
21
|
+
const handleClose = (event: Event) => {
|
|
22
|
+
isOpen.value = false;
|
|
23
|
+
|
|
24
|
+
updateModalDisplay();
|
|
25
|
+
emit('close', event);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
const updateModalDisplay = () => {
|
|
29
|
+
if (isOpen.value) {
|
|
30
|
+
savedScrollPosition.value = window.scrollY;
|
|
31
|
+
document.body.style.overflow = 'hidden';
|
|
32
|
+
savedScrollPosition.value && window.scrollTo(0, savedScrollPosition.value);
|
|
33
|
+
|
|
34
|
+
addOpenListeners();
|
|
35
|
+
} else {
|
|
36
|
+
document.body.style.overflow = '';
|
|
37
|
+
|
|
38
|
+
removeOpenListeners();
|
|
39
|
+
}
|
|
40
|
+
};
|
|
41
|
+
|
|
42
|
+
const handleKeyDown = (event: KeyboardEvent) => {
|
|
43
|
+
if (event.key === 'Escape') {
|
|
44
|
+
event.stopPropagation();
|
|
45
|
+
handleClose(event);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
const addOpenListeners = () => {
|
|
50
|
+
window.addEventListener('keydown', handleKeyDown);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
const removeOpenListeners = () => {
|
|
54
|
+
window.removeEventListener('keydown', handleKeyDown);
|
|
55
|
+
};
|
|
56
|
+
|
|
57
|
+
onMounted(() => {
|
|
58
|
+
updateModalDisplay();
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
watch(
|
|
62
|
+
() => props.isOpen,
|
|
63
|
+
(newValue) => {
|
|
64
|
+
isOpen.value = newValue;
|
|
65
|
+
updateModalDisplay();
|
|
66
|
+
}
|
|
67
|
+
);
|
|
68
|
+
</script>
|
|
69
|
+
|
|
70
|
+
<template>
|
|
71
|
+
<Teleport to="body">
|
|
72
|
+
<div
|
|
73
|
+
:class="[
|
|
74
|
+
'tide-modal-wrapper',
|
|
75
|
+
CSS.POSITION.ABSOLUTE,
|
|
76
|
+
CSS.DISPLAY.FLEX,
|
|
77
|
+
CSS.AXIS1.CENTER,
|
|
78
|
+
CSS.AXIS2.CENTER,
|
|
79
|
+
CSS.POSITIONING.TOP,
|
|
80
|
+
CSS.POSITIONING.LEFT,
|
|
81
|
+
CSS.WIDTH.FULL,
|
|
82
|
+
CSS.HEIGHT.FULL,
|
|
83
|
+
props.isOpen ? 'active' : CSS.POINTER_EVENTS.OFF,
|
|
84
|
+
CSS.OVERFLOW.Y.HIDDEN,
|
|
85
|
+
]"
|
|
86
|
+
>
|
|
87
|
+
<div
|
|
88
|
+
:class="['tide-modal-bg', CSS.POSITION.ABSOLUTE, CSS.WIDTH.FULL, CSS.HEIGHT.FULL]"
|
|
89
|
+
:style="{ '--tide-modal-width': props.width }"
|
|
90
|
+
@click.self="handleClose"
|
|
91
|
+
/>
|
|
92
|
+
|
|
93
|
+
<div
|
|
94
|
+
:class="[
|
|
95
|
+
'tide-modal',
|
|
96
|
+
CSS.BG.SURFACE.DEFAULT,
|
|
97
|
+
CSS.FONT.COLOR.SURFACE.DEFAULT,
|
|
98
|
+
CSS.POSITION.ABSOLUTE,
|
|
99
|
+
CSS.DISPLAY.FLEX,
|
|
100
|
+
CSS.FLEX.DIRECTION.COLUMN,
|
|
101
|
+
CSS.BORDER.RADIUS.ONE,
|
|
102
|
+
CSS.OVERFLOW.XY.HIDDEN,
|
|
103
|
+
CSS.SHADOW.BOTTOM,
|
|
104
|
+
]"
|
|
105
|
+
>
|
|
106
|
+
<header
|
|
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>
|
|
156
|
+
</div>
|
|
157
|
+
</div>
|
|
158
|
+
</Teleport>
|
|
159
|
+
</template>
|
|
160
|
+
|
|
161
|
+
<style scoped>
|
|
162
|
+
.tide-modal {
|
|
163
|
+
width: var(--tide-modal-width);
|
|
164
|
+
max-width: calc(100% - 2rem);
|
|
165
|
+
max-height: calc(100% - 2rem);
|
|
166
|
+
box-shadow: 0px 10px 25px 0px rgba(18, 43, 58, 0.2);
|
|
167
|
+
transform: translateY(100vh);
|
|
168
|
+
transition: var(--tide-animate);
|
|
169
|
+
transition-property: transform;
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
.tide-modal-bg {
|
|
173
|
+
backdrop-filter: blur(0px);
|
|
174
|
+
background-color: rgba(255, 255, 255, 0);
|
|
175
|
+
transition: var(--tide-animate);
|
|
176
|
+
transition-property: backdrop-filter, background-color;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
.active .tide-modal {
|
|
180
|
+
transform: translateY(0);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
.active .tide-modal-bg {
|
|
184
|
+
backdrop-filter: blur(8px);
|
|
185
|
+
background-color: var(--tide-transparent-400);
|
|
186
|
+
}
|
|
187
|
+
</style>
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { computed, ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
import TideButtonIcon from '@/components/TideButtonIcon.vue';
|
|
5
|
+
import TideButtonPagination from '@/components/TideButtonPagination.vue';
|
|
6
|
+
import { CSS } from '@/types/Styles';
|
|
7
|
+
import { ICON } from '@/types/Icon';
|
|
8
|
+
import { PRIORITY } from '@/types/Priority';
|
|
9
|
+
|
|
10
|
+
type Props = {
|
|
11
|
+
pageCurrent?: number;
|
|
12
|
+
pageTotal?: number;
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
pageCurrent: 1,
|
|
17
|
+
pageTotal: 1,
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
const emit = defineEmits(['change']);
|
|
21
|
+
|
|
22
|
+
const pageCurrent = ref(props.pageCurrent);
|
|
23
|
+
|
|
24
|
+
const paginationButtons = computed(() => new Array(props.pageTotal).fill('').map((empty, index) => index + 1));
|
|
25
|
+
|
|
26
|
+
const handleClick = (event: Event, index: number) => {
|
|
27
|
+
pageCurrent.value = index;
|
|
28
|
+
|
|
29
|
+
emit('change', event, index);
|
|
30
|
+
};
|
|
31
|
+
</script>
|
|
32
|
+
|
|
33
|
+
<template>
|
|
34
|
+
<section
|
|
35
|
+
:class="['tide-pagination', CSS.DISPLAY.FLEX, CSS.AXIS1.CENTER, CSS.AXIS2.CENTER, CSS.GAP.QUARTER, CSS.WIDTH.FULL]"
|
|
36
|
+
>
|
|
37
|
+
<TideButtonIcon
|
|
38
|
+
:disabled="pageCurrent === 1"
|
|
39
|
+
:icon="ICON.CHEVRON_LEFT"
|
|
40
|
+
:priority="PRIORITY.QUATERNARY"
|
|
41
|
+
@click="(event: Event) => handleClick(event, pageCurrent - 1)"
|
|
42
|
+
/>
|
|
43
|
+
|
|
44
|
+
<ul :class="[CSS.DISPLAY.FLEX, CSS.AXIS2.CENTER, CSS.GAP.QUARTER, CSS.LIST_BULLETS.OFF]">
|
|
45
|
+
<li
|
|
46
|
+
:key="paginationButton"
|
|
47
|
+
v-for="paginationButton in paginationButtons"
|
|
48
|
+
>
|
|
49
|
+
<TideButtonPagination
|
|
50
|
+
:disabled="pageCurrent === paginationButton"
|
|
51
|
+
:label="paginationButton"
|
|
52
|
+
:priority="PRIORITY.QUATERNARY"
|
|
53
|
+
@click="(event: Event) => handleClick(event, paginationButton)"
|
|
54
|
+
/>
|
|
55
|
+
</li>
|
|
56
|
+
</ul>
|
|
57
|
+
|
|
58
|
+
<TideButtonIcon
|
|
59
|
+
:disabled="pageCurrent === paginationButtons[paginationButtons.length - 1]"
|
|
60
|
+
:icon="ICON.CHEVRON_RIGHT"
|
|
61
|
+
:priority="PRIORITY.QUATERNARY"
|
|
62
|
+
@click="(event: Event) => handleClick(event, pageCurrent + 1)"
|
|
63
|
+
/>
|
|
64
|
+
</section>
|
|
65
|
+
</template>
|
|
66
|
+
|
|
67
|
+
<style scoped></style>
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import type { Link } from '@/types/Link';
|
|
3
|
+
|
|
4
|
+
import { CSS } from '@/types/Styles';
|
|
5
|
+
import { TARGET } from '@/types/Target';
|
|
6
|
+
|
|
7
|
+
type Props = {
|
|
8
|
+
heading?: string;
|
|
9
|
+
links: Link[];
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
13
|
+
heading: '',
|
|
14
|
+
});
|
|
15
|
+
</script>
|
|
16
|
+
|
|
17
|
+
<template>
|
|
18
|
+
<section class="tide-seo-links">
|
|
19
|
+
<h2 :class="[CSS.MARGIN.BOTTOM.HALF, CSS.FONT.SIZE.SIXTEEN]">
|
|
20
|
+
{{ props.heading }}
|
|
21
|
+
</h2>
|
|
22
|
+
|
|
23
|
+
<ul :class="[CSS.DISPLAY.FLEX, CSS.FLEX.WRAP, CSS.GAP.TWO, CSS.LIST_BULLETS.OFF]">
|
|
24
|
+
<li
|
|
25
|
+
:class="['tide-seo-link', CSS.DISPLAY.FLEX, CSS.FLEX.DIRECTION.COLUMN, CSS.GAP.QUARTER, CSS.FONT.SIZE.FOURTEEN]"
|
|
26
|
+
:key="link.label"
|
|
27
|
+
v-for="link in props.links"
|
|
28
|
+
>
|
|
29
|
+
<a
|
|
30
|
+
:class="[CSS.UNDERLINE.OFF]"
|
|
31
|
+
:href="link.url"
|
|
32
|
+
:target="link.isNewTab ? TARGET.BLANK : TARGET.SELF"
|
|
33
|
+
>
|
|
34
|
+
{{ link.label }}
|
|
35
|
+
</a>
|
|
36
|
+
</li>
|
|
37
|
+
</ul>
|
|
38
|
+
</section>
|
|
39
|
+
</template>
|
|
40
|
+
|
|
41
|
+
<style scoped>
|
|
42
|
+
/* TODO: Refactor to accept breakpoint prop in order to accomplish this with neither custom breakpoints nor dependency on ViewportStore. */
|
|
43
|
+
.tide-seo-link {
|
|
44
|
+
width: 100%;
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
@media (min-width: 992px) {
|
|
48
|
+
.tide-seo-link {
|
|
49
|
+
width: calc((100% - 2rem) / 2);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
@media (min-width: 1232px) {
|
|
54
|
+
.tide-seo-link {
|
|
55
|
+
width: calc((100% - 6rem) / 4);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
</style>
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
import type { Tab } from '@/types/Tab';
|
|
5
|
+
|
|
6
|
+
import { CSS } from '@/types/Styles';
|
|
7
|
+
|
|
8
|
+
type Props = {
|
|
9
|
+
activeTabInitial?: number;
|
|
10
|
+
tabs: Tab[];
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
14
|
+
activeTabInitial: 0,
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
const emit = defineEmits(['change']);
|
|
18
|
+
|
|
19
|
+
const activeTab = ref(props.activeTabInitial);
|
|
20
|
+
|
|
21
|
+
const handleClick = (event: Event, index: number) => {
|
|
22
|
+
activeTab.value = index;
|
|
23
|
+
|
|
24
|
+
emit('change', event, index);
|
|
25
|
+
};
|
|
26
|
+
</script>
|
|
27
|
+
|
|
28
|
+
<template>
|
|
29
|
+
<div
|
|
30
|
+
:class="[
|
|
31
|
+
'tide-tabs',
|
|
32
|
+
CSS.BG.SURFACE.VARIANT,
|
|
33
|
+
CSS.DISPLAY.FLEX,
|
|
34
|
+
CSS.GAP.QUARTER,
|
|
35
|
+
CSS.BORDER.RADIUS.HALF,
|
|
36
|
+
CSS.PADDING.FULL.QUARTER,
|
|
37
|
+
CSS.OVERFLOW.XY.HIDDEN,
|
|
38
|
+
CSS.WIDTH.FULL,
|
|
39
|
+
]"
|
|
40
|
+
>
|
|
41
|
+
<button
|
|
42
|
+
:class="[
|
|
43
|
+
'tide-tabs-tab',
|
|
44
|
+
index === activeTab
|
|
45
|
+
? [CSS.BG.SURFACE.DEFAULT, CSS.FONT.COLOR.SURFACE.DEFAULT, CSS.SHADOW.BOTTOM]
|
|
46
|
+
: ['inactive', CSS.FONT.COLOR.SURFACE.VARIANT],
|
|
47
|
+
CSS.FLEX.GROW.ON,
|
|
48
|
+
CSS.BORDER.RADIUS.QUARTER,
|
|
49
|
+
CSS.PADDING.Y.QUARTER,
|
|
50
|
+
CSS.WIDTH.FULL,
|
|
51
|
+
CSS.FONT.WEIGHT.SIX_HUNDRED,
|
|
52
|
+
CSS.WHITESPACE_WRAP.OFF,
|
|
53
|
+
]"
|
|
54
|
+
:data-track="tab.dataTrack || undefined"
|
|
55
|
+
:key="tab.label"
|
|
56
|
+
@click="(event: Event) => handleClick(event, index)"
|
|
57
|
+
v-for="(tab, index) in props.tabs"
|
|
58
|
+
>
|
|
59
|
+
<span :class="[CSS.FONT.WEIGHT.SIX_HUNDRED]">
|
|
60
|
+
{{ tab.label }}
|
|
61
|
+
</span>
|
|
62
|
+
<span
|
|
63
|
+
:class="[CSS.FONT.WEIGHT.SIX_HUNDRED]"
|
|
64
|
+
v-if="tab.count && tab.count > 0"
|
|
65
|
+
>
|
|
66
|
+
({{ tab.count }})
|
|
67
|
+
</span>
|
|
68
|
+
</button>
|
|
69
|
+
</div>
|
|
70
|
+
</template>
|
|
71
|
+
|
|
72
|
+
<style scoped>
|
|
73
|
+
.tide-tabs {
|
|
74
|
+
max-width: 23.3rem;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
.tide-tabs-tab {
|
|
78
|
+
flex: 1;
|
|
79
|
+
transition: background-color var(--tide-animate);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.inactive:not(:hover) {
|
|
83
|
+
border: 1px solid var(--tide-surface-variant);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.inactive:hover {
|
|
87
|
+
border: 1px solid var(--tide-border);
|
|
88
|
+
}
|
|
89
|
+
</style>
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
<script lang="ts" setup>
|
|
2
|
+
import { ref } from 'vue';
|
|
3
|
+
|
|
4
|
+
import TideIcon from '@/components/TideIcon.vue';
|
|
5
|
+
import { CSS } from '@/types/Styles';
|
|
6
|
+
import { ICON } from '@/types/Icon';
|
|
7
|
+
import { SIZE } from '@/types/Size';
|
|
8
|
+
|
|
9
|
+
const props = defineProps({
|
|
10
|
+
disabled: {
|
|
11
|
+
default: false,
|
|
12
|
+
required: false,
|
|
13
|
+
type: Boolean,
|
|
14
|
+
},
|
|
15
|
+
isActive: {
|
|
16
|
+
required: true,
|
|
17
|
+
type: Boolean,
|
|
18
|
+
},
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
const emit = defineEmits(['change']);
|
|
22
|
+
|
|
23
|
+
const isActive = ref(props.isActive);
|
|
24
|
+
|
|
25
|
+
const handleClick = (event: Event) => {
|
|
26
|
+
if (!props.disabled) {
|
|
27
|
+
isActive.value = !isActive.value;
|
|
28
|
+
|
|
29
|
+
emit('change', event, isActive.value);
|
|
30
|
+
}
|
|
31
|
+
};
|
|
32
|
+
</script>
|
|
33
|
+
|
|
34
|
+
<template>
|
|
35
|
+
<button
|
|
36
|
+
:class="[
|
|
37
|
+
'tide-toggle',
|
|
38
|
+
props.isActive ? 'active' : '',
|
|
39
|
+
CSS.DISPLAY.FLEX,
|
|
40
|
+
CSS.AXIS2.CENTER,
|
|
41
|
+
CSS.BORDER.FULL.ONE,
|
|
42
|
+
CSS.BORDER.RADIUS.FULL,
|
|
43
|
+
props.isActive ? '' : CSS.BORDER.COLOR.DEFAULT,
|
|
44
|
+
CSS.OVERFLOW.XY.HIDDEN,
|
|
45
|
+
props.isActive ? CSS.BG.SECONDARY : CSS.BG.SURFACE.DEFAULT,
|
|
46
|
+
]"
|
|
47
|
+
:disabled="props.disabled"
|
|
48
|
+
@click="handleClick"
|
|
49
|
+
aria-label="Toggle"
|
|
50
|
+
>
|
|
51
|
+
<div
|
|
52
|
+
:class="[
|
|
53
|
+
'tide-toggle-indicator',
|
|
54
|
+
CSS.POSITION.RELATIVE,
|
|
55
|
+
CSS.DISPLAY.FLEX,
|
|
56
|
+
CSS.AXIS1.CENTER,
|
|
57
|
+
CSS.AXIS2.CENTER,
|
|
58
|
+
CSS.BORDER.RADIUS.FULL,
|
|
59
|
+
props.isActive ? CSS.BG.SURFACE.DEFAULT : CSS.BG.SECONDARY,
|
|
60
|
+
]"
|
|
61
|
+
>
|
|
62
|
+
<TideIcon
|
|
63
|
+
:icon="ICON.CHECK"
|
|
64
|
+
:size="SIZE.LARGE"
|
|
65
|
+
/>
|
|
66
|
+
</div>
|
|
67
|
+
</button>
|
|
68
|
+
</template>
|
|
69
|
+
|
|
70
|
+
<style scoped>
|
|
71
|
+
.tide-toggle {
|
|
72
|
+
width: 64px;
|
|
73
|
+
height: 32px;
|
|
74
|
+
transition: var(--tide-animate);
|
|
75
|
+
transition-property: background-color;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
.tide-toggle:disabled {
|
|
79
|
+
opacity: 0.32;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
.tide-toggle.active {
|
|
83
|
+
border-color: var(--tide-secondary);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
.tide-toggle.active .tide-toggle-indicator {
|
|
87
|
+
left: 36px;
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
.tide-toggle-indicator {
|
|
91
|
+
left: 4px;
|
|
92
|
+
transition: var(--tide-animate);
|
|
93
|
+
transition-property: left, border-color, background-color;
|
|
94
|
+
}
|
|
95
|
+
</style>
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# TIDE Development
|
|
2
|
+
|
|
3
|
+
## Local Integration
|
|
4
|
+
Run a local instance of `tide-design-system` in parallel with a local consumer project to preview changes prior to publishing a revision to the NPM Registrty.
|
|
5
|
+
|
|
6
|
+
1. Clone repository:
|
|
7
|
+
|
|
8
|
+
`git clone git@github.com:traderinteractive/tide-design-system.git`
|
|
9
|
+
|
|
10
|
+
2. Install packages:
|
|
11
|
+
|
|
12
|
+
`cd tide-design-system`
|
|
13
|
+
|
|
14
|
+
`npm install`
|
|
15
|
+
|
|
16
|
+
3. Generate distribution files:
|
|
17
|
+
|
|
18
|
+
`npm build`
|
|
19
|
+
|
|
20
|
+
4. From TIDE directory, create local package alias:
|
|
21
|
+
|
|
22
|
+
`npm link`
|
|
23
|
+
|
|
24
|
+
5. From consumer directory. leverage local package alias:
|
|
25
|
+
|
|
26
|
+
`npm link tide-design-system`
|
|
27
|
+
|
|
28
|
+
## Scripts
|
|
29
|
+
- `npm run build`: Generate package.
|
|
30
|
+
- `npm run build-storybook`: Generate Storybook UI.
|
|
31
|
+
- `npm run coverage`: Display unit test statistics.
|
|
32
|
+
- `npm run lint`: Display ESLint issues.
|
|
33
|
+
- `npm run lint:fix`: Autofix ESLint issues where available.
|
|
34
|
+
- `npm run preview`: Serve Storybook UI in production mode.
|
|
35
|
+
- `npm run storybook`: Serve Storybook UI in development mode.
|
|
36
|
+
- `npm run test`: Run unit test suite.
|
|
37
|
+
- `npm run type-check`: Detect TypeScript errors.
|
|
38
|
+
|
|
39
|
+
## Publication (TIDE Task Force devs only)
|
|
40
|
+
1. Test via local integration (see above)
|
|
41
|
+
2. Increment version
|
|
42
|
+
|
|
43
|
+
\# Non-backward compatible release
|
|
44
|
+
|
|
45
|
+
#.# Backward compatible feature
|
|
46
|
+
|
|
47
|
+
#.#.# Backward compatible bugfix
|
|
48
|
+
|
|
49
|
+
3. Publish (RESTRICTED)
|
|
50
|
+
|
|
51
|
+
`npm publish`
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
# TIDE Prod Integration
|
|
2
|
+
1. Install dependency from Node Package Manager Registry:
|
|
3
|
+
|
|
4
|
+
`npm install tide-design-system`
|
|
5
|
+
|
|
6
|
+
2. Use CSS utilities:
|
|
7
|
+
1. Import global utilities:
|
|
8
|
+
|
|
9
|
+
`import 'tide-design-system/css';`
|
|
10
|
+
|
|
11
|
+
2. Import realm-specific utilities (where applicable):
|
|
12
|
+
|
|
13
|
+
`import 'tide-design-system/css/realm/aero';`
|
|
14
|
+
|
|
15
|
+
`import 'tide-design-system/css/realm/atv';`
|
|
16
|
+
|
|
17
|
+
`import 'tide-design-system/css/realm/boatmart';`
|
|
18
|
+
|
|
19
|
+
`import 'tide-design-system/css/realm/cycle';`
|
|
20
|
+
|
|
21
|
+
`import 'tide-design-system/css/realm/equip';`
|
|
22
|
+
|
|
23
|
+
`import 'tide-design-system/css/realm/pwc';`
|
|
24
|
+
|
|
25
|
+
`import 'tide-design-system/css/realm/snow';`
|
|
26
|
+
|
|
27
|
+
`import 'tide-design-system/css/realm/truck';`
|
|
28
|
+
|
|
29
|
+
3. Import TypeScript constant:
|
|
30
|
+
|
|
31
|
+
`import { CSS } from 'tide-design-system';`
|
|
32
|
+
|
|
33
|
+
4. Leverage:
|
|
34
|
+
|
|
35
|
+
`<div :class="[CSS.POSITION.ABSOLUTE]" />`
|
|
36
|
+
|
|
37
|
+
5. Via CSS directly (only when markup is outside a JS framework):
|
|
38
|
+
|
|
39
|
+
`<div class="tide-position-absolute" />`
|
|
40
|
+
|
|
41
|
+
6. Apply classes responsively:
|
|
42
|
+
|
|
43
|
+
`<div :class=[CSS.DISPLAY.NONE, withBreakpoint([CSS.DISPLAY.FLEX], BREAKPOINT.MD)] />`
|
|
44
|
+
|
|
45
|
+
3. Use TypeScript types:
|
|
46
|
+
1. Import:
|
|
47
|
+
|
|
48
|
+
`import type { Priority } from 'tide-design-system';`
|
|
49
|
+
|
|
50
|
+
2. Leverage:
|
|
51
|
+
|
|
52
|
+
```
|
|
53
|
+
type Sample = {
|
|
54
|
+
...
|
|
55
|
+
priority: Priority;
|
|
56
|
+
};
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
```
|
|
60
|
+
const setPriority = (priority: Priority) => {...};
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
4. Leverage TypeScript constants:
|
|
64
|
+
1. Import:
|
|
65
|
+
|
|
66
|
+
`import { PRIORITY } from 'tide-design-system';`
|
|
67
|
+
|
|
68
|
+
2. Leverage:
|
|
69
|
+
|
|
70
|
+
`<div :priority="PRIORITY.QUATERNARY">Sample</div>`
|
|
71
|
+
|
|
72
|
+
5. Use Vue 3 component(s):
|
|
73
|
+
1. Import:
|
|
74
|
+
|
|
75
|
+
`import { TideButton } from 'tide-design-system';`
|
|
76
|
+
|
|
77
|
+
2. Leverage:
|
|
78
|
+
|
|
79
|
+
`<TideButton label="Sample" />`
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
# TIDE Storybook
|
|
2
|
+
|
|
3
|
+
Storybook is a frontend workshop for building, testing, and documenting UI components and styles in isolation.
|
|
4
|
+
|
|
5
|
+
## Benefits
|
|
6
|
+
|
|
7
|
+
The TIDE Storybook was implemented to facilitate collaboration between 3 primary departments within the Trader Interactive development group:
|
|
8
|
+
- **Product Managers** can reference our components library when writing requirements for new pages and features.
|
|
9
|
+
- **Designers** can interact with our components in real browser conditions independent from any specific context in our websites.
|
|
10
|
+
- **Engineers** can leverage our components without having to become reacquinted with formatting standards, styling structures, or complex prop implementations.
|
|
11
|
+
|
|
12
|
+
## TODO
|
|
13
|
+
- based in stories
|
|
14
|
+
- args -> props, etc.
|
|
15
|
+
|
|
16
|
+
## Public
|
|
17
|
+
|
|
18
|
+
The TIDE Storybook UI is currently hosted from Netlify, a free, third-party platform connected to the Trader developer's personal GitHub fork. This is a temporary measure, to be replaced by a permanent solution that integrates the private server deployment process into the `tide-design-system` repository of the `traderinteractive` GitHub account for hosting to users within the Trader VPN.
|
|
19
|
+
|
|
20
|
+
https://tide-design-system.netlify.app
|
|
21
|
+
|
|
22
|
+
## Local Setup
|
|
23
|
+
|
|
24
|
+
1. Install dependencies:
|
|
25
|
+
|
|
26
|
+
`npm install`
|
|
27
|
+
|
|
28
|
+
2. Run demo:
|
|
29
|
+
|
|
30
|
+
`npm run storybook`
|
|
31
|
+
|
|
32
|
+
## Storybook UI
|
|
33
|
+
|
|
34
|
+
1. **Sidebar** serves as table of contents along the left edge of the screen
|
|
35
|
+
2. **Toolbar** offers project-level controls across the top of the screen
|
|
36
|
+
3. **Canvas** contains an interactive demo
|
|
37
|
+
4. **Code snippet** displays live-updated markup implementation available to copy
|
|
38
|
+
5. **Controls** determine the options passed into demo and code snippet
|
|
39
|
+
6. **Stories** demonstrate all major features of a given structure
|