diff --git a/package.json b/package.json
index d7e3de424..8fef8c97f 100644
--- a/package.json
+++ b/package.json
@@ -70,6 +70,7 @@
"vue-tsc": "^1.8.5"
},
"dependencies": {
+ "date-fns": "^2.30.0",
"lodash": "^4.17.21",
"pinia": "^2.1.6"
}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index 1e7d62470..5dcccd9c9 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -5,6 +5,9 @@ settings:
excludeLinksFromLockfile: false
dependencies:
+ date-fns:
+ specifier: ^2.30.0
+ version: 2.30.0
lodash:
specifier: ^4.17.21
version: 4.17.21
@@ -1478,7 +1481,6 @@ packages:
engines: {node: '>=6.9.0'}
dependencies:
regenerator-runtime: 0.14.0
- dev: true
/@babel/template@7.22.15:
resolution: {integrity: sha512-QPErUVm4uyJa60rkI73qneDacvdvzxshT3kksGqlGWYdOTIUOwJ7RDUL8sGqslY1uXWSL6xMFKEXDS3ox2uF0w==}
@@ -5279,6 +5281,13 @@ packages:
assert-plus: 1.0.0
dev: true
+ /date-fns@2.30.0:
+ resolution: {integrity: sha512-fnULvOpxnC5/Vg3NCiWelDsLiUc9bRwAPs/+LfTLNvetFCtCTN+yQz15C/fs4AwX1R9K5GLtLfn8QW+dWisaAw==}
+ engines: {node: '>=0.11'}
+ dependencies:
+ '@babel/runtime': 7.23.1
+ dev: false
+
/dayjs@1.11.10:
resolution: {integrity: sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==}
dev: true
@@ -9279,7 +9288,6 @@ packages:
/regenerator-runtime@0.14.0:
resolution: {integrity: sha512-srw17NI0TUWHuGa5CFGGmhfNIeja30WMBfbslPNhf6JrqQlLN5gcrvig1oqPxiVaXb0oW0XRKtH6Nngs5lKCIA==}
- dev: true
/regenerator-transform@0.15.2:
resolution: {integrity: sha512-hfMp2BoF0qOk3uc5V20ALGDS2ddjQaLrdl7xrGXvAIow7qeWRM2VA2HuCHkUKk9slq3VwEwLNK3DFBqDfPGYtg==}
diff --git a/serve/serve.vue b/serve/serve.vue
index fe0761e70..307f17cd2 100644
--- a/serve/serve.vue
+++ b/serve/serve.vue
@@ -1,31 +1,36 @@
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib-components/BlockEvent.vue b/src/lib-components/BlockEvent.vue
new file mode 100644
index 000000000..8dcdff10b
--- /dev/null
+++ b/src/lib-components/BlockEvent.vue
@@ -0,0 +1,189 @@
+
+
+
+
+
+
+
+
{{ category }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib-components/BlockSimpleCard.vue b/src/lib-components/BlockSimpleCard.vue
new file mode 100644
index 000000000..20a614de9
--- /dev/null
+++ b/src/lib-components/BlockSimpleCard.vue
@@ -0,0 +1,164 @@
+
+
+
+
+
+ {{ sectionName }}
+
+
+ {{ title }}
+
+
+
+
+ {{ parsedText }}
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib-components/BlockSpaces.vue b/src/lib-components/BlockSpaces.vue
new file mode 100644
index 000000000..801e94abe
--- /dev/null
+++ b/src/lib-components/BlockSpaces.vue
@@ -0,0 +1,201 @@
+
+
+
+
+
+
+
+
+
+
+ {{ title }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/lib-components/BlockSponsor.vue b/src/lib-components/BlockSponsor.vue
index 1f78ff61a..a18ae0c82 100644
--- a/src/lib-components/BlockSponsor.vue
+++ b/src/lib-components/BlockSponsor.vue
@@ -30,7 +30,11 @@ export default {
-
+
diff --git a/src/lib-components/index.js b/src/lib-components/index.js
index 4892d83dd..e8e48fdbf 100644
--- a/src/lib-components/index.js
+++ b/src/lib-components/index.js
@@ -4,21 +4,24 @@ import '@/styles/global.scss'
export { default as AlphabeticalBrowseBy } from './AlphabeticalBrowseBy.vue'
export { default as BlockCallToAction } from './BlockCallToAction.vue'
export { default as BlockCallToActionTwoUp } from './BlockCallToActionTwoUp.vue'
+export { default as BlockCardWithIllustration } from './BlockCardWithIllustration.vue'
export { default as BlockDate } from './BlockDate.vue'
+export { default as BlockEvent } from './BlockEvent.vue'
export { default as BlockMediaWithText } from './BlockMediaWithText.vue'
+export { default as BlockSimpleCard } from './BlockSimpleCard.vue'
+export { default as BlockSpaces } from './BlockSpaces.vue'
+export { default as BlockSponsor } from './BlockSponsor.vue'
export { default as ButtonHide } from './ButtonHide.vue'
export { default as ButtonLink } from './ButtonLink.vue'
export { default as ButtonMore } from './ButtonMore.vue'
export { default as ButtonShow } from './ButtonShow.vue'
export { default as DividerGeneral } from './DividerGeneral.vue'
export { default as DividerWayFinder } from './DividerWayFinder.vue'
+export { default as FlexibleMediaGalleryNewLightbox } from './Flexible/MediaGallery/NewLightbox.vue'
+export { default as FooterMain } from './FooterMain.vue'
export { default as FooterPrimary } from './FooterPrimary.vue'
-export { default as BlockSponsor } from './BlockSponsor.vue'
-export { default as FooterSponsor } from './FooterSponsor.vue'
export { default as FooterSock } from './FooterSock.vue'
-export { default as FooterMain } from './FooterMain.vue'
-
-export { default as FlexibleMediaGalleryNewLightbox } from './Flexible/MediaGallery/NewLightbox.vue'
+export { default as FooterSponsor } from './FooterSponsor.vue'
export { default as HeadingArrow } from './HeadingArrow.vue'
export { default as IconWithLink } from './IconWithLink.vue'
export { default as MediaItem } from './Media/Item.vue'
@@ -27,7 +30,7 @@ export { default as RichText } from './RichText.vue'
export { default as SearchResult } from './SearchResult.vue'
export { default as SectionHeader } from './SectionHeader.vue'
export { default as SectionWrapper } from './SectionWrapper.vue'
+export { default as SingleCheckbox } from './SingleCheckbox.vue'
export { default as SiteBrandBar } from './SiteBrandBar.vue'
export { default as SiteNotificationAlert } from './SiteNotificationAlert.vue'
-export { default as SingleCheckbox } from './SingleCheckbox.vue'
export { default as SmartLink } from './SmartLink.vue'
diff --git a/src/stories/BlockCardWithIllustration.spec.js b/src/stories/BlockCardWithIllustration.spec.js
new file mode 100644
index 000000000..0b2f51cde
--- /dev/null
+++ b/src/stories/BlockCardWithIllustration.spec.js
@@ -0,0 +1,28 @@
+describe('BLOCK / Card With Illustration', () => {
+ it('Default', () => {
+ cy.visit(
+ '/iframe.html?id=block-card-with-illustration--default&args=&viewMode=story'
+ )
+ cy.get('.block-card-with-illustration ').should('exist')
+
+ // Opens local link in same tag
+ cy.contains('a.smart-link', 'Quisque Volutpat').should(
+ 'not.have.attr',
+ 'target',
+ '_blank'
+ )
+
+ cy.percySnapshot('BLOCK / Card With Illustration: Default')
+ })
+
+ it('Opens external links in a new tab', () => {
+ cy.visit(
+ '/iframe.html?id=block-card-with-illustration--external-link&args=&viewMode=story'
+ )
+ cy.contains('a.smart-link', 'Quisque Volutpat').should(
+ 'have.attr',
+ 'target',
+ '_blank'
+ )
+ })
+})
diff --git a/src/stories/BlockCardWithIllustration.stories.js b/src/stories/BlockCardWithIllustration.stories.js
new file mode 100644
index 000000000..9a869ff99
--- /dev/null
+++ b/src/stories/BlockCardWithIllustration.stories.js
@@ -0,0 +1,278 @@
+import BlockCardWithIllustration from '@/lib-components/BlockCardWithIllustration'
+
+// Storybook default settings
+export default {
+ title: 'BLOCK / Card With Illustration',
+ component: BlockCardWithIllustration,
+}
+
+const mock = {
+ to: '/help/foo/bar/',
+ title: 'Quisque Volutpat',
+ text: 'Need help figuring out what topic you want to explore for your project?
',
+}
+
+const mock2 = {
+ to: '/visit/foo/bar/',
+ title: 'Quisque Volutpat',
+ text: 'Need help figuring out what topic you want to explore for your project? Having trouble turning a general idea into something more specific? Learn how to develop a research question through synchronous.
',
+}
+
+export function Default() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function Visit() {
+ return {
+ data() {
+ return {
+ ...mock2,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function LongTextAbout() {
+ return {
+ data() {
+ return {
+ ...mock2,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function DatabasesVisit() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function RemoteAccessHelp() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function ResearchVisit() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function TeachingAbout() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function ExternalLink() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function HorizontalCardRemoteAccess() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function HorizontalCardTeaching() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function HorizontalCardResearch() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function HorizontalCardShortDigitizedResources() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
+
+export function NoText() {
+ return {
+ data() {
+ return {
+ ...mock,
+ text: '',
+ }
+ },
+ components: { BlockCardWithIllustration },
+ template: `
+
+ `,
+ }
+}
diff --git a/src/stories/BlockEvent.spec.js b/src/stories/BlockEvent.spec.js
new file mode 100644
index 000000000..c86512236
--- /dev/null
+++ b/src/stories/BlockEvent.spec.js
@@ -0,0 +1,8 @@
+describe('BLOCK / Event', () => {
+ it('Default', () => {
+ cy.visit('/iframe.html?id=block-event--short-text&args=&viewMode=story')
+ cy.get('.block-event').should('exist')
+
+ cy.percySnapshot('BLOCK / Event: Short Text')
+ })
+})
diff --git a/src/stories/BlockEvent.stories.js b/src/stories/BlockEvent.stories.js
new file mode 100644
index 000000000..ffe6f02b4
--- /dev/null
+++ b/src/stories/BlockEvent.stories.js
@@ -0,0 +1,113 @@
+// Storybook default settings
+import BlockEvent from '@/lib-components/BlockEvent'
+
+// Import mock api data
+import * as API from '@/stories/mock-api.json'
+
+// Storybook default settings
+export default {
+ title: 'BLOCK / Event',
+ component: BlockEvent,
+}
+
+export function ShortText() {
+ return {
+ data() {
+ return {
+ item: { ...API.bricks[0] },
+ }
+ },
+ components: { BlockEvent },
+ template: `
+
+ `,
+ }
+}
+
+export function LongText() {
+ return {
+ data() {
+ return {
+ item: { ...API.bricks[1] },
+ }
+ },
+ components: { BlockEvent },
+ template: `
+
+ `,
+ }
+}
+
+export function Visit() {
+ return {
+ data() {
+ return {
+ item: { ...API.bricks[1] },
+ }
+ },
+ components: { BlockEvent },
+ template: `
+
+ `,
+ }
+}
+
+export function About() {
+ return {
+ data() {
+ return {
+ item: { ...API.bricks[1] },
+ }
+ },
+ components: { BlockEvent },
+ template: `
+
+ `,
+ }
+}
+
+export function Help() {
+ return {
+ data() {
+ return {
+ item: { ...API.bricks[1] },
+ }
+ },
+ components: { BlockEvent },
+ template: `
+
+ `,
+ }
+}
diff --git a/src/stories/BlockSimpleCard.spec.js b/src/stories/BlockSimpleCard.spec.js
new file mode 100644
index 000000000..542717642
--- /dev/null
+++ b/src/stories/BlockSimpleCard.spec.js
@@ -0,0 +1,28 @@
+describe('BLOCK / SimpleCard', () => {
+ it('Default', () => {
+ cy.visit(
+ '/iframe.html?id=block-simple-card--default&args=&viewMode=story'
+ )
+ cy.get('.block-simple-card').should('exist')
+
+ // Opens external link in new tag
+ cy.contains('a.smart-link', 'Types of Sinkholes').should(
+ 'have.attr',
+ 'target',
+ '_blank'
+ )
+
+ cy.percySnapshot('BLOCK / Simple Card: Default')
+ })
+
+ it('Opens internal links in the same tab', () => {
+ cy.visit(
+ '/iframe.html?id=block-simple-card--internal-link&args=&viewMode=story'
+ )
+ cy.contains('a.smart-link', 'Sink Hole').should(
+ 'not.have.attr',
+ 'target',
+ '_blank'
+ )
+ })
+})
diff --git a/src/stories/BlockSimpleCard.stories.js b/src/stories/BlockSimpleCard.stories.js
new file mode 100644
index 000000000..2698aed63
--- /dev/null
+++ b/src/stories/BlockSimpleCard.stories.js
@@ -0,0 +1,104 @@
+import BlockSimpleCard from '@/lib-components/BlockSimpleCard'
+
+export default {
+ title: 'BLOCK / Simple Card',
+ component: BlockSimpleCard,
+}
+
+const mockExternal = {
+ title: 'Types of Sinkholes',
+ summary:
+ 'It is a frightening thought to imagine the ground below your feet or house suddenly collapsing and forming a big hole in the ground. Sinkholes rarely happen, but when they strike, tragedy can occur. Sinkholes happen when the ground below the land surface cannot support the land surface. They happen for many reasons; read on to educate yourself about sinkholes.',
+ externalLink: 'https://www.heliconusa.com/types-of-sinkholes/',
+}
+
+const mockInternal = {
+ id: '13785',
+ contentLink: [
+ {
+ slug: 'sink-hole',
+ title: 'Sink Hole',
+ summary:
+ 'Man-made sinkholes are the result of a variety of practices, from drilling to mining to changes in water diversion systems to broken pipes.
',
+ },
+ ],
+}
+
+const mockInternalGuide = {
+ id: '13899',
+ contentLink: [
+ {
+ slug: 'road-work',
+ title: 'Road Work Guide',
+ summary:
+ 'It is a frightening thought to imagine the ground below your feet or house suddenly collapsing and forming a big hole in the ground.',
+ researchGuideUrl: 'http://libguides.library.ucla.edu',
+ },
+ ],
+}
+
+// Variations of stories below
+// ExternalLink
+export function Default() {
+ return {
+ data() {
+ return { ...mockExternal }
+ },
+ components: { BlockSimpleCard },
+ template: `
+
+ `,
+ }
+}
+
+export function InternalLink() {
+ return {
+ data() {
+ return { ...mockInternal }
+ },
+ components: { BlockSimpleCard },
+ template: `
+
+ `,
+ }
+}
+
+export function InternalLinkGuide() {
+ return {
+ data() {
+ return { ...mockInternalGuide }
+ },
+ components: { BlockSimpleCard },
+ template: `
+
+ `,
+ }
+}
+
+export function LongText() {
+ return {
+ data() {
+ return {
+ card: {
+ to: 'sink-hole',
+ title: 'Sink Hole',
+ text: 'Adipisicing do enim voluptate amet nisi eiusmod ex aliqua exercitation nulla sint magna proident proident. Exercitation in et enim est esse consectetur ex dolore labore ut laborum non minim ea. In ad excepteur cillum commodo veniam dolore labore cupidatat. Ea fugiat occaecat et fugiat consectetur do consectetur anim cillum. Ex nulla est ex cillum esse. Aliquip deserunt consequat pariatur sunt labore occaecat. Excepteur nostrud ex ex anim ut irure tempor eu quis id cupidatat consectetur. Mollit adipisicing cupidatat occaecat labore cupidatat culpa sit pariatur. Anim reprehenderit dolore est aliqua id pariatur quis exercitation incididunt do magna. Reprehenderit irure duis aliqua ullamco sint incididunt commodo exercitation reprehenderit. Non esse quis consectetur eiusmod. Labore dolore ex commodo culpa incididunt ipsum nulla elit tempor in officia eiusmod. Velit incididunt Lorem eiusmod eu anim dolore voluptate elit nisi aliquip est elit qui occaecat. Consequat cillum consectetur pariatur magna incididunt tempor eu do commodo laboris proident id dolor. Pariatur sint incididunt Lorem anim est nostrud qui excepteur eu fugiat exercitation exercitation. Lorem laboris reprehenderit ipsum aliquip ullamco sunt aute culpa occaecat in aliquip incididunt consequat nostrud.',
+ },
+ }
+ },
+ components: { BlockSimpleCard },
+ template: ' ',
+ }
+}
diff --git a/src/stories/BlockSpaces.spec.js b/src/stories/BlockSpaces.spec.js
new file mode 100644
index 000000000..92f39e4be
--- /dev/null
+++ b/src/stories/BlockSpaces.spec.js
@@ -0,0 +1,8 @@
+describe('BLOCK / Spaces / List', () => {
+ it('Default', () => {
+ cy.visit('/iframe.html?id=block-spaces--default&args=&viewMode=story')
+ cy.get('.block-spaces').should('exist')
+
+ cy.percySnapshot('BLOCK / Spaces: Default')
+ })
+})
diff --git a/src/stories/BlockSpaces.stories.js b/src/stories/BlockSpaces.stories.js
new file mode 100644
index 000000000..13bea173e
--- /dev/null
+++ b/src/stories/BlockSpaces.stories.js
@@ -0,0 +1,83 @@
+import BlockSpaces from '@/lib-components/BlockSpaces'
+
+export default {
+ title: 'BLOCK / Spaces',
+ component: BlockSpaces,
+}
+
+const mock = {
+ to: 'https://calendar.library.ucla.edu',
+ title: 'Bureaux de Garcons',
+ location: 'Fast Lane Building',
+ text: 'Eclectic sophisticated carefully curated lovely Baggu Muji sharp finest efficient perfect. Hub Boeing 787 lovely Melbourne flat white ryokan. Global iconic Gaggenau Muji bulletin premium espresso delightful destination vibrant remarkable elegant bureaux boutique. Sunspel exclusive first-class espresso, Fast Lane intricate Melbourne Airbus A380 pintxos Shinkansen Swiss vibrant the highest quality.
',
+}
+
+const mock2 = {
+ to: 'https://www.gettyimages.com/photos/cute-llamas',
+ title: 'Tote Bag Boutique',
+ location: 'Destination Building',
+ text: 'Nordic classic hand-crafted Marylebone elegant soft power bespoke signature punctual pintxos handsome discerning Asia-Pacific global international. Exquisite Asia-Pacific Washlet sharp. Exquisite Lufthansa hub, concierge cosy bureaux finest joy global iconic Nordic Singapore. Hand-crafted joy alluring intricate.',
+}
+
+const mock3 = {
+ to: '',
+ title: 'Ginza Tsutaya Lounge',
+ location: 'K-pop Kanteen',
+ text: 'Punctual tote bag the highest quality Nordic, sharp Singapore Gaggenau international Ginza Tsutaya conversation joy lovely Helsinki perfect. Uniforms classic izakaya Ettinger. Signature ANA sharp, liveable Shinkansen Asia-Pacific soft power. Efficient Scandinavian liveable international craftsmanship remarkable cutting-edge premium business class eclectic K-pop lovely Washlet classic.',
+}
+
+// Variations of stories below
+export function Default() {
+ return {
+ data() {
+ return {
+ ...mock,
+ }
+ },
+ components: { BlockSpaces },
+ template: `
+
+ `,
+ }
+}
+
+export function ExternalLink() {
+ return {
+ data() {
+ return {
+ item: {
+ ...mock2,
+ },
+ }
+ },
+ components: { BlockSpaces },
+ template: `
+
+ `,
+ }
+}
+
+export function NoLink() {
+ return {
+ data() {
+ return {
+ item: {
+ ...mock3,
+ },
+ }
+ },
+ components: { BlockSpaces },
+ template: `
+
+ `,
+ }
+}
diff --git a/src/utils/formatEventDates.js b/src/utils/formatEventDates.js
new file mode 100644
index 000000000..fb9e98707
--- /dev/null
+++ b/src/utils/formatEventDates.js
@@ -0,0 +1,32 @@
+import format from 'date-fns/format'
+
+/**
+ * Take two date strings, and return them in human readable date formats for Events
+ *
+ * @param {string} startDate
+ * @param {string} endDate
+ * @returns {string}
+ */
+
+function formatDates(startDate = '', endDate = '') {
+ const start = format(new Date(startDate), 'MMMM d, Y')
+ // console.log(start)
+ const end = format(new Date(endDate), 'MMMM d, Y')
+
+ // "February 11 2020 – May 31 2021"
+ let output = `${start} - ${end}`
+
+ if (start === end) {
+ // Thursday, January 28
+ output = format(new Date(startDate), 'MMMM d, Y')
+ }
+
+ if (!endDate) {
+ // February 11 2020
+ output = start
+ }
+
+ return output
+}
+
+export default formatDates
diff --git a/src/utils/formatEventTimes.js b/src/utils/formatEventTimes.js
new file mode 100644
index 000000000..0d18d1975
--- /dev/null
+++ b/src/utils/formatEventTimes.js
@@ -0,0 +1,31 @@
+import format from 'date-fns/format'
+
+/**
+ * Take two date strings, and return them in human readable time for Events
+ *
+ * @param {string} startDate
+ * @param {string} endDate
+ * @returns {string}
+ */
+
+function formatTimes(startDate = '', endDate = '') {
+ const start = format(new Date(startDate), 'h:mm aaa')
+ const end = format(new Date(endDate), 'h:mm aaa')
+
+ // "9:00 am – 1:00 pm"
+ let output = `${start} - ${end}`
+
+ if (start === end) {
+ // "9:00 am"
+ output = format(new Date(startDate), 'h:mm aaa')
+ }
+
+ if (!endDate) {
+ // 9:00 am
+ output = start
+ }
+
+ return output
+}
+
+export default formatTimes
diff --git a/src/utils/isInternalLink.js b/src/utils/isInternalLink.js
index 7b43d30aa..a967497c4 100644
--- a/src/utils/isInternalLink.js
+++ b/src/utils/isInternalLink.js
@@ -1,12 +1,20 @@
-export default function isInternalLink(uri = '') {
+/**
+ * Take a URI and determine if it is an internal link
+ * @param {string} uri
+ * @returns {boolean}
+ */
+
+function isInternalLink(uri = '') {
let output = false
if (
uri == null
- || String(uri).indexOf('/') === 0
- || (!uri.includes('.') && uri.length !== 0)
+ || String(uri).indexOf('/') === 0
+ || (!uri.includes('.') && uri.length !== 0)
)
output = true
return output
}
+
+export default isInternalLink