@phila/phila-ui-app-footer 0.0.5
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/README.md +49 -0
- package/dist/AppFooter.css +1 -0
- package/dist/AppFooter.js +63 -0
- package/dist/AppFooter.umd.cjs +2 -0
- package/dist/AppFooter.vue.d.ts +40 -0
- package/dist/types.d.ts +13 -0
- package/package.json +48 -0
package/README.md
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
## Code Samples
|
|
2
|
+
### Props vs Slots Links
|
|
3
|
+
The footer links can be added via props using the [Navigation Links](/components/NavLink) format.
|
|
4
|
+
```html
|
|
5
|
+
<app-footer
|
|
6
|
+
:links="myFooterLinks"
|
|
7
|
+
/>
|
|
8
|
+
```
|
|
9
|
+
|
|
10
|
+
Or the links can be added using the default slot. The default slot accepts an unordered list of links.
|
|
11
|
+
```html
|
|
12
|
+
<app-footer>
|
|
13
|
+
<ul>
|
|
14
|
+
<li>
|
|
15
|
+
<a href="/about">About</a>
|
|
16
|
+
</li>
|
|
17
|
+
<li>
|
|
18
|
+
<a href="/terms-and-conditions">Terms & Conditions</a>
|
|
19
|
+
</li>
|
|
20
|
+
</ul>
|
|
21
|
+
</app-footer>
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Sticky Footer
|
|
25
|
+
The footer can be fixed to the bottom of the page, so it's always visible.
|
|
26
|
+
```html
|
|
27
|
+
<app-footer
|
|
28
|
+
:is-sticky="true"
|
|
29
|
+
/>
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
### Mobile Display
|
|
33
|
+
By default the footer is hidden on mobile devices. If the links in the footer are important, they should be added to the [Mobile Navigation](/components/MobileNav).
|
|
34
|
+
|
|
35
|
+
If the footer must be displayed on mobile, set ``is-hidden-mobile`` to ``false``.
|
|
36
|
+
```html
|
|
37
|
+
<app-footer
|
|
38
|
+
:is-hidden-mobile="false"
|
|
39
|
+
/>
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Live Examples
|
|
43
|
+
<alert type="warning">Open the iframe below in a new window as the footer is by default hidden on smaller screens</alert>
|
|
44
|
+
|
|
45
|
+
### Non-sticky, using the slot
|
|
46
|
+
<example name="AppFooter1" height="300" :options="{ horizontal: true}"></example>
|
|
47
|
+
|
|
48
|
+
### Sticky, using the link prop
|
|
49
|
+
<example name="AppFooter2" height="300" :options="{ horizontal: true}"></example>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
@font-face{font-family:Montserrat;src:local("Montserrat Regular"),local("Montserrat-Regular"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Regular.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Regular.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Italic"),local("OpenSans-Italic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Italic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Italic.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Open Sans;src:local("Open Sans Bold Italic"),local("OpenSans-BoldItalic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-BoldItalic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-BoldItalic.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Montserrat;src:local("Montserrat Bold"),local("Montserrat-Bold"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Bold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Bold.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Bold"),local("OpenSans-Bold"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Bold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Bold.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans SemiBold Italic"),local("OpenSans-SemiBoldItalic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBoldItalic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBoldItalic.woff) format("woff");font-weight:600;font-style:italic}@font-face{font-family:Open Sans;src:local("Open Sans SemiBold"),local("OpenSans-SemiBold"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBold.woff) format("woff");font-weight:600;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Regular"),local("OpenSans-Regular"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Regular.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Regular.woff) format("woff");font-weight:400;font-style:normal}#app-footer[data-v-f34d21d1]{background-color:#0f4d90;height:46px;max-height:46px;overflow:hidden;width:100%}#app-footer a[data-v-f34d21d1]{color:#fff;line-height:46px}#app-footer a[data-v-f34d21d1]:hover{color:#25cef7}#app-footer.is-sticky[data-v-f34d21d1]{position:fixed;bottom:0;z-index:99}#app-footer ul[data-v-f34d21d1]{list-style:none;padding:0;margin:0}#app-footer ul li[data-v-f34d21d1]{display:inline-block;vertical-align:middle;margin:0;padding:0}#app-footer ul li[data-v-f34d21d1]:not(:last-child):after{content:"|";margin:0 1rem;display:inline-block;position:relative;color:#fff;font-weight:700}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import "./AppFooter.css";
|
|
2
|
+
import { defineComponent as m, inject as h, computed as v, ref as y, onMounted as k, resolveComponent as _, openBlock as a, createElementBlock as c, normalizeClass as g, createElementVNode as u, Fragment as H, renderList as S, createVNode as b, mergeProps as M, renderSlot as x, createCommentVNode as B, pushScopeId as F, popScopeId as I } from "vue";
|
|
3
|
+
const N = (e) => (F("data-v-f34d21d1"), e = e(), I(), e), A = /* @__PURE__ */ N(() => /* @__PURE__ */ u("div", { class: "container" }, null, -1)), C = { class: "container has-text-centered" }, T = {
|
|
4
|
+
key: 0,
|
|
5
|
+
role: "menu",
|
|
6
|
+
class: "inline-list"
|
|
7
|
+
}, $ = /* @__PURE__ */ m({
|
|
8
|
+
__name: "AppFooter",
|
|
9
|
+
props: {
|
|
10
|
+
links: { default() {
|
|
11
|
+
return [];
|
|
12
|
+
} },
|
|
13
|
+
isSticky: { type: Boolean, default: !0 },
|
|
14
|
+
isHiddenMobile: { type: Boolean, default: !1 }
|
|
15
|
+
},
|
|
16
|
+
setup(e) {
|
|
17
|
+
const n = e, l = h("responsiveHelpers"), { responsiveState: p } = l, o = v(() => p.isMobile), i = y();
|
|
18
|
+
return k(() => {
|
|
19
|
+
var r;
|
|
20
|
+
const t = document.getElementById("app-header"), s = document.querySelector("main");
|
|
21
|
+
if (s) {
|
|
22
|
+
if (n.isSticky && i.value)
|
|
23
|
+
s.style.cssText = s.style.cssText + `padding-bottom: ${i.value.offsetHeight}px`;
|
|
24
|
+
else if (o.value && !n.isHiddenMobile || !o.value)
|
|
25
|
+
if (t) {
|
|
26
|
+
const d = t.offsetHeight + (((r = i.value) == null ? void 0 : r.offsetHeight) || 0);
|
|
27
|
+
s.style.cssText = s.style.cssText + `min-height: calc(100vh - ${d}px)`;
|
|
28
|
+
} else
|
|
29
|
+
console.warn("AppFooter: No app-header found, unable to calculate sticky footer height");
|
|
30
|
+
} else
|
|
31
|
+
console.warn("AppFooter: No main element found, unable to calculate sticky footer height");
|
|
32
|
+
}), (t, s) => {
|
|
33
|
+
const r = _("nav-link");
|
|
34
|
+
return o.value && !t.isHiddenMobile || !o.value ? (a(), c("footer", {
|
|
35
|
+
key: 0,
|
|
36
|
+
id: "app-footer",
|
|
37
|
+
ref_key: "footer",
|
|
38
|
+
ref: i,
|
|
39
|
+
class: g({ "is-sticky": t.isSticky })
|
|
40
|
+
}, [
|
|
41
|
+
A,
|
|
42
|
+
u("div", C, [
|
|
43
|
+
t.links.length > 0 ? (a(), c("ul", T, [
|
|
44
|
+
(a(!0), c(H, null, S(t.links, (d, f) => (a(), c("li", {
|
|
45
|
+
key: `fl-${f}`,
|
|
46
|
+
role: "none"
|
|
47
|
+
}, [
|
|
48
|
+
b(r, M({ ref_for: !0 }, d, { role: "menuitem" }), null, 16)
|
|
49
|
+
]))), 128))
|
|
50
|
+
])) : x(t.$slots, "default", { key: 1 }, void 0, !0)
|
|
51
|
+
])
|
|
52
|
+
], 2)) : B("", !0);
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}), w = (e, n) => {
|
|
56
|
+
const l = e.__vccOpts || e;
|
|
57
|
+
for (const [p, o] of n)
|
|
58
|
+
l[p] = o;
|
|
59
|
+
return l;
|
|
60
|
+
}, j = /* @__PURE__ */ w($, [["__scopeId", "data-v-f34d21d1"]]);
|
|
61
|
+
export {
|
|
62
|
+
j as default
|
|
63
|
+
};
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
(function(e,n){typeof exports=="object"&&typeof module<"u"?module.exports=n(require("vue")):typeof define=="function"&&define.amd?define(["vue"],n):(e=typeof globalThis<"u"?globalThis:e||self,e.AppFooter=n(e.Vue))})(this,function(e){"use strict";var n=document.createElement("style");n.textContent=`@font-face{font-family:Montserrat;src:local("Montserrat Regular"),local("Montserrat-Regular"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Regular.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Regular.woff) format("woff");font-weight:400;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Italic"),local("OpenSans-Italic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Italic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Italic.woff) format("woff");font-weight:400;font-style:italic}@font-face{font-family:Open Sans;src:local("Open Sans Bold Italic"),local("OpenSans-BoldItalic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-BoldItalic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-BoldItalic.woff) format("woff");font-weight:700;font-style:italic}@font-face{font-family:Montserrat;src:local("Montserrat Bold"),local("Montserrat-Bold"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Bold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/Montserrat/Montserrat-Bold.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Bold"),local("OpenSans-Bold"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Bold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Bold.woff) format("woff");font-weight:700;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans SemiBold Italic"),local("OpenSans-SemiBoldItalic"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBoldItalic.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBoldItalic.woff) format("woff");font-weight:600;font-style:italic}@font-face{font-family:Open Sans;src:local("Open Sans SemiBold"),local("OpenSans-SemiBold"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBold.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-SemiBold.woff) format("woff");font-weight:600;font-style:normal}@font-face{font-family:Open Sans;src:local("Open Sans Regular"),local("OpenSans-Regular"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Regular.woff2) format("woff2"),url(https://www.phila.gov/assets/fonts/OpenSans/OpenSans-Regular.woff) format("woff");font-weight:400;font-style:normal}#app-footer[data-v-f34d21d1]{background-color:#0f4d90;height:46px;max-height:46px;overflow:hidden;width:100%}#app-footer a[data-v-f34d21d1]{color:#fff;line-height:46px}#app-footer a[data-v-f34d21d1]:hover{color:#25cef7}#app-footer.is-sticky[data-v-f34d21d1]{position:fixed;bottom:0;z-index:99}#app-footer ul[data-v-f34d21d1]{list-style:none;padding:0;margin:0}#app-footer ul li[data-v-f34d21d1]{display:inline-block;vertical-align:middle;margin:0;padding:0}#app-footer ul li[data-v-f34d21d1]:not(:last-child):after{content:"|";margin:0 1rem;display:inline-block;position:relative;color:#fff;font-weight:700}
|
|
2
|
+
`,document.head.appendChild(n);const d=(t=>(e.pushScopeId("data-v-f34d21d1"),t=t(),e.popScopeId(),t))(()=>e.createElementVNode("div",{class:"container"},null,-1)),w={class:"container has-text-centered"},m={key:0,role:"menu",class:"inline-list"};return((t,l)=>{const f=t.__vccOpts||t;for(const[p,a]of l)f[p]=a;return f})(e.defineComponent({__name:"AppFooter",props:{links:{default(){return[]}},isSticky:{type:Boolean,default:!0},isHiddenMobile:{type:Boolean,default:!1}},setup(t){const l=t,f=e.inject("responsiveHelpers"),{responsiveState:p}=f,a=e.computed(()=>p.isMobile),r=e.ref();return e.onMounted(()=>{var i;const o=document.getElementById("app-header"),s=document.querySelector("main");if(s){if(l.isSticky&&r.value)s.style.cssText=s.style.cssText+`padding-bottom: ${r.value.offsetHeight}px`;else if(a.value&&!l.isHiddenMobile||!a.value)if(o){const c=o.offsetHeight+(((i=r.value)==null?void 0:i.offsetHeight)||0);s.style.cssText=s.style.cssText+`min-height: calc(100vh - ${c}px)`}else console.warn("AppFooter: No app-header found, unable to calculate sticky footer height")}else console.warn("AppFooter: No main element found, unable to calculate sticky footer height")}),(o,s)=>{const i=e.resolveComponent("nav-link");return a.value&&!o.isHiddenMobile||!a.value?(e.openBlock(),e.createElementBlock("footer",{key:0,id:"app-footer",ref_key:"footer",ref:r,class:e.normalizeClass({"is-sticky":o.isSticky})},[d,e.createElementVNode("div",w,[o.links.length>0?(e.openBlock(),e.createElementBlock("ul",m,[(e.openBlock(!0),e.createElementBlock(e.Fragment,null,e.renderList(o.links,(c,h)=>(e.openBlock(),e.createElementBlock("li",{key:`fl-${h}`,role:"none"},[e.createVNode(i,e.mergeProps({ref_for:!0},c,{role:"menuitem"}),null,16)]))),128))])):e.renderSlot(o.$slots,"default",{key:1},void 0,!0)])],2)):e.createCommentVNode("",!0)}}}),[["__scopeId","data-v-f34d21d1"]])});
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { AppFooterProps } from './types';
|
|
2
|
+
|
|
3
|
+
declare const _default: __VLS_WithTemplateSlots<import('vue').DefineComponent<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<AppFooterProps>, {
|
|
4
|
+
links(): never[];
|
|
5
|
+
isSticky: boolean;
|
|
6
|
+
isHiddenMobile: boolean;
|
|
7
|
+
}>, {}, unknown, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<AppFooterProps>, {
|
|
8
|
+
links(): never[];
|
|
9
|
+
isSticky: boolean;
|
|
10
|
+
isHiddenMobile: boolean;
|
|
11
|
+
}>>>, {
|
|
12
|
+
links: import('@phila/phila-ui-nav-link').NavLinkProps[];
|
|
13
|
+
isSticky: boolean;
|
|
14
|
+
isHiddenMobile: boolean;
|
|
15
|
+
}, {}>, {
|
|
16
|
+
default?(_: {}): any;
|
|
17
|
+
}>;
|
|
18
|
+
export default _default;
|
|
19
|
+
type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
|
|
20
|
+
type __VLS_TypePropsToRuntimeProps<T> = {
|
|
21
|
+
[K in keyof T]-?: {} extends Pick<T, K> ? {
|
|
22
|
+
type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
|
|
23
|
+
} : {
|
|
24
|
+
type: import('vue').PropType<T[K]>;
|
|
25
|
+
required: true;
|
|
26
|
+
};
|
|
27
|
+
};
|
|
28
|
+
type __VLS_WithDefaults<P, D> = {
|
|
29
|
+
[K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
|
|
30
|
+
default: D[K];
|
|
31
|
+
}> : P[K];
|
|
32
|
+
};
|
|
33
|
+
type __VLS_Prettify<T> = {
|
|
34
|
+
[K in keyof T]: T[K];
|
|
35
|
+
} & {};
|
|
36
|
+
type __VLS_WithTemplateSlots<T, S> = T & {
|
|
37
|
+
new (): {
|
|
38
|
+
$slots: S;
|
|
39
|
+
};
|
|
40
|
+
};
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { default as AppFooter } from './AppFooter.vue';
|
|
2
|
+
import { NavLinkProps } from '@phila/phila-ui-nav-link';
|
|
3
|
+
|
|
4
|
+
declare module "@vue/runtime-core" {
|
|
5
|
+
interface GlobalComponents {
|
|
6
|
+
AppFooter: typeof AppFooter;
|
|
7
|
+
}
|
|
8
|
+
}
|
|
9
|
+
export interface AppFooterProps {
|
|
10
|
+
links: NavLinkProps[];
|
|
11
|
+
isSticky?: boolean;
|
|
12
|
+
isHiddenMobile?: boolean;
|
|
13
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@phila/phila-ui-app-footer",
|
|
3
|
+
"private": false,
|
|
4
|
+
"version": "0.0.5",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"files": [
|
|
7
|
+
"dist"
|
|
8
|
+
],
|
|
9
|
+
"main": "./dist/AppFooter.umd.cjs",
|
|
10
|
+
"module": "./dist/AppFooter.js",
|
|
11
|
+
"types": "./dist/types.d.ts",
|
|
12
|
+
"exports": {
|
|
13
|
+
".": {
|
|
14
|
+
"import": {
|
|
15
|
+
"types": "./dist/types.d.ts",
|
|
16
|
+
"default": "./dist/AppFooter.js"
|
|
17
|
+
},
|
|
18
|
+
"require": "./dist/AppFooter.umd.cjs"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"scripts": {
|
|
22
|
+
"dev": "vite",
|
|
23
|
+
"prepublish": "npm i && npm run build",
|
|
24
|
+
"build": "vue-tsc && vite build",
|
|
25
|
+
"preview": "vite preview"
|
|
26
|
+
},
|
|
27
|
+
"dependencies": {
|
|
28
|
+
"@phila/phila-ui-core": "^1.0.12",
|
|
29
|
+
"@phila/phila-ui-nav-link": "0.0.4",
|
|
30
|
+
"bulma": "^0.9.4",
|
|
31
|
+
"vue": "^3.3.8"
|
|
32
|
+
},
|
|
33
|
+
"devDependencies": {
|
|
34
|
+
"@types/node": "^20.10.3",
|
|
35
|
+
"@vitejs/plugin-vue": "^4.5.0",
|
|
36
|
+
"sass": "^1.69.5",
|
|
37
|
+
"typescript": "^5.2.2",
|
|
38
|
+
"vite": "^5.0.0",
|
|
39
|
+
"vite-plugin-dts": "^3.6.4",
|
|
40
|
+
"vite-plugin-lib-inject-css": "^1.3.0",
|
|
41
|
+
"vue-tsc": "^1.8.22"
|
|
42
|
+
},
|
|
43
|
+
"publishConfig": {
|
|
44
|
+
"registry": "https://registry.npmjs.com/",
|
|
45
|
+
"access": "public"
|
|
46
|
+
},
|
|
47
|
+
"gitHead": "84a4bd30a82f912e4d3a9eacd9cc197746be9fc8"
|
|
48
|
+
}
|