@dcrackel/meyersquaredui 1.0.79 → 1.0.81

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/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@dcrackel/meyersquaredui",
3
3
  "private": false,
4
- "version": "1.0.79",
4
+ "version": "1.0.81",
5
5
  "type": "module",
6
6
  "main": "dist/meyersquaredui.cjs.js",
7
7
  "module": "dist/meyersquaredui.esm.js",
Binary file
package/src/index.js CHANGED
@@ -11,6 +11,7 @@ export { default as PageHeader } from './stories/Organisms/Headers/PageHeader/Pa
11
11
  export { default as HostColumn } from './stories/Organisms/Column/HostColumn.vue'
12
12
  export { default as ClubHeader } from './stories/Organisms/Headers/ClubHeader/ClubHeader.vue'
13
13
  export { default as TournamentHeader } from './stories/Organisms/Headers/TournamentHeader/TournamentHeader.vue'
14
+ export { default as ScrollNav } from './stories/Organisms/Headers/ScrollNav/ScrollNav.vue'
14
15
  export { default as TournamentDetailsBanner } from './stories/Organisms/HeroBanners/TournamentDetails/TournamentDetailsBanner.vue'
15
16
  export { default as TournamentBanner } from './stories/Organisms/HeroBanners/Tournaments/TournamentBanner.vue'
16
17
 
@@ -47,7 +47,7 @@ export default {
47
47
  color: {
48
48
  type: String,
49
49
  default: 'primary',
50
- validator: (value) => ['primary', 'secondary', 'accent'].includes(value),
50
+ validator: (value) => ['primary', 'secondary', 'accent', 'white'].includes(value),
51
51
  },
52
52
  hoverColor: {
53
53
  type: String,
@@ -104,6 +104,7 @@ export default {
104
104
  primary: 'bg-primary hover:bg-accent text-secondary hover:text-secondary',
105
105
  secondary: 'bg-secondary hover:bg-primary text-primary hover:text-secondary',
106
106
  accent: 'bg-accent hover:bg-accent hover:text-secondary',
107
+ white: 'bg-white hover:bg-primary text-primary hover:text-secondary',
107
108
  };
108
109
  return colorMap[this.backgroundColor] || 'bg-primary';
109
110
  },
@@ -3,12 +3,7 @@
3
3
  :type="type"
4
4
  :placeholder="placeholder"
5
5
  :value="modelValue"
6
- :class="[
7
- color === 'primary'
8
- ? 'bg-primary text-secondary border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-secondary px-2 hover:border-accent duration-300 ease-in-out placeholder:text-xl'
9
- : 'text-primary bg-white border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-primary px-2 hover:border-accent duration-300 ease-in-out placeholder:text-xl'
10
- ,
11
- ]"
6
+ :class="[inputClass]"
12
7
  @input="$emit('update:modelValue', $event.target.value)"
13
8
  />
14
9
  </template>
@@ -33,14 +28,24 @@ export default {
33
28
  type: String,
34
29
  default: 'primary',
35
30
  validator: (value) => ['primary', 'secondary'].includes(value),
31
+ },
32
+ textSize: {
33
+ type: String,
34
+ default: 'text-md',
35
+ validator: (value) => ['text-sm', 'text-md', 'text-lg', 'text-xl', 'text-2xl'].includes(value),
36
36
  }
37
37
  },
38
38
  computed: {
39
- bgClass() {
40
- return this.mode === 'primary' ? 'bg-primary text-secondary border-b-2 border-secondary focus:outline-none focus:border-accent w-full placeholder-secondary px-2 hover:border-accent duration-300 ease-in-out' : 'bg-secondary';
41
- },
42
- textClass() {
43
- return this.mode === 'primary' ? 'text-primary' : 'text-primary';
39
+ inputClass() {
40
+ const baseClasses = 'w-full border-b-2 focus:outline-none focus:border-accent px-2 hover:border-accent duration-300 ease-in-out';
41
+
42
+ const colorClass = this.color === 'primary'
43
+ ? 'bg-primary text-secondary border-secondary placeholder-secondary'
44
+ : 'bg-white text-primary border-secondary placeholder-primary';
45
+
46
+ const textSizeClass = this.textSize;
47
+
48
+ return `${baseClasses} ${colorClass} ${textSizeClass}`;
44
49
  }
45
50
  }
46
51
  };
@@ -1,7 +1,7 @@
1
1
  <template>
2
2
  <div class="relative flex items-center w-full max-w-md">
