@nuxtify/pages 0.2.1 β†’ 0.3.1

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.
Files changed (51) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +36 -14
  3. package/dist/module.d.mts +0 -83
  4. package/dist/module.json +2 -2
  5. package/dist/module.mjs +9 -66
  6. package/dist/runtime/components/EmailSubscribeForm.vue +7 -7
  7. package/dist/runtime/components/app/AppBar.vue +1 -1
  8. package/dist/runtime/components/app/AppFooter.vue +1 -1
  9. package/dist/runtime/components/app/AppNavigationDrawer.vue +1 -1
  10. package/dist/runtime/layouts/DefaultLayout.vue +3 -1
  11. package/dist/runtime/pages/DynamicSlug.vue +1 -1
  12. package/dist/runtime/pages/IndexPage.vue +14 -10
  13. package/dist/runtime/utils/icons.d.ts +1 -1
  14. package/dist/runtime/utils/icons.js +1 -1
  15. package/package.json +11 -12
  16. package/dist/runtime/components/app/AppAnnouncementBar.vue +0 -36
  17. package/dist/runtime/components/app/AppAnnouncementBar.vue.d.ts +0 -2
  18. package/dist/runtime/components/app/AppDialog.vue +0 -38
  19. package/dist/runtime/components/app/AppDialog.vue.d.ts +0 -2
  20. package/dist/runtime/components/app/AppLoading.vue +0 -16
  21. package/dist/runtime/components/app/AppLoading.vue.d.ts +0 -2
  22. package/dist/runtime/components/app/AppLogo.vue +0 -41
  23. package/dist/runtime/components/app/AppLogo.vue.d.ts +0 -23
  24. package/dist/runtime/components/app/AppToast.vue +0 -16
  25. package/dist/runtime/components/app/AppToast.vue.d.ts +0 -2
  26. package/dist/runtime/composables/dialog.d.ts +0 -13
  27. package/dist/runtime/composables/dialog.js +0 -15
  28. package/dist/runtime/composables/nuxtify.d.ts +0 -2
  29. package/dist/runtime/composables/nuxtify.js +0 -2
  30. package/dist/runtime/composables/state.d.ts +0 -15
  31. package/dist/runtime/composables/state.js +0 -10
  32. package/dist/runtime/server/composables/client.d.ts +0 -1
  33. package/dist/runtime/server/composables/client.js +0 -1
  34. package/dist/runtime/server/utils/client.d.ts +0 -1
  35. package/dist/runtime/server/utils/client.js +0 -1
  36. package/dist/runtime/utils/formRules.d.ts +0 -19
  37. package/dist/runtime/utils/formRules.js +0 -23
  38. package/dist/runtime/utils/io.d.ts +0 -2
  39. package/dist/runtime/utils/io.js +0 -19
  40. package/dist/runtime/utils/math.d.ts +0 -2
  41. package/dist/runtime/utils/math.js +0 -13
  42. package/dist/runtime/utils/text.d.ts +0 -23
  43. package/dist/runtime/utils/text.js +0 -159
  44. package/dist/runtime/utils/time.d.ts +0 -2
  45. package/dist/runtime/utils/time.js +0 -7
  46. package/dist/runtime/utils/url.d.ts +0 -9
  47. package/dist/runtime/utils/url.js +0 -27
  48. package/dist/runtime/utils/util.d.ts +0 -7
  49. package/dist/runtime/utils/util.js +0 -5
  50. package/dist/runtime/utils/youtube.d.ts +0 -1
  51. package/dist/runtime/utils/youtube.js +0 -13
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2023-present - Nuxtify
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md CHANGED
@@ -4,19 +4,23 @@
4
4
 
5
5
  # Nuxtify Pages
6
6
 
7
- <!-- [![npm version][npm-version-src]][npm-version-href]
7
+ <!--
8
8
  [![npm downloads][npm-downloads-src]][npm-downloads-href]
9
- [![License][license-src]][license-href]
10
9
  [![Nuxtify Docs][nuxtify-src]][nuxtify-href] -->
