@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 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
+ };
@@ -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
+ }