3
- <InputField v-model="searchQuery" placeholder="Search" color="primary"/>
4
- <Icon icon="fa-search" color="secondary" size="md" class="absolute right-2" @click="onSearch" />
3
+ <InputField v-model="searchQuery" :text-size="textSize" placeholder="Search" :color="inputColor"/>
4
+ <Icon icon="fa-search" :color="iconColor" :size="iconSize" class="absolute right-2" @click="onSearch" />
5
5
  </div>
6
6
  </template>
7
7
 
@@ -15,6 +15,24 @@ export default {
15
15
  InputField,
16
16
  Icon,
17
17
  },
18
+ props: {
19
+ textSize: {
20
+ type: String,
21
+ default: 'text-md',
22
+ },
23
+ iconSize: {
24
+ type: String,
25
+ default: 'md',
26
+ },
27
+ inputColor: {
28
+ type: String,
29
+ default: 'primary',
30
+ },
31
+ iconColor: {
32
+ type: String,
33
+ default: 'secondary',
34
+ },
35
+ },
18
36
  data() {
19
37
  return {
20
38
  searchQuery: '',
@@ -54,9 +54,21 @@ export default {
54
54
  ],
55
55
  },
56
56
  },
57
+ mounted() {
58
+ this.preloadImage(this.imageSrc);
59
+ },
57
60
  data() {
58
61
  return {
59
62
  };
60
63
  },
64
+ methods: {
65
+ preloadImage(imageUrl) {
66
+ const link = document.createElement('link');
67
+ link.rel = 'preload';
68
+ link.as = 'image';
69
+ link.href = imageUrl;
70
+ document.head.appendChild(link);
71
+ }
72
+ }
61
73
  };
62
74
  </script>
@@ -76,7 +76,7 @@ export default {
76
76
  return '00:00 AM'; // Replace with actual time if available in the data object
77
77
  },
78
78
  tournamentImage() {
79
- return this.data.ImagesURLs || 'https://via.placeholder.com/150';
79
+ return this.data.ImagesURLs || 'https://meyersquared.com/uploads/defaulttournament.png';
80
80
  },