11
- <!-- [πŸ€ Online playground](https://stackblitz.com/github/nuxtify-dev/pages?file=playground%2Fapp.vue) -->
10
+
11
+ [![npm version][npm-version-src]][npm-version-href]
12
+ [![License][license-src]][license-href]
13
+ [![πŸ€ Playground][playground-src]][playground-href]
12
14
 
13
15
  > [!NOTE]
16
+ >
14
17
  > **Early Access Preview:**
15
18
  > This module is under active development. While it is already used to power a [handful of sites](https://nuxtify.dev/showcase) in production, expect things to change frequently. I will do my best to call out breaking changes in the [changelog](https://github.com/nuxtify-dev/pages/blob/main/CHANGELOG.md).
16
19
 
17
20
  ### Table of Contents
18
21
 
19
22
  - ♾️ [Why Nuxtify?](#why-nuxtify)
23
+ - 🧩 [Nuxtify Modules](#modules)
20
24
  - ✨ [Features](#features)
21
25
  - πŸš€ [Quick Start](#quick-start)
22
26
  - πŸ”§ [Configuration](#configuration)
@@ -47,9 +51,25 @@ This means you can:
47
51
 
48
52
  In short, Nuxtify helps you build faster, iterate smarter, and maintain consistency – without sacrificing control or creativity.
49
53
 
54
+ ## <a name="modules">🧩 Modules</a>
55
+
56
+ ### [Nuxtify Core](https://github.com/nuxtify-dev/core)
57
+
58
+ Provides the core functionality for Nuxtify, including:
59
+
60
+ - Default components, composables, and utilities
61
+ - Global configuration and theming with [Vuetify](https://vuetifyjs.com/en/introduction/why-vuetify/)
62
+
63
+ ### [Nuxtify Pages](https://github.com/nuxtify-dev/pages) (this module)
64
+
65
+ Provides single and multi-page website building blocks so you can _ship weirdly fast_.
66
+
67
+ - Ready to use page components, page templates, and email subscribe form
68
+ - (coming soon) Robots, sitemaps, schema.org, social share images, broken links, and more powered by [Nuxt SEO](https://nuxtseo.com/)
69
+
50
70
  ## <a name="features">✨ Features</a>
51
71
 
52
- Nuxtify builds on the amazing features of [Vue](https://vuejs.org/guide/introduction), [Nuxt](https://nuxt.com/docs/getting-started/introduction), and [Vuetify](https://vuetifyjs.com/en/introduction/why-vuetify/).
72
+ Nuxtify Pages builds on the functionality in [Nuxtify Core](https://github.com/nuxtify-dev/core).
53
73
 
54
74
  ### πŸ’‘ Intuitive UI & UX
55
75
 
@@ -102,12 +122,10 @@ Add the `@nuxtify/pages` module to `nuxt.config.ts` and configure it:
102
122
  // nuxt.config.ts
103
123
 
104
124
  export default defineNuxtConfig({
105
- modules: [
106
- '@nuxtify/pages'
107
- ],
125
+ modules: ["@nuxtify/pages"],
108
126
  nuxtifyPages: {
109
127
  /* module specific options */
110
- }
128
+ },
111
129
  });
112
130
  ```
113
131
 
@@ -138,11 +156,13 @@ If you need to override a [composable](https://nuxt.com/docs/guide/directory-str
138
156
  It's easy to stay up to date with the latest version of Nuxtify. Just update to the latest package using your favorite package manager.
139
157
 
140
158
  **Minor and patch versions**
159
+
141
160
  ```bash
142
161
  npm update @nuxtify/pages --save
143
162
  ```
144
163
 
145
164
  **Major versions**
165
+
146
166
  ```bash
147
167
  npm install @nuxtify/pages@latest --save
148
168
  ```
@@ -164,23 +184,23 @@ Here are a few ways you can get involved:
164
184
  ```bash
165
185
  # Install dependencies
166
186
  npm install
167
-
187
+
168
188
  # Generate type stubs
169
189
  npm run dev:prepare
170
-
190
+
171
191
  # Develop with the playground
172
192
  npm run dev
173
-
193
+
174
194
  # Build the playground
175
195
  npm run dev:build
176
-
196
+
177
197
  # Run ESLint
178
198
  npm run lint
179
-
199
+
180
200
  # Run Vitest
181
201
  npm run test
182
202
  npm run test:watch
183
- ```
203
+ ```
184
204
 
185
205
  Learn about [authoring Nuxt modules](https://nuxt.com/docs/guide/going-further/modules).
186
206
 
@@ -198,3 +218,5 @@ Learn about [authoring Nuxt modules](https://nuxt.com/docs/guide/going-further/m
198
218
  [license-href]: https://npmjs.com/package/@nuxtify/pages
199
219
  [nuxtify-src]: https://img.shields.io/badge/Nuxtify_Docs-00DC82
200
220
  [nuxtify-href]: https://nuxtify.dev/docs
221
+ [playground-src]: https://img.shields.io/badge/%F0%9F%8F%80_Playground-Demo-00DC82?labelColor=020420
222
+ [playground-href]: https://stackblitz.com/github/nuxtify-dev/pages?file=playground%2Fpages%2Findex.vue
package/dist/module.d.mts CHANGED
@@ -11,79 +11,7 @@ interface FooterLinks {
11
11
  title: string;
12
12
  links: Link[];
13
13
  }
14
- interface BrandOptions {
15
- /**
16
- * The name of the brand.
17
- *
18
- * @default "nuxtify-pages"
19
- */
20
- name?: string;
21
- /**
22
- * The domain of the brand.
23
- *
24
- * @default ""
25
- */
26
- domain?: string;
27
- /**
28
- * The tagline of the brand.
29
- *
30
- * @default ""
31
- */
32
- tagline?: string;
33
- /**
34
- * The logo of the brand.
35
- */
36
- logo?: {
37
- /**
38
- * The URL of the light logo. Recommended 5:1 aspect ratio (e.g. 400 x 80 px).
39
- *
40
- * @default ""
41
- */
42
- lightUrl?: string;
43
- /**
44
- * The URL of the dark logo. Recommended 5:1 aspect ratio (e.g. 400 x 80 px).
45
- *
46
- * @default ""
47
- */
48
- darkUrl?: string;
49
- /**
50
- * The width of the logo.
51
- *
52
- * @default 200
53
- */
54
- width?: number;
55
- /**
56
- * The width of the logo on mobile.
57
- *
58
- * @default 150
59
- */
60
- mobileWidth?: number;
61
- };
62
- }
63
- interface PagesOptions {
64
- policies: {
65
- privacyUrl: string;
66
- termsUrl: string;
67
- };
68
- }
69
14
  interface ModuleOptions {
70
- /**
71
- * Brand options
72
- */
73
- brand?: BrandOptions;
74
- /**
75
- * Pages options
76
- */
77
- pages?: PagesOptions;
78
- /**
79
- * Announcement banner options
80
- */
81
- announcement?: {
82
- show?: boolean;
83
- message?: string;
84
- buttonText?: string;
85
- buttonUrl?: string;
86
- };
87
15
  /**
88
16
  * Navigation options
89
17
  */
@@ -98,15 +26,6 @@ interface ModuleOptions {
98
26
  */
99
27
  footer?: {
100
28
  copyright?: string;
101
- credits?: {
102
- creator?: {
103
- name?: string;
104
- domain?: string;
105
- };
106
- prependText?: string;
107
- appendText?: string;
108
- showPoweredBy?: boolean;
109
- };
110
29
  cta?: {
111
30
  show?: boolean;
112
31
  title?: string;
@@ -118,8 +37,6 @@ interface ModuleOptions {
118
37
  * Email options
119
38
  */
120
39
  email?: {
121
- general?: string;
122
- support?: string;
123
40
  provider?: {
124
41
  defaultSubmitUrl?: string;
125
42
  };
package/dist/module.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
- "name": "nuxtify-pages",
2
+ "name": "@nuxtify/pages",
3
+ "version": "0.3.1",
3
4
  "configKey": "nuxtifyPages",
4
5
  "compatibility": {
5
6
  "nuxt": ">=3.16.0",
6
7
  "bridge": false
7
8
  },
8
- "version": "0.2.1",
9
9
  "builder": {
10
10
  "@nuxt/module-builder": "1.0.1",
11
11
  "unbuild": "3.5.0"
package/dist/module.mjs CHANGED
@@ -1,9 +1,13 @@
1
- import { defineNuxtModule, createResolver, installModule, addLayout, addComponentsDir, addImportsDir, addServerImportsDir, extendPages } from '@nuxt/kit';
1
+ import { defineNuxtModule, createResolver, installModule, addLayout, addComponentsDir, addImportsDir, extendPages } from '@nuxt/kit';
2
2
  import { defu } from 'defu';
3
3
 
4
+ const name = "@nuxtify/pages";
5
+ const version = "0.3.1";
6
+
4
7
  const module = defineNuxtModule({
5
8
  meta: {
6
- name: "nuxtify-pages",
9
+ name,
10
+ version,
7
11
  configKey: "nuxtifyPages",
8
12
  compatibility: {
9
13
  nuxt: ">=3.16.0",
@@ -11,32 +15,6 @@ const module = defineNuxtModule({
11
15
  }
12
16
  },
13
17
  defaults: {
14
- // Brand
15
- brand: {
16
- name: "nuxtify-pages",
17
- domain: "",
18
- tagline: "",
19
- logo: {
20
- lightUrl: "",
21
- darkUrl: "",
22
- width: 200,
23
- mobileWidth: 150
24
- }
25
- },
26
- // Pages
27
- pages: {
28
- policies: {
29
- privacyUrl: "/privacy",
30
- termsUrl: "/terms"
31
- }
32
- },
33
- // Announcement
34
- announcement: {
35
- show: false,
36
- message: "",
37
- buttonText: "",
38
- buttonUrl: ""
39
- },
40
18
  // Navigation
41
19
  navigation: {
42
20
  primary: [],
@@ -47,15 +25,6 @@ const module = defineNuxtModule({
47
25
  // Footer
48
26
  footer: {
49
27
  copyright: "",
50
- credits: {
51
- creator: {
52
- name: "",
53
- domain: ""
54
- },
55
- prependText: "",
56
- appendText: "",
57
- showPoweredBy: true
58
- },
59
28
  cta: {
60
29
  show: false,
61
30
  title: "",
@@ -65,8 +34,6 @@ const module = defineNuxtModule({
65
34
  },
66
35
  // Email
67
36
  email: {
68
- general: "",
69
- support: "",
70
37
  provider: {
71
38
  defaultSubmitUrl: ""
72
39
  }
@@ -80,31 +47,9 @@ const module = defineNuxtModule({
80
47
  },
81
48
  async setup(_options, _nuxt) {
82
49
  const resolver = createResolver(import.meta.url);
83
- await installModule("vuetify-nuxt-module", {
84
- vuetifyOptions: {
85
- icons: {
86
- defaultSet: "mdi-svg"
87
- },
88
- theme: {
89
- themes: {
90
- light: {
91
- colors: {
92
- primary: "#020420",
93
- secondary: "#00DC82",
94
- background: "#fff"
95
- }
96
- }
97
- }
98
- },
99
- defaults: {
100
- VBtn: { color: "secondary", variant: "flat", class: "text-none" },
101
- VAlert: {
102
- VBtn: { color: "inherit" }
103
- },
104
- VFooter: {
105
- VBtn: { color: "inherit" }
106
- }
107
- }
50
+ await installModule("@nuxtify/core", {
51
+ brand: {
52
+ name: "@nuxtify/pages"
108
53
  }
109
54
  });
110
55
  _nuxt.options.appConfig.nuxtify = defu(_nuxt.options.appConfig.nuxtify, {
@@ -117,9 +62,7 @@ const module = defineNuxtModule({
117
62
  path: resolver.resolve("./runtime/components")
118
63
  });
119
64
  addImportsDir(resolver.resolve("./runtime/composables"));
120
- addServerImportsDir(resolver.resolve("./runtime/server/composables"));
121
65
  addImportsDir(resolver.resolve("./runtime/utils"));
122
- addServerImportsDir(resolver.resolve("./runtime/server/utils"));
123
66
  extendPages((pages) => {
124
67
  pages.unshift({
125
68
  name: "index",
@@ -1,15 +1,15 @@
1
1
  <script setup>
2
2
  import {
3
- useId,
3
+ formRules,
4
+ getBaseUrl,
5
+ getUtmParams,
6
+ isExternalUrl,
4
7
  navigateTo,
5
- useDisplay,
6
8
  ref,
7
- useNuxtifyConfig,
8
- getUtmParams,
9
- getBaseUrl,
10
9
  submitFormData,
11
- formRules,
12
- isExternalUrl
10
+ useDisplay,
11
+ useId,
12
+ useNuxtifyConfig
13
13
  } from "#imports";
14
14
  const props = defineProps({
15
15
  submitUrl: {
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { useDisplay, useDrawer, useNuxtifyConfig, mdiArrowTopRight, mdiClose, mdiMenu } from "#imports";
2
+ import { mdiArrowTopRight, mdiClose, mdiMenu, useDisplay, useDrawer, useNuxtifyConfig } from "#imports";
3
3
  const { smAndDown } = useDisplay();
4
4
  const nuxtifyConfig = useNuxtifyConfig();
5
5
  const drawer = useDrawer();
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { useNuxtifyConfig, mdiArrowTopRight } from "#imports";
2
+ import { mdiArrowTopRight, useNuxtifyConfig } from "#imports";
3
3
  const nuxtifyConfig = useNuxtifyConfig();
4
4
  const footerPrimaryLinks = nuxtifyConfig.navigation?.footerPrimary;
5
5
  const footerSecondaryLinks = nuxtifyConfig.navigation?.footerSecondary;
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { useDisplay, useDrawer, useNuxtifyConfig, mdiArrowTopRight } from "#imports";
2
+ import { mdiArrowTopRight, useDisplay, useDrawer, useNuxtifyConfig } from "#imports";
3
3
  const { smAndDown } = useDisplay();
4
4
  const nuxtifyConfig = useNuxtifyConfig();
5
5
  const drawer = useDrawer();
@@ -22,7 +22,9 @@ const { mdAndUp } = useDisplay();
22
22
  <slot />
23
23
  </v-main>
24
24
 
25
- <AppToast />
25
+ <AppToast class="d-print-none" />
26
+
27
+ <AppDialog class="d-print-none" />
26
28
 
27
29
  <v-footer class="bg-primary justify-center mt-8">
28
30
  <AppFooter />
@@ -1,5 +1,5 @@
1
1
  <script setup>
2
- import { useRoute, capitalizeFirstLetter } from "#imports";
2
+ import { capitalizeFirstLetter, useRoute } from "#imports";
3
3
  const route = useRoute();
4
4
  </script>
5
5
 
@@ -1,19 +1,23 @@
1
1
  <script setup>
2
- import { useServerSeoMeta, useNuxtifyConfig } from "#imports";
2
+ import { useNuxtifyConfig, useServerSeoMeta } from "#imports";
3
+ const nuxtifyConfig = useNuxtifyConfig();
3
4
  useServerSeoMeta({
4
- title: "@nuxtify/pages",
5
- description: "This is the @nuxtify/pages homepage."
5
+ title: `${nuxtifyConfig.brand?.name}`,
6
+ description: `This is the ${nuxtifyConfig.brand?.name} home page.`
6
7
  });
7
- const nuxtifyConfig = useNuxtifyConfig();
8
8
  </script>
9
9
 
10
10
  <template>
11
11
  <v-container class="text-center">
12
- <ClientOnly>
13
- <h1>{{ nuxtifyConfig.brand?.name }} Home</h1>
14
- <template #fallback>
15
- <AppLoading />
16
- </template>
17
- </ClientOnly>
12
+ <v-row>
13
+ <v-col cols="12">
14
+ <ClientOnly>
15
+ <h1>{{ nuxtifyConfig.brand?.name }} Home</h1>
16
+ <template #fallback>
17
+ <AppLoading />
18
+ </template>
19
+ </ClientOnly>
20
+ </v-col>
21
+ </v-row>
18
22
  </v-container>
19
23
  </template>
@@ -1 +1 @@
1
- export { mdiArrowRight, mdiClose, mdiMenu, mdiArrowTopRight } from '@mdi/js';
1
+ export { mdiArrowRight, mdiArrowTopRight, mdiClose, mdiMenu } from '@mdi/js';
@@ -1 +1 @@
1
- export { mdiArrowRight, mdiClose, mdiMenu, mdiArrowTopRight } from "@mdi/js";
1
+ export { mdiArrowRight, mdiArrowTopRight, mdiClose, mdiMenu } from "@mdi/js";
package/package.json CHANGED
@@ -1,9 +1,9 @@
1
1
  {
2
2
  "name": "@nuxtify/pages",
3
- "version": "0.2.1",
3
+ "version": "0.3.1",
4
4
  "description": "Nuxtify pages module powered by Nuxt and Vuetify.",
5
5
  "license": "MIT",
6
- "homepage": "https://nuxtify.dev/",
6
+ "homepage": "https://nuxtify.dev",
7
7
  "author": "Nuxtify.dev <hello@nuxtify.dev>",
8
8
  "funding": "https://github.com/sponsors/davidstackio",
9
9
  "repository": {
@@ -43,21 +43,20 @@
43
43
  "test:types": "vue-tsc --noEmit && cd playground && vue-tsc --noEmit"
44
44
  },
45
45
  "dependencies": {
46
- "@mdi/js": "^7.4.47",
47
- "defu": "^6.1.4",
48
- "vuetify-nuxt-module": "^0.18.6"
46
+ "@nuxtify/core": "^0.1.0",
47
+ "defu": "^6.1.4"
49
48
  },
50
49
  "devDependencies": {
51
- "@nuxt/devtools": "^2.4.0",
52
- "@nuxt/eslint-config": "^1.3.0",
53
- "@nuxt/kit": "^3.17.2",
50
+ "@nuxt/devtools": "^2.4.1",
51
+ "@nuxt/eslint-config": "^1.3.1",
52
+ "@nuxt/kit": "^3.17.3",
54
53
  "@nuxt/module-builder": "^1.0.1",
55
- "@nuxt/schema": "^3.17.2",
56
- "@nuxt/test-utils": "^3.18.0",
57
- "@types/node": "^20.17.46",
54
+ "@nuxt/schema": "^3.17.3",
55
+ "@nuxt/test-utils": "^3.19.0",
56
+ "@types/node": "^22.15.18",
58
57
  "changelogen": "^0.6.1",
59
58
  "eslint": "^9.26.0",
60
- "nuxt": "^3.17.2",
59
+ "nuxt": "^3.17.3",
61
60
  "typescript": "~5.8.2",
62
61
  "vitest": "^3.1.3",
63
62
  "vue-tsc": "^2.2.10"
@@ -1,36 +0,0 @@
1
- <script setup>
2
- import { useDisplay, computed, useNuxtifyConfig, isExternalUrl } from "#imports";
3
- const nuxtifyConfig = useNuxtifyConfig();
4
- const { xs } = useDisplay();
5
- const isExternalLink = computed(
6
- () => isExternalUrl(nuxtifyConfig.announcement?.buttonUrl ?? "", nuxtifyConfig.brand?.domain ?? "")
7
- );
8
- </script>
9
-
10
- <template>
11
- <v-system-bar
12
- :height="xs ? 60 : 40"
13
- :order="-100"
14
- color="primary"
15
- class="justify-center text-start"
16
- >
17
- <div
18
- v-if="nuxtifyConfig.announcement?.message"
19
- :class="`${xs ? 'text-subtitle-2' : 'text-subtitle-1'} mr-4`"
20
- >
21
- {{ nuxtifyConfig.announcement.message }}
22
- </div>
23
- <v-btn
24
- v-if="
25
- nuxtifyConfig.announcement?.buttonText && nuxtifyConfig.announcement.buttonUrl
26
- "
27
- :to="!isExternalLink ? nuxtifyConfig.announcement.buttonUrl : void 0"
28
- :href="isExternalLink ? nuxtifyConfig.announcement.buttonUrl : void 0"
29
- size="small"
30
- variant="flat"
31
- color="secondary"
32
- >
33
- {{ nuxtifyConfig.announcement.buttonText }}
34
- </v-btn>
35
- </v-system-bar>
36
- </template>
@@ -1,2 +0,0 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- export default _default;
@@ -1,38 +0,0 @@
1
- <script setup>
2
- import { useDialog } from "#imports";
3
- const dialog = useDialog();
4
- </script>
5
-
6
- <template>
7
- <v-dialog
8
- v-model="dialog.show"
9
- width="500"
10
- >
11
- <v-card class="pa-2">
12
- <v-card-title>{{ dialog.title }}</v-card-title>
13
-
14
- <v-card-text class="ml-n2">
15
- {{ dialog.message }}
16
- </v-card-text>
17
-
18
- <v-card-actions>
19
- <v-spacer />
20
-
21
- <v-btn
22
- color="grey-darken-1"
23
- @click="dialog.show = false"
24
- >
25
- {{ dialog.closeButtonText }}
26
- </v-btn>
27
-
28
- <v-btn
29
- :color="dialog.action.buttonColor"
30
- variant="flat"
31
- @click="dialog.action.function"
32
- >
33
- {{ dialog.action.buttonText }}
34
- </v-btn>
35
- </v-card-actions>
36
- </v-card>
37
- </v-dialog>
38
- </template>
@@ -1,2 +0,0 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- export default _default;
@@ -1,16 +0,0 @@
1
- <template>
2
- <div class="center">
3
- <div class="sk-chase">
4
- <div class="sk-chase-dot" />
5
- <div class="sk-chase-dot" />
6
- <div class="sk-chase-dot" />
7
- <div class="sk-chase-dot" />
8
- <div class="sk-chase-dot" />
9
- <div class="sk-chase-dot" />
10
- </div>
11
- </div>
12
- </template>
13
-
14
- <style scoped>
15
- .center{align-items:center;display:flex;height:100vh;justify-content:center}.sk-chase{animation:sk-chase 2.5s linear infinite both;height:40px;position:relative;width:40px}.sk-chase-dot{animation:sk-chase-dot 2s ease-in-out infinite both;height:100%;left:0;position:absolute;top:0;width:100%}.sk-chase-dot:before{animation:sk-chase-dot-before 2s ease-in-out infinite both;background-color:rgb(var(--v-theme-primary));border-radius:100%;content:"";display:block;height:25%;width:25%}.sk-chase-dot:first-child{animation-delay:-1.1s}.sk-chase-dot:nth-child(2){animation-delay:-1s}.sk-chase-dot:nth-child(3){animation-delay:-.9s}.sk-chase-dot:nth-child(4){animation-delay:-.8s}.sk-chase-dot:nth-child(5){animation-delay:-.7s}.sk-chase-dot:nth-child(6){animation-delay:-.6s}.sk-chase-dot:first-child:before{animation-delay:-1.1s}.sk-chase-dot:nth-child(2):before{animation-delay:-1s}.sk-chase-dot:nth-child(3):before{animation-delay:-.9s}.sk-chase-dot:nth-child(4):before{animation-delay:-.8s}.sk-chase-dot:nth-child(5):before{animation-delay:-.7s}.sk-chase-dot:nth-child(6):before{animation-delay:-.6s}@keyframes sk-chase{to{transform:rotate(1turn)}}@keyframes sk-chase-dot{80%,to{transform:rotate(1turn)}}@keyframes sk-chase-dot-before{50%{transform:scale(.4)}0%,to{transform:scale(1)}}
16
- </style>
@@ -1,2 +0,0 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- export default _default;
@@ -1,41 +0,0 @@
1
- <script setup>
2
- import { useAppConfig, useDisplay, computed } from "#imports";
3
- const props = defineProps({
4
- dark: {
5
- type: Boolean,
6
- default: false
7
- },
8
- width: {
9
- type: Number,
10
- default: void 0
11
- }
12
- });
13
- const nuxtifyConfig = useAppConfig().nuxtify;
14
- const { smAndDown } = useDisplay();
15
- let imageUrl = nuxtifyConfig.brand.logo.lightUrl;
16
- if (props.dark && nuxtifyConfig.brand.logo.darkUrl) {
17
- imageUrl = nuxtifyConfig.brand.logo.darkUrl;
18
- }
19
- const width = computed(() => {
20
- if (props.width) {
21
- return props.width;
22
- } else {
23
- return smAndDown.value ? nuxtifyConfig.brand.logo.mobileWidth : nuxtifyConfig.brand.logo.width;
24
- }
25
- });
26
- </script>
27
-
28
- <template>
29
- <v-img
30
- v-if="imageUrl"
31
- :width
32
- :src="imageUrl"
33
- :alt="`${nuxtifyConfig.brand.name} logo`"
34
- />
35
- <span
36
- v-else
37
- :class="`text-subtitle-1 text-sm-h6 ${dark ? '' : 'text-primary'}`"
38
- >
39
- {{ nuxtifyConfig.brand.name }}
40
- </span>
41
- </template>
@@ -1,23 +0,0 @@
1
- declare const _default: import("vue").DefineComponent<import("vue").ExtractPropTypes<{
2
- dark: {
3
- type: BooleanConstructor;
4
- default: boolean;
5
- };
6
- width: {
7
- type: NumberConstructor;
8
- default: undefined;
9
- };
10
- }>, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<import("vue").ExtractPropTypes<{
11
- dark: {
12
- type: BooleanConstructor;
13
- default: boolean;
14
- };
15
- width: {
16
- type: NumberConstructor;
17
- default: undefined;
18
- };
19
- }>> & Readonly<{}>, {
20
- dark: boolean;
21
- width: number;
22
- }, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
23
- export default _default;
@@ -1,16 +0,0 @@
1
- <script setup>
2
- import { useToast } from "#imports";
3
- const toast = useToast();
4
- </script>
5
-
6
- <template>
7
- <v-snackbar
8
- v-model="toast.show"
9
- :timeout="5e3"
10
- color="info"
11
- :min-width="0"
12
- close-on-content-click
13
- >
14
- {{ toast.message }}
15
- </v-snackbar>
16
- </template>
@@ -1,2 +0,0 @@
1
- declare const _default: import("vue").DefineComponent<{}, {}, {}, {}, {}, import("vue").ComponentOptionsMixin, import("vue").ComponentOptionsMixin, {}, string, import("vue").PublicProps, Readonly<{}> & Readonly<{}>, {}, {}, {}, {}, string, import("vue").ComponentProvideOptions, true, {}, any>;
2
- export default _default;
@@ -1,13 +0,0 @@
1
- export interface Dialog {
2
- show: boolean;
3
- title: string;
4
- message: string;
5
- action: {
6
- function: () => Promise<void>;
7
- buttonText: string;
8
- buttonColor: string;
9
- };
10
- closeButtonText: string;
11
- }
12
- export declare const dialogInitialState: Dialog;
13
- export declare const useDialog: () => import("vue").Ref<Dialog, Dialog>;
@@ -1,15 +0,0 @@
1
- import { useState } from "#imports";
2
- export const dialogInitialState = {
3
- show: false,
4
- title: "",
5
- message: "",
6
- action: {
7
- function: () => new Promise((resolve) => resolve()),
8
- buttonText: "",
9
- buttonColor: ""
10
- },
11
- closeButtonText: "Cancel"
12
- };
13
- export const useDialog = () => useState("dialog", () => {
14
- return dialogInitialState;
15
- });
@@ -1,2 +0,0 @@
1
- import type { ModuleOptions } from '../../types.js';
2
- export declare const useNuxtifyConfig: () => ModuleOptions;
@@ -1,2 +0,0 @@
1
- import { useAppConfig } from "#imports";
2
- export const useNuxtifyConfig = () => useAppConfig().nuxtify;
@@ -1,15 +0,0 @@
1
- export declare const useDrawer: () => import("vue").Ref<boolean | null, boolean | null>;
2
- export declare const useToast: () => import("vue").Ref<{
3
- show: boolean;
4
- message: string;
5
- } | {
6
- show: boolean;
7
- message: string;
8
- }, {
9
- show: boolean;
10
- message: string;
11
- } | {
12
- show: boolean;
13
- message: string;
14
- }>;
15
- export declare const useErrorMessage: () => import("vue").Ref<string, string>;
@@ -1,10 +0,0 @@
1
- import { ref, useState } from "#imports";
2
- export const useDrawer = () => useState("drawer", () => null);
3
- export const useToast = () => useState(
4
- "toast",
5
- () => ref({
6
- show: false,
7
- message: ""
8
- })
9
- );
10
- export const useErrorMessage = () => useState("errorMessage", () => "");
@@ -1 +0,0 @@
1
- export { useNuxtifyConfig } from '../../composables/nuxtify.js';
@@ -1 +0,0 @@
1
- export { useNuxtifyConfig } from "../../composables/nuxtify.js";
@@ -1 +0,0 @@
1
- export { slugify, unslugify } from '../../utils/text.js';
@@ -1 +0,0 @@
1
- export { slugify, unslugify } from "../../utils/text.js";
@@ -1,19 +0,0 @@
1
- export declare const formRules: {
2
- required: (v: string) => true | "Required";
3
- requiredArray: <T>(v: Array<T>) => true | "Required";
4
- validEmail: (v: string) => true | "Must be a valid email address";
5
- minLength8: (v: string) => true | "Must be at least 8 characters";
6
- minLength12: (v: string) => true | "Must be at least 12 characters";
7
- maxLength30: (v: string) => true | "Must not be longer than 30 characters";
8
- maxLength60: (v: string) => true | "Must not be longer than 60 characters";
9
- maxLength120: (v: string) => true | "Must not be longer than 120 characters";
10
- maxLength200: (v: string) => true | "Must not be longer than 200 characters";
11
- maxLength300: (v: string) => true | "Must not be longer than 300 characters";
12
- maxLength600: (v: string) => true | "Must not be longer than 600 characters";
13
- maxLength1200: (v: string) => true | "Must not be longer than 1200 characters";
14
- isInteger: (v: string) => true | "Must be an integer";
15
- gt0: (v: string) => true | "Must be greater than 0";
16
- gte6: (v: string) => true | "Must be greater than or equal to 6";
17
- lte12: (v: string) => true | "Must be less than or equal to 12";
18
- lte365: (v: string) => true | "Must be less than or equal to 365";
19
- };
@@ -1,23 +0,0 @@
1
- export const formRules = {
2
- // Required
3
- required: (v) => !!v || "Required",
4
- requiredArray: (v) => !!v.length || "Required",
5
- // Text
6
- validEmail: (v) => /.+@.+/.test(v) || "Must be a valid email address",
7
- // Length
8
- minLength8: (v) => v ? v.length >= 8 || "Must be at least 8 characters" : true,
9
- minLength12: (v) => v ? v.length >= 12 || "Must be at least 12 characters" : true,
10
- maxLength30: (v) => v ? v.length <= 30 || "Must not be longer than 30 characters" : true,
11
- maxLength60: (v) => v ? v.length <= 60 || "Must not be longer than 60 characters" : true,
12
- maxLength120: (v) => v ? v.length <= 120 || "Must not be longer than 120 characters" : true,
13
- maxLength200: (v) => v ? v.length <= 200 || "Must not be longer than 200 characters" : true,
14
- maxLength300: (v) => v ? v.length <= 300 || "Must not be longer than 300 characters" : true,
15
- maxLength600: (v) => v ? v.length <= 600 || "Must not be longer than 600 characters" : true,
16
- maxLength1200: (v) => v ? v.length <= 1200 || "Must not be longer than 1200 characters" : true,
17
- // Number
18
- isInteger: (v) => Number.isInteger(+v) || "Must be an integer",
19
- gt0: (v) => Number.parseFloat(v) > 0 || "Must be greater than 0",
20
- gte6: (v) => Number.parseFloat(v) >= 6 || "Must be greater than or equal to 6",
21
- lte12: (v) => Number.parseFloat(v) <= 12 || "Must be less than or equal to 12",
22
- lte365: (v) => Number.parseFloat(v) <= 365 || "Must be less than or equal to 365"
23
- };
@@ -1,2 +0,0 @@
1
- export declare function blobToDataURL(blob: Blob): Promise<string>;
2
- export declare function filenameToUrl(filename: string, timestamped?: boolean): string;
@@ -1,19 +0,0 @@
1
- export function blobToDataURL(blob) {
2
- return new Promise((resolve, reject) => {
3
- const reader = new FileReader();
4
- reader.onload = (_e) => resolve(reader.result);
5
- reader.onerror = (_e) => reject(reader.error);
6
- reader.onabort = (_e) => reject(new Error("Read aborted"));
7
- reader.readAsDataURL(blob);
8
- });
9
- }
10
- export function filenameToUrl(filename, timestamped = false) {
11
- const filenameClean = encodeURIComponent(
12
- filename.trim().replace(/[^a-z0-9.-]/gi, "-").replace(/-{2,}/g, "-").replace(/\.{2,}/g, ".").replace(/-\./g, ".").replace(/-$/g, "").replace(/^-/g, "").slice(0, 500)
13
- // limit to the first 500 characters
14
- );
15
- if (timestamped) {
16
- return `${Date.now()}-${filenameClean}`;
17
- }
18
- return filenameClean;
19
- }
@@ -1,2 +0,0 @@
1
- export declare function toPercentage(val: number, decimals?: number): string;
2
- export declare function roundToFixed(val: number | string, positions?: number): number;
@@ -1,13 +0,0 @@
1
- export function toPercentage(val, decimals = 0) {
2
- const percentage = (val * 100).toFixed(decimals);
3
- return `${percentage}%`;
4
- }
5
- export function roundToFixed(val, positions = 2) {
6
- let text = 0;
7
- if (typeof val === "string") {
8
- text = +Number.parseFloat(val).toFixed(positions);
9
- } else if (typeof val === "number") {
10
- text = +val.toFixed(positions);
11
- }
12
- return text;
13
- }
@@ -1,23 +0,0 @@
1
- export declare const titleCase: (text: string, skipShortWords?: boolean) => string;
2
- export declare function capitalizeFirstLetter(text: string): string;
3
- export declare function fullName(firstName: string, lastName: string): string;
4
- export declare function parseFullName(fullName: string | undefined | null): {
5
- firstName: string;
6
- lastName: string;
7
- };
8
- export declare const honoraryName: (name: string, honorificSuffix?: string) => string;
9
- export declare function getPronouns(gender: string): {
10
- single: string;
11
- plural: string;
12
- possessive: string;
13
- possessivePlural: string;
14
- };
15
- export declare const formatPhone: (input: string, separator?: string) => string;
16
- export declare function formatDate(date: string, locale?: string): string;
17
- export declare function formatDateTime(date: string, locale?: string): string;
18
- export declare function booleanToText(bool: boolean): "Yes" | "No";
19
- export declare const truncate: (text: string, maxLength?: number, ellipses?: boolean) => string;
20
- export declare const slugify: (text: string) => string;
21
- export declare const unslugify: (text: string) => string;
22
- export declare function pluralize(value: number, units: string, showValue?: boolean): string;
23
- export declare const getLanguageName: (languageCode: string, displayLanguage?: string) => string | undefined;
@@ -1,159 +0,0 @@
1
- export const titleCase = (text, skipShortWords = true) => {
2
- const shortWords = ["and", "an", "the", "a", "but", "for", "at", "by", "to"];
3
- const words = text.split(" ");
4
- const titleWords = [];
5
- for (const [i] of words.entries()) {
6
- if (skipShortWords && shortWords.includes(words[i])) {
7
- if (i === 0) {
8
- titleWords.push(words[i].charAt(0).toUpperCase() + words[i].slice(1));
9
- } else {
10
- titleWords.push(words[i]);
11
- }
12
- } else {
13
- titleWords.push(words[i].charAt(0).toUpperCase() + words[i].slice(1));
14
- }
15
- }
16
- return titleWords.join(" ");
17
- };
18
- export function capitalizeFirstLetter(text) {
19
- if (!text) {
20
- return "";
21
- }
22
- return text.charAt(0).toUpperCase() + text.slice(1);
23
- }
24
- export function fullName(firstName, lastName) {
25
- let name = "";
26
- if (firstName && lastName) {
27
- name = `${firstName} ${lastName}`;
28
- } else if (firstName) {
29
- name = firstName;
30
- } else if (lastName) {
31
- name = lastName;
32
- }
33
- return name;
34
- }
35
- export function parseFullName(fullName2) {
36
- let firstName = "";
37
- let lastName = "";
38
- if (fullName2) {
39
- const nameSplit = fullName2.split(" ");
40
- firstName = nameSplit[0];
41
- if (nameSplit.length > 1) {
42
- lastName = nameSplit.slice(1).join(" ");
43
- }
44
- }
45
- return { firstName, lastName };
46
- }
47
- export const honoraryName = (name, honorificSuffix = "") => {
48
- return honorificSuffix ? `${name}, ${honorificSuffix}` : name;
49
- };
50
- export function getPronouns(gender) {
51
- if (gender === "male") {
52
- return {
53
- single: "he",
54
- plural: "he's",
55
- possessive: "his",
56
- possessivePlural: "his"
57
- };
58
- } else if (gender === "female") {
59
- return {
60
- single: "she",
61
- plural: "she's",
62
- possessive: "her",
63
- possessivePlural: "her's"
64
- };
65
- } else {
66
- return {
67
- single: "they",
68
- plural: "they're",
69
- possessive: "their",
70
- possessivePlural: "theirs"
71
- };
72
- }
73
- }
74
- export const formatPhone = (input, separator = "-") => {
75
- let phone = input;
76
- if (phone.slice(0, 2) === "+1") {
77
- phone = phone.slice(2);
78
- }
79
- if (phone.length === 10) {
80
- phone = phone.replace(
81
- /(\d{3})(\d{3})(\d{4})/,
82
- `$1${separator}$2${separator}$3`
83
- );
84
- }
85
- return phone;
86
- };
87
- export function formatDate(date, locale = "en-us") {
88
- return new Date(date).toLocaleDateString(locale, {
89
- year: "numeric",
90
- month: "long",
91
- day: "numeric"
92
- });
93
- }
94
- export function formatDateTime(date, locale = "en-us") {
95
- return new Date(date).toLocaleString(locale, {
96
- year: "numeric",
97
- month: "long",
98
- day: "numeric",
99
- hour: "numeric",
100
- minute: "numeric"
101
- });
102
- }
103
- export function booleanToText(bool) {
104
- return bool ? "Yes" : "No";
105
- }
106
- export const truncate = (text, maxLength = 80, ellipses = true) => {
107
- if (text.length > maxLength) {
108
- let trimmedString = text.substring(0, maxLength + 1);
109
- trimmedString = trimmedString.substring(
110
- 0,
111
- Math.min(trimmedString.length, trimmedString.lastIndexOf(" "))
112
- );
113
- return `${trimmedString}${ellipses ? "..." : ""}`;
114
- }
115
- return text;
116
- };
117
- export const slugify = (text) => {
118
- const slug = text.normalize("NFKD").toLowerCase().trim().replace(/\s+/g, "-").replace(/_/g, "-").replace(/-{2,}/g, "-").replace(/-$/g, "");
119
- return slug;
120
- };
121
- export const unslugify = (text) => {
122
- const unslug = text.replace(/-/g, " ");
123
- return unslug;
124
- };
125
- export function pluralize(value, units, showValue = true) {
126
- let text = "";
127
- let unitsPlural = units;
128
- if (unitsPlural.slice(-1) === "y") {
129
- unitsPlural = unitsPlural.slice(0, -1) + "ies";
130
- } else {
131
- unitsPlural = units + "s";
132
- }
133
- if (showValue) {
134
- if (value === 1) {
135
- text = `${value} ${units}`;
136
- } else {
137
- text = `${value} ${unitsPlural}`;
138
- }
139
- } else if (!value || value === 1) {
140
- text = `${units}`;
141
- } else {
142
- text = `${unitsPlural}`;
143
- }
144
- return text;
145
- }
146
- export const getLanguageName = (languageCode, displayLanguage = "en") => {
147
- try {
148
- const languageNames = new Intl.DisplayNames([displayLanguage], {
149
- type: "language"
150
- });
151
- return languageNames.of(languageCode);
152
- } catch (error) {
153
- console.error(
154
- `Error getting language name for code '${languageCode}' with locale '${displayLanguage}':`,
155
- error
156
- );
157
- return languageCode;
158
- }
159
- };
@@ -1,2 +0,0 @@
1
- export declare const delay: (ms: number) => Promise<unknown>;
2
- export declare function daysSince(targetDate: Date): number;
@@ -1,7 +0,0 @@
1
- export const delay = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
2
- export function daysSince(targetDate) {
3
- const currentDate = /* @__PURE__ */ new Date();
4
- const timeDifference = currentDate.getTime() - targetDate.getTime();
5
- const daysDifference = Math.floor(timeDifference / (1e3 * 60 * 60 * 24));
6
- return daysDifference;
7
- }
@@ -1,9 +0,0 @@
1
- export declare const getBaseUrl: (url: string) => string;
2
- export declare const getUtmParams: (url: string) => {
3
- utmSource: string | null;
4
- utmMedium: string | null;
5
- utmCampaign: string | null;
6
- utmTerm: string | null;
7
- utmContent: string | null;
8
- };
9
- export declare const isExternalUrl: (url: string, hostname: string) => boolean;
@@ -1,27 +0,0 @@
1
- export const getBaseUrl = (url) => {
2
- const urlObject = new URL(url);
3
- urlObject.search = "";
4
- urlObject.hash = "";
5
- return urlObject.href;
6
- };
7
- export const getUtmParams = (url) => {
8
- const urlSearchParams = new URLSearchParams(new URL(url).search);
9
- return {
10
- utmSource: urlSearchParams.get("utm_source"),
11
- utmMedium: urlSearchParams.get("utm_medium"),
12
- utmCampaign: urlSearchParams.get("utm_campaign"),
13
- utmTerm: urlSearchParams.get("utm_term"),
14
- utmContent: urlSearchParams.get("utm_content")
15
- };
16
- };
17
- export const isExternalUrl = (url, hostname) => {
18
- if (!url) {
19
- return false;
20
- }
21
- if (url.startsWith("/")) {
22
- return false;
23
- } else {
24
- const linkHostname = new URL(url).hostname;
25
- return linkHostname !== hostname;
26
- }
27
- };
@@ -1,7 +0,0 @@
1
- export declare const addOrReplaceArrayItem: (array: {
2
- id: string | number;
3
- [key: string]: unknown;
4
- }[], element: {
5
- id: string | number;
6
- [key: string]: unknown;
7
- }) => void;
@@ -1,5 +0,0 @@
1
- export const addOrReplaceArrayItem = (array, element) => {
2
- const i = array.findIndex((e) => e.id === element.id);
3
- if (i > -1) array[i] = element;
4
- else array.push(element);
5
- };
@@ -1 +0,0 @@
1
- export declare function youTubeUrl(url: string): string | null;
@@ -1,13 +0,0 @@
1
- function youTubeId(url) {
2
- const regExp = /^.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|&v=)([^#&?]*).*/;
3
- const match = url.match(regExp);
4
- return match && match[2].length === 11 ? match[2] : null;
5
- }
6
- export function youTubeUrl(url) {
7
- const videoId = youTubeId(url);
8
- if (videoId) {
9
- return `https://www.youtube.com/embed/${videoId}`;
10
- } else {
11
- return null;
12
- }
13
- }