diff --git a/assets/js/getLinkTag.js b/assets/js/getLinkTag.js new file mode 100644 index 000000000..eb03ec171 --- /dev/null +++ b/assets/js/getLinkTag.js @@ -0,0 +1,18 @@ +const DEFAULT_TAG = "button" +const ANCHOR_TAG = "a" +const FRAMEWORK_LINK = "NuxtLink" // or "router-link", "g-link"... + +const getLinkTag = ({ to, blank }) => { + if (!to) { + return DEFAULT_TAG + } else if (blank) { + return ANCHOR_TAG + } else if (/^\/(?!\/).*$/.test(to)) { + // regex101.com/r/LU1iFL/1 + return FRAMEWORK_LINK + } else { + return ANCHOR_TAG + } +} + +export { getLinkTag as default, ANCHOR_TAG, FRAMEWORK_LINK } diff --git a/assets/scss/styles.scss b/assets/scss/styles.scss index 3af97891b..829e5f117 100644 --- a/assets/scss/styles.scss +++ b/assets/scss/styles.scss @@ -149,6 +149,46 @@ hr { @apply my-4; } +.tippy-popper { + .tooltip-theme { + @apply bg-secondary; + @apply text-primaryLight; + @apply text-xs; + @apply font-semibold; + @apply px-2; + @apply px-4; + @apply shadow; + } + + .popover-theme { + @apply bg-primaryLight; + @apply text-secondary; + @apply p-2; + @apply shadow-md; + } + + &[x-placement^="top"] .tippy-tooltip .tippy-arrow { + border-top-color: var(--color-primary-light); + } + + &[x-placement^="bottom"] .tippy-tooltip .tippy-arrow { + border-bottom-color: var(--color-primary-light); + } + + &[x-placement^="left"] .tippy-tooltip .tippy-arrow { + border-left-color: var(--color-primary-light); + } + + &[x-placement^="right"] .tippy-tooltip .tippy-arrow { + border-right-color: var(--color-primary-light); + } +} + +[arrow] > div { + @apply flex; + @apply w-full; +} + .tooltip { @apply z-50; @apply outline-none; diff --git a/assets/scss/themes.scss b/assets/scss/themes.scss index fd65d3b83..616cfad57 100644 --- a/assets/scss/themes.scss +++ b/assets/scss/themes.scss @@ -29,11 +29,11 @@ @mixin lightTheme { // Background color - --primary-color: rgba(255, 255, 255, 1); + --primary-color: theme("colors.white"); // Light Background color - --primary-light-color: theme("colors.gray.200"); + --primary-light-color: theme("colors.gray.50"); // Dark Background color - --primary-dark-color: rgba(0, 0, 0, 0.02); + --primary-dark-color: theme("colors.gray.100"); // Text color --secondary-color: theme("colors.gray.600"); // Light Text color diff --git a/components/app/Header.vue b/components/app/Header.vue index 393c0cb1e..c6c140d08 100644 --- a/components/app/Header.vue +++ b/components/app/Header.vue @@ -1,9 +1,10 @@ + + diff --git a/components/button/Secondary.vue b/components/button/Secondary.vue new file mode 100644 index 000000000..b3794f8dc --- /dev/null +++ b/components/button/Secondary.vue @@ -0,0 +1,96 @@ + + + diff --git a/components/landing/Features.vue b/components/landing/Features.vue new file mode 100644 index 000000000..b519cf144 --- /dev/null +++ b/components/landing/Features.vue @@ -0,0 +1,118 @@ + + + diff --git a/components/landing/Footer.vue b/components/landing/Footer.vue new file mode 100644 index 000000000..2211aa4cd --- /dev/null +++ b/components/landing/Footer.vue @@ -0,0 +1,168 @@ + + + + + diff --git a/components/app/Globe.vue b/components/landing/Globe.vue similarity index 74% rename from components/app/Globe.vue rename to components/landing/Globe.vue index 13f50fe6b..b4f6c6d54 100644 --- a/components/app/Globe.vue +++ b/components/landing/Globe.vue @@ -1,5 +1,5 @@ diff --git a/components/landing/Stats.vue b/components/landing/Stats.vue new file mode 100644 index 000000000..87d9fb3f6 --- /dev/null +++ b/components/landing/Stats.vue @@ -0,0 +1,27 @@ + + + diff --git a/components/landing/Users.vue b/components/landing/Users.vue new file mode 100644 index 000000000..512d73351 --- /dev/null +++ b/components/landing/Users.vue @@ -0,0 +1,27 @@ + diff --git a/components/smart/Anchor.vue b/components/smart/Anchor.vue new file mode 100644 index 000000000..949c0d198 --- /dev/null +++ b/components/smart/Anchor.vue @@ -0,0 +1,74 @@ + + + diff --git a/components/smart/ChangeLanguage.vue b/components/smart/ChangeLanguage.vue new file mode 100644 index 000000000..98d446001 --- /dev/null +++ b/components/smart/ChangeLanguage.vue @@ -0,0 +1,51 @@ + diff --git a/components/smart/Link.js b/components/smart/Link.js new file mode 100644 index 000000000..dfa08fd2f --- /dev/null +++ b/components/smart/Link.js @@ -0,0 +1,67 @@ +/* Vue 2 Functional Component: https://vuejs.org/v2/guide/render-function.html#Functional-Components */ +import { mergeData } from "vue-functional-data-merge" +import getLinkTag, { ANCHOR_TAG, FRAMEWORK_LINK } from "~/assets/js/getLinkTag" + +const SmartLink = { + functional: true, + props: { + to: { + type: String, + default: "", + }, + exact: { + type: Boolean, + default: false, + }, + blank: { + type: Boolean, + default: false, + }, + }, + // It's a convention to rename `createElement` to `h` + render(h, context) { + const tag = getLinkTag(context.props) + + // Map our attributes correctly + const attrs = {} + let on = {} + switch (tag) { + case ANCHOR_TAG: + // Map `to` prop to the correct attribute + attrs.href = context.props.to + + // Handle `blank` prop + if (context.props.blank) { + attrs.target = "_blank" + attrs.rel = "noopener" + } + + // Transform native events to regular events for HTML anchor tag + on = { ...context.data.nativeOn } + delete context.data.nativeOn + break + + case FRAMEWORK_LINK: + // Map `to` prop to the correct attribute + attrs.to = context.props.to + + // Handle `exact` prop + if (context.props.exact) { + attrs.exact = true + } + + break + + default: + break + } + + // Merge our new data with existing ones + const data = mergeData(context.data, { attrs, on }) + + // Return a new virtual node + return h(tag, data, context.children) + }, +} + +export default SmartLink diff --git a/layouts/default.vue b/layouts/default.vue index 2e9fd925b..d1a5929eb 100644 --- a/layouts/default.vue +++ b/layouts/default.vue @@ -6,7 +6,7 @@ @@ -30,7 +30,7 @@ - +