81
81
  imageAltText() {
82
82
  return this.data.ImagesAltTexts || 'Tournament Image';
@@ -86,9 +86,12 @@ export default {
86
86
  emits: ['grid-click', 'grid-card-click'],
87
87
  computed: {
88
88
  topClasses() {
89
- let retClass = "max-w-[1200px] overflow-x-auto mt-8";
90
- if (this.whiteStyle) retClass = `w-full md:mr-10 md:mt-10`;
91
- return retClass;
89
+ if (this.mobileHorizontal) {
90
+ return "w-screen overflow-x-auto";
91
+ }
92
+
93
+ // For larger screens, limit the width to 1200px
94
+ return "max-w-[1200px] w-full flex justify-center mx-auto mt-8";
92
95
  },
93
96
  headerClasses() {
94
97
  let retClasses = "w-full flex py-4 md:pb-10 ml-2 md:ml-0 mb-4";
@@ -97,15 +100,17 @@ export default {
97
100
  },
98
101
  gridClasses() {
99
102
  let baseClasses = "md:grid md:gap-x-6 md:gap-y-4";
103
+
104
+ // Enable horizontal scrolling for mobile layout
100
105
  if (this.mobileHorizontal) {
101
- baseClasses = `flex space-x-4 md:grid md:gap-x-6 md:gap-y-4`;
106
+ baseClasses = `flex space-x-4 overflow-x-auto md:grid md:gap-x-6 md:gap-y-4`;
102
107
  }
108
+
103
109
  if (this.whiteStyle) {
104
110
  baseClasses = `bg-white p-2 mx-2 md:mx-0 rounded-lg`;
105
111
  }
106
112
 
107
113
  let columnClasses;
108
-
109
114
  switch (this.maxColumns) {
110
115
  case 1:
111
116
  columnClasses = "grid-cols-1";
@@ -7,7 +7,7 @@
7
7
 
8
8
  <section class="flex w-full items-center border-r border-l border-lineGrey">
9
9
  <div class="hidden lg:flex w-1/3 pl-20 mb-3 mt-1">
10
- <SearchBox class="w-24 md:w-32 lg:w-52 xl:w-64" @search="onSearch" />
10
+ <SearchBox class="w-24 md:w-32 lg:w-52 xl:w-64" text-size="text-xl" @search="onSearch" />
11
11
  </div>
12
12
  <nav class="ml-8 w-2/3 flex justify-around">
13
13
  <BaseText color="secondary" size="xl" tag="p" weight="normal" class="border-b-2 border-primary hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('TournamentList')">Tournaments</BaseText>
@@ -0,0 +1,32 @@
1
+ import ScrollNav from './ScrollNav.vue';
2
+ export default {
3
+ title: 'Organisms/Headers/ScrollNav',
4
+ component: ScrollNav,
5
+ argTypes: {},
6
+ };
7
+
8
+ const Template = (args, { argTypes }) => ({
9
+ components: { ScrollNav },
10
+ setup() {
11
+ return { args };
12
+ },
13
+ template: `
14
+ <div>
15
+ <!-- Simulating a hero banner -->
16
+ <div id="hero" class="h-screen bg-gray-400 flex justify-center items-center">
17
+ <h1 class="text-4xl text-white">Hero Banner</h1>
18
+ </div>
19
+
20
+ <!-- ScrollNav Component -->
21
+ <ScrollNav v-bind="args" />
22
+
23
+ <!-- Simulate some content to scroll through -->
24
+ <div class="h-screen bg-gray-100 flex justify-center items-center">
25
+ <p class="text-2xl">Scroll down to see the Nav Bar appear!</p>
26
+ </div>
27
+ </div>
28
+ `,
29
+ });
30
+
31
+ export const Default = Template.bind({});
32
+ Default.args = {};
@@ -0,0 +1,68 @@
1
+ <template>
2
+ <nav
3
+ v-show="showNav"
4
+ class="fixed top-0 left-0 w-full bg-white shadow-md transition-opacity duration-1000 z-50"
5
+ :class="{ 'opacity-0': !showNav, 'opacity-100': showNav }"
6
+ >
7
+ <div class="max-w-7xl mx-auto px-4 py-2">
8
+ <section class="w-full hidden md:flex">
9
+ <div class="w-[150px] h-[50px] flex-shrink-0 flex items-center justify-center" @click="handlePageChange('Home')">
10
+ <img :src="logo" alt="Logo" class="h-10 bg-accent" />
11
+ </div>
12
+
13
+ <section class="flex w-full items-center">
14
+ <div class="hidden lg:flex w-1/3 pl-20 mb-3 mt-1">
15
+ <SearchBox inputColor="secondary" iconColor="primary" class="w-24 md:w-32 lg:w-52 xl:w-64" @search="onSearch" />
16
+ </div>
17
+ <nav class="ml-8 w-2/3 flex justify-around">
18
+ <BaseText color="primary" size="sm" tag="p" weight="normal" class="border-b-2 border-white hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('TournamentList')">Tournaments</BaseText>
19
+ <BaseText color="primary" size="sm" tag="p" weight="normal" class="border-b-2 border-white hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('ClubList')">Clubs</BaseText>
20
+ <BaseText color="primary" size="sm" tag="p" weight="normal" class="border-b-2 border-white hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('Leaderboard')">Leaderboard</BaseText>
21
+ <BaseText color="primary" size="sm" tag="p" weight="normal" class="border-b-2 border-white hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('ContactUs')">Contact</BaseText>
22
+ <BaseText color="primary" size="sm" tag="p" weight="normal" class="border-b-2 border-white hover:border-accent pb-2 duration-300 ease-in-out" @click="handlePageChange('ContactUs')">Login</BaseText>
23
+ </nav>
24
+ </section>
25
+ </section>
26
+ </div>
27
+ </nav>
28
+ </template>
29
+
30
+ <script>
31
+ import logo from '../../../../assets/images/m2-white.png';
32
+ import BaseText from "../../../Atoms/BaseText/BaseText.vue";
33
+ import BaseButton from "../../../Atoms/BaseButton/BaseButton.vue";
34
+ import SearchBox from "../../../Molecules/SearchBox/SearchBox.vue";
35
+
36
+ export default {
37
+ name: 'ScrollNav',
38
+ components: {
39
+ SearchBox, BaseButton, BaseText
40
+ },
41
+ props: {
42
+ buffer: {
43
+ type: Number,
44
+ default: 0,
45
+ },
46
+ },
47
+ data() {
48
+ return {
49
+ logo: logo,
50
+ showNav: false,
51
+ heroHeight: 0,
52
+ };
53
+ },
54
+ mounted() {
55
+ this.heroHeight = document.querySelector('#hero')?.offsetHeight || 600;
56
+ window.addEventListener('scroll', this.handleScroll);
57
+ },
58
+ beforeDestroy() {
59
+ window.removeEventListener('scroll', this.handleScroll);
60
+ },
61
+ methods: {
62
+ handleScroll() {
63
+ const scrollPos = window.scrollY;
64
+ this.showNav = scrollPos > (this.heroHeight + this.buffer);
65
+ },
66
+ },
67
+ };
68
+ </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <section class="relative w-full h-3/4 flex justify-center bg-primary md:m-0 mt-6 " :style="backgroundStyle">
2
+ <section id="hero" class="relative w-full h-3/4 flex justify-center bg-primary md:m-0 mt-6 " :style="backgroundStyle">
3
3
  <!-- Spacer (Left) -->
4
4
  <div class="hidden md:block w-[150px] bg-primary border-b border-lineGrey flex-shrink-0"></div>
5
5
 
@@ -97,6 +97,7 @@ export default {
97
97
  mounted() {
98
98
  this.checkScreenSize();
99
99
  window.addEventListener('resize', this.checkScreenSize);
100
+ this.preloadImage(this.imageSrc);
100
101
  },
101
102
  beforeDestroy() {
102
103
  window.removeEventListener('resize', this.checkScreenSize);
@@ -108,6 +109,13 @@ export default {
108
109
  onClick() {
109
110
  this.$emit('button-click');
110
111
  },
112
+ preloadImage(imageUrl) {
113
+ const link = document.createElement('link');
114
+ link.rel = 'preload';
115
+ link.as = 'image';
116
+ link.href = imageUrl;
117
+ document.head.appendChild(link);
118
+ }
111
119
  },
112
120
  };
113
121
  </script>
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <section class="hidden md:flex relative w-full justify-center bg-primary m-0 bg-top" :style="backgroundStyle">
2
+ <section id="hero" class="hidden md:flex relative w-full justify-center bg-primary m-0 bg-top" :style="backgroundStyle">
3
3
  <!-- Left Spacer -->
4
4
  <div class="hidden md:block w-[150px] bg-primary border-b border-lineGrey flex-shrink-0"></div>
5
5
 
@@ -125,11 +125,19 @@ export default {
125
125
  mounted() {
126
126
  this.checkScreenSize();
127
127
  window.addEventListener('resize', this.checkScreenSize);
128
+ this.preloadImage(this.imageSrc);
128
129
  },
129
130
  beforeDestroy() {
130
131
  window.removeEventListener('resize', this.checkScreenSize);
131
132
  },
132
133
  methods: {
134
+ preloadImage(imageUrl) {
135
+ const link = document.createElement('link');
136
+ link.rel = 'preload';
137
+ link.as = 'image';
138
+ link.href = imageUrl;
139
+ document.head.appendChild(link);
140
+ },
133
141
  checkScreenSize() {
134
142
  this.isMobile = window.innerWidth < 768;
135
143
  },
@@ -1,5 +1,5 @@
1
1
  <template>
2
- <section class="relative w-full flex justify-center bg-primary m-0 bg-top" :style="backgroundStyle">
2
+ <section id="hero" class="relative w-full flex justify-center bg-primary m-0 bg-top" :style="backgroundStyle">
3
3
  <div class="hidden md:block w-[150px] bg-primary border-b border-lineGrey flex-shrink-0"></div>
4
4
 
5
5
  <div class="relative w-full md:border-b md:border-l md:border-r border-lineGrey">
@@ -71,6 +71,7 @@ export default {
71
71
  mounted() {
72
72
  this.checkScreenSize();
73
73
  window.addEventListener('resize', this.checkScreenSize);
74
+ this.preloadImage(this.imageSrc);
74
75
  },
75
76
  beforeDestroy() {
76
77
  window.removeEventListener('resize', this.checkScreenSize);
@@ -79,6 +80,13 @@ export default {
79
80
  checkScreenSize() {
80
81
  this.isMobile = window.innerWidth < 768;
81
82
  },
83
+ preloadImage(imageUrl) {
84
+ const link = document.createElement('link');
85
+ link.rel = 'preload';
86
+ link.as = 'image';
87
+ link.href = imageUrl;
88
+ document.head.appendChild(link);
89
+ }
82
90
  },
83
91
  };
84
92
  </script>
@@ -1,7 +1,8 @@
1
1
  <template>
2
2
  <div class="m-0 w-full bg-secondary">
3
3
  <PageHeader @changePage="changePage"/>
4
- <HeroBanner :title="title" :buttonLabel="buttonLabel" :description="description" :imageSrc="imageSrc"/>
4
+ <HeroBanner :title="title" :buttonLabel="buttonLabel" :description="description" :imageSrc="imageSrc"/>
5
+ <ScrollNav buffer=100 />
5
6
  <GridLayout
6
7
  :cardComponent="TournamentCard"
7
8
  :items="limitedTournaments"
@@ -22,7 +23,7 @@
22
23
  :cardComponent="FencerCard"
23
24
  :items="topFencers"
24
25
  :maxColumns="5"
25
- :mobileHorizontal="true"
26
+ :mobileHorizontal="mobileHorizontal"
26
27
  :isLoading="topFencersIsLoading"
27
28
  moreButtonLabel="Leaderboards"
28
29
  title="Top Fencers"
@@ -34,19 +35,21 @@
34
35
  @handle-button-click-one="changePage('submitresults')"
35
36
  @handle-button-click-two="changePage('runtournament')"
36
37
  />
38
+
37
39
  <GridLayout
38
40
  :cardComponent="ArticleCard"
39
41
  :items="articles"
40
42
  :maxColumns="3"
41
- :mobileHorizontal="true"
43
+ :mobileHorizontal="mobileHorizontal"
42
44
  :isLoading="articlesIsLoading"
43
45
  moreButtonLabel="See More"
44
46
  title="Interesting Articles"
45
47
  @grid-click="changePage('articles')"
46
48
  @grid-card-click="handleGridCardClick"
47
49
  />
50
+ </div>
48
51
  <Footer @changePage="changePage"/>
49
- </div>
52
+
50
53
  </template>
51
54
 
52
55
  <script>
@@ -59,6 +62,7 @@ import GridLayout from "../../Organisms/GridLayout/GridLayout.vue";
59
62
  import SingleButtonBanner from "../../Organisms/SectionBanners/SingleButtonBanner/SingleButtonBanner.vue";
60
63
  import DoubleButtonBanner from "../../Organisms/SectionBanners/DoubleButtonBanner/DoubleButtonBanner.vue";
61
64
  import Footer from "../../Organisms/Footer/Footer.vue";
65
+ import ScrollNav from "../../Organisms/Headers/ScrollNav/ScrollNav.vue";
62
66
  import {markRaw} from 'vue';
63
67
 
64
68
  export default {
@@ -72,6 +76,7 @@ export default {
72
76
  FencerCard,
73
77
  PageHeader,
74
78
  HeroBanner,
79
+ ScrollNav
75
80
  },
76
81
  props: {
77
82
  title: {
@@ -126,12 +131,27 @@ export default {
126
131
  return this.tournaments.slice(0, 6);
127
132
  }
128
133
  },
134
+ mounted() {
135
+ // Check initial screen size
136
+ this.checkScreenSize();
137
+
138
+ // Add listener for window resize
139
+ window.addEventListener('resize', this.checkScreenSize);
140
+ },
141
+ beforeUnmount() {
142
+ // Clean up the event listener when the component is destroyed
143
+ window.removeEventListener('resize', this.checkScreenSize);
144
+ },
129
145
  data() {
130
146
  return {
131
147
  TournamentCard: markRaw(TournamentCard),
148
+ mobileHorizontal: true,
132
149
  };
133
150
  },
134
151
  methods: {
152
+ checkScreenSize() {
153
+ this.mobileHorizontal = window.matchMedia('(max-width: 768px)').matches;
154
+ },
135
155
  handleGridCardClick() {
136
156
  console.log('Grid Card Clicked');
137
157
  },
@@ -5,19 +5,22 @@
5
5
  <TournamentHeader :weapons="['All Weapons', 'Longsword', 'Saber', 'Rapier', 'Smallsword', 'Sword and Buckler']" />
6
6
 
7
7
  <div class="w-full flex justify-center">
8
- <section class="w-full md:w-2/3 mb-20 flex">
9
- <GridLayout
10
- :cardComponent="cardComponent"
11
- :items="limitedTournaments"
12
- :maxColumns="1"
13
- :isLoading="tournamentsIsLoading"
14
- :whiteStyle="true"
15
- moreButtonLabel="See All Tournaments"
16
- :title="formattedDate"
17
- @grid-card-click="changePage"
18
- />
19
- <Calendar :tournaments="tournaments" class="hidden md:block mt-32" />
20
- </section>
8
+ <section class="mb-20 flex w-full md:w-7/12">
9
+ <GridLayout
10
+ :cardComponent="cardComponent"
11
+ :items="limitedTournaments"
12
+ :maxColumns="1"
13
+ :isLoading="tournamentsIsLoading"
14
+ :whiteStyle="true"
15
+ moreButtonLabel="See All Tournaments"
16
+ :title="formattedDate"
17
+ @grid-card-click="handleCardClick"
18
+ topBoxClass="w-full md:w-3/4 md:mr-10 md:-mt-3"
19
+ />
20
+ <div class="flex md:w-60 justify-start">
21
+ <Calendar :tournaments="tournaments" class="hidden md:block mt-32 items-start" />
22
+ </div>
23
+ </section>
21
24
  </div>
22
25
 
23
26
  <Footer />