@phila/phila-ui-tooltip 0.0.15 → 0.1.0-beta.0

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 CHANGED
@@ -1,24 +1,81 @@
1
+ # Tooltip Component
2
+
3
+ <!-- status-badge-start -->
4
+
5
+ ![Status: In Progress](https://img.shields.io/badge/-In%20Progress-yellow)
6
+
7
+ <!-- status-badge-end -->
8
+
9
+ A simple, customizable Vue 3. Tooltip component built with TypeScript and Vite.
10
+ Tooltip component for displaying simple or rich content on hover of an element
11
+
12
+ ## Features
13
+
14
+ - 🎯 TypeScript support with full type definitions
15
+
16
+ ## Installation
17
+
18
+ ```bash
19
+ npm install @phila/phila-ui-tooltip
20
+ # or
21
+ yarn add @phila/phila-ui-tooltip
22
+ # or
23
+ pnpm add @phila/phila-ui-tooltip
24
+ ```
25
+
1
26
  ## Usage
2
- ### Import single component
3
- ```js
4
- import { Callout } from '@phila/phila-ui';
5
27
 
6
- //register it locally...
7
- components: {
8
- Callout,
9
- }
28
+ ```vue
29
+ <script setup lang="ts">
30
+ import { Tooltip } from "@phila/phila-ui-tooltip";
31
+ </script>
32
+ <template>...Add basic component template here...</template>
33
+ ```
34
+
35
+ ## Props
36
+
37
+ | Prop | Type | Default | Description |
38
+ | ---- | ---- | ------- | ----------- |
39
+
40
+ | ...Add props here...
10
41
 
11
- //... or register it globally
12
- Vue.component('callout', Callout);
42
+ ## Events
43
+
44
+ | Event | Payload | Description |
45
+ | ----- | ------- | ----------- |
46
+
47
+ | ...Add events here...
48
+
49
+ ## Examples
50
+
51
+ ...Add examples here...
52
+
53
+ ## Development
54
+
55
+ ### Install Dependencies
56
+
57
+ ```bash
58
+ pnpm install
13
59
  ```
14
60
 
15
- ## Code Samples
16
- ### Basic tooltip with dark mode enabled (default)
61
+ ### Run Demo
17
62
 
18
- ```html
19
- <tooltip message="My tooltip message" />
63
+ ```bash
64
+ pnpm dev
20
65
  ```
21
- ### Basic tooltip with light mode enabled
22
- ```html
23
- <tooltip message="My tooltip message" mode="light" />
66
+
67
+ ### Build Library
68
+
69
+ ```bash
70
+ pnpm build
24
71
  ```
72
+
73
+ ### Type Check
74
+
75
+ ```bash
76
+ pnpm type-check
77
+ ```
78
+
79
+ ## License
80
+
81
+ MIT
@@ -1,36 +1,34 @@
1
- import { TooltipProps } from './types';
2
-
1
+ import { TooltipProps, TooltipPlacement } from './index';
3
2
  declare function __VLS_template(): {
4
- default?(_: {}): any;
5
- };
6
- declare const __VLS_component: import('vue').DefineComponent<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<TooltipProps>, {
7
- mode: string;
8
- }>>, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<import('vue').ExtractPropTypes<__VLS_WithDefaults<__VLS_TypePropsToRuntimeProps<TooltipProps>, {
9
- mode: string;
10
- }>>> & Readonly<{}>, {
11
- mode: "light" | "dark";
12
- }, {}, {}, {}, string, import('vue').ComponentProvideOptions, true, {}, any>;
13
- declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, ReturnType<typeof __VLS_template>>;
14
- export default _default;
15
- type __VLS_NonUndefinedable<T> = T extends undefined ? never : T;
16
- type __VLS_TypePropsToRuntimeProps<T> = {
17
- [K in keyof T]-?: {} extends Pick<T, K> ? {
18
- type: import('vue').PropType<__VLS_NonUndefinedable<T[K]>>;
19
- } : {
20
- type: import('vue').PropType<T[K]>;
21
- required: true;
3
+ attrs: Partial<{}>;
4
+ slots: {
5
+ default?(_: {
6
+ tooltipId: string;
7
+ }): any;
8
+ body?(_: {}): any;
22
9
  };
10
+ refs: {
11
+ wrapperEl: HTMLSpanElement;
12
+ positionerEl: HTMLSpanElement;
13
+ };
14
+ rootEl: any;
23
15
  };
24
- type __VLS_WithDefaults<P, D> = {
25
- [K in keyof Pick<P, keyof P>]: K extends keyof D ? __VLS_Prettify<P[K] & {
26
- default: D[K];
27
- }> : P[K];
28
- };
29
- type __VLS_Prettify<T> = {
30
- [K in keyof T]: T[K];
31
- } & {};
16
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
17
+ declare const __VLS_component: import('vue').DefineComponent<TooltipProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {}, string, import('vue').PublicProps, Readonly<TooltipProps> & Readonly<{}>, {
18
+ type: import('./index').TooltipType;
19
+ color: import('./index').TooltipColor;
20
+ tail: boolean;
21
+ placement: TooltipPlacement;
22
+ trigger: import('./index').TooltipTrigger;
23
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {
24
+ wrapperEl: HTMLSpanElement;
25
+ positionerEl: HTMLSpanElement;
26
+ }, any>;
27
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
28
+ export default _default;
32
29
  type __VLS_WithTemplateSlots<T, S> = T & {
33
30
  new (): {
34
31
  $slots: S;
35
32
  };
36
33
  };
34
+ //# sourceMappingURL=Tooltip.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Tooltip.vue.d.ts","sourceRoot":"","sources":["../src/Tooltip.vue"],"names":[],"mappings":"AA8KA,OAAO,KAAK,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAC;AA2F9D,iBAAS,cAAc;WAgFT,OAAO,IAA6B;;;;YAbrB,GAAG;sBACN,GAAG;;;;;;;EAiB5B;AAoBD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;;OAQnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { TooltipBubbleProps } from './index';
2
+ interface BubbleProps extends TooltipBubbleProps {
3
+ id?: string;
4
+ }
5
+ declare function __VLS_template(): {
6
+ attrs: Partial<{}>;
7
+ slots: {
8
+ default?(_: {}): any;
9
+ default?(_: {}): any;
10
+ };
11
+ refs: {};
12
+ rootEl: HTMLDivElement;
13
+ };
14
+ type __VLS_TemplateResult = ReturnType<typeof __VLS_template>;
15
+ declare const __VLS_component: import('vue').DefineComponent<BubbleProps, {}, {}, {}, {}, import('vue').ComponentOptionsMixin, import('vue').ComponentOptionsMixin, {
16
+ dismiss: () => any;
17
+ }, string, import('vue').PublicProps, Readonly<BubbleProps> & Readonly<{
18
+ onDismiss?: (() => any) | undefined;
19
+ }>, {
20
+ type: import('./index').TooltipType;
21
+ color: import('./index').TooltipColor;
22
+ tail: boolean;
23
+ placement: import('./index').TooltipPlacement;
24
+ dismissable: boolean;
25
+ }, {}, {}, {}, string, import('vue').ComponentProvideOptions, false, {}, HTMLDivElement>;
26
+ declare const _default: __VLS_WithTemplateSlots<typeof __VLS_component, __VLS_TemplateResult["slots"]>;
27
+ export default _default;
28
+ type __VLS_WithTemplateSlots<T, S> = T & {
29
+ new (): {
30
+ $slots: S;
31
+ };
32
+ };
33
+ //# sourceMappingURL=TooltipBubble.vue.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"TooltipBubble.vue.d.ts","sourceRoot":"","sources":["../src/TooltipBubble.vue"],"names":[],"mappings":"AAsLA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAC;AAElD,UAAU,WAAY,SAAQ,kBAAkB;IAC9C,EAAE,CAAC,EAAE,MAAM,CAAC;CACb;AAmCD,iBAAS,cAAc;WAwIT,OAAO,IAA6B;;yBAXrB,GAAG;yBACF,GAAG;;;;EAehC;AAaD,KAAK,oBAAoB,GAAG,UAAU,CAAC,OAAO,cAAc,CAAC,CAAC;AAC9D,QAAA,MAAM,eAAe;;;;;;;;;;wFASnB,CAAC;wBACkB,uBAAuB,CAAC,OAAO,eAAe,EAAE,oBAAoB,CAAC,OAAO,CAAC,CAAC;AAAnG,wBAAoG;AAapG,KAAK,uBAAuB,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG;IACxC,QAAO;QACN,MAAM,EAAE,CAAC,CAAC;KAEV,CAAA;CACD,CAAC"}
package/dist/index.css ADDED
@@ -0,0 +1 @@
1
+ .tooltip[data-v-0155bbdd]{position:relative;display:inline-flex;flex-direction:column;align-items:flex-start;border-radius:var(--border-radius-xs);filter:drop-shadow(0px 1px 2px rgba(0,0,0,.3)) drop-shadow(0px 1px 3px rgba(0,0,0,.15));--tooltip-bg: var(--Schemes-On-Primary);background-color:var(--tooltip-bg);color:var(--Schemes-On-Background)}.tooltip.tooltip--grey[data-v-0155bbdd]{--tooltip-bg: var(--Schemes-Surface-Container-Lowest);color:var(--Schemes-On-Surface)}.tooltip.tooltip--plain[data-v-0155bbdd]{--tail-height: 10px;padding:var(--spacing-2xs) var(--spacing-xs);justify-content:center}.tooltip.tooltip--rich[data-v-0155bbdd]{--tail-height: 12px;padding:var(--spacing-s) var(--spacing-m);width:max-content;min-width:11.25rem;max-width:25rem;gap:var(--spacing-xs)}.tooltip .tooltip__tail[data-v-0155bbdd]{position:absolute;width:20px;height:var(--tail-height);background-color:var(--tooltip-bg)}.tooltip.tooltip--top-left .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--top-right .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--top-center .tooltip__tail[data-v-0155bbdd]{clip-path:polygon(0 0,100% 0,50% 100%);bottom:calc(-1 * var(--tail-height) + 1px)}.tooltip.tooltip--bottom-left .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--bottom-right .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--bottom-center .tooltip__tail[data-v-0155bbdd]{clip-path:polygon(50% 0,0 100%,100% 100%);top:calc(-1 * var(--tail-height) + 1px)}.tooltip.tooltip--top-left .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--bottom-left .tooltip__tail[data-v-0155bbdd]{left:8px}.tooltip.tooltip--top-right .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--bottom-right .tooltip__tail[data-v-0155bbdd]{right:8px}.tooltip.tooltip--top-center .tooltip__tail[data-v-0155bbdd],.tooltip.tooltip--bottom-center .tooltip__tail[data-v-0155bbdd]{left:50%;transform:translate(-50%)}.tooltip__plain-row[data-v-0155bbdd],.tooltip__title-row[data-v-0155bbdd]{display:flex;align-items:flex-start;justify-content:space-between;gap:var(--spacing-xs);width:100%}.tooltip__title-row h6[data-v-0155bbdd]{flex:1}.tooltip__dismiss[data-v-0155bbdd]{margin-left:auto;flex-shrink:0}.tooltip-trigger[data-v-5dcd06cf]{position:relative;display:inline-block}.tooltip-trigger__positioner[data-v-5dcd06cf]{position:absolute;z-index:1000}.tooltip-trigger__positioner.tooltip-trigger__positioner--top-left[data-v-5dcd06cf]{bottom:100%;left:-8px;padding-bottom:var(--positioner-gap)}.tooltip-trigger__positioner.tooltip-trigger__positioner--top-right[data-v-5dcd06cf]{bottom:100%;right:-8px;padding-bottom:var(--positioner-gap)}.tooltip-trigger__positioner.tooltip-trigger__positioner--top-center[data-v-5dcd06cf]{bottom:100%;left:50%;transform:translate(-50%);padding-bottom:var(--positioner-gap)}.tooltip-trigger__positioner.tooltip-trigger__positioner--bottom-left[data-v-5dcd06cf]{top:100%;left:-8px;padding-top:var(--positioner-gap)}.tooltip-trigger__positioner.tooltip-trigger__positioner--bottom-right[data-v-5dcd06cf]{top:100%;right:-8px;padding-top:var(--positioner-gap)}.tooltip-trigger__positioner.tooltip-trigger__positioner--bottom-center[data-v-5dcd06cf]{top:100%;left:50%;transform:translate(-50%);padding-top:var(--positioner-gap)}
@@ -0,0 +1,27 @@
1
+ import { BaseProps } from '@phila/phila-ui-core';
2
+ export { default as Tooltip } from './Tooltip.vue';
3
+ export { default as TooltipBubble } from './TooltipBubble.vue';
4
+ export type TooltipType = "plain" | "rich";
5
+ export type TooltipColor = "default" | "grey";
6
+ export type TooltipTrigger = "hover" | "click";
7
+ /** Placement of the bubble relative to the trigger element. Use `"auto"` to detect based on available viewport space. */
8
+ export type TooltipPlacement = "auto" | "top-left" | "top-center" | "top-right" | "bottom-left" | "bottom-center" | "bottom-right";
9
+ export interface TooltipBubbleProps extends BaseProps {
10
+ /** Plain tooltips show a single line of text. Rich tooltips can include a title, tag, body, and actions. */
11
+ type?: TooltipType;
12
+ /** White (default) or grey surface background. */
13
+ color?: TooltipColor;
14
+ /** Whether to show the directional tail pointer. */
15
+ tail?: boolean;
16
+ /** Where the bubble appears relative to the trigger. Only used when `tail` is true. */
17
+ placement?: TooltipPlacement;
18
+ /** Title text shown at the top of a rich tooltip. */
19
+ title?: string;
20
+ /** When true, renders an X button that emits `dismiss`. Primarily used with `trigger="click"`. */
21
+ dismissable?: boolean;
22
+ }
23
+ export interface TooltipProps extends TooltipBubbleProps {
24
+ /** How the tooltip is triggered. `"hover"` shows on mouseenter/focus; `"click"` toggles on click. */
25
+ trigger?: TooltipTrigger;
26
+ }
27
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,OAAO,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE/D,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,MAAM,CAAC;AAC3C,MAAM,MAAM,YAAY,GAAG,SAAS,GAAG,MAAM,CAAC;AAC9C,MAAM,MAAM,cAAc,GAAG,OAAO,GAAG,OAAO,CAAC;AAC/C,yHAAyH;AACzH,MAAM,MAAM,gBAAgB,GACxB,MAAM,GACN,UAAU,GACV,YAAY,GACZ,WAAW,GACX,aAAa,GACb,eAAe,GACf,cAAc,CAAC;AAEnB,MAAM,WAAW,kBAAmB,SAAQ,SAAS;IACnD,4GAA4G;IAC5G,IAAI,CAAC,EAAE,WAAW,CAAC;IACnB,kDAAkD;IAClD,KAAK,CAAC,EAAE,YAAY,CAAC;IACrB,oDAAoD;IACpD,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uFAAuF;IACvF,SAAS,CAAC,EAAE,gBAAgB,CAAC;IAC7B,qDAAqD;IACrD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kGAAkG;IAClG,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,YAAa,SAAQ,kBAAkB;IACtD,qGAAqG;IACrG,OAAO,CAAC,EAAE,cAAc,CAAC;CAC1B"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});require('./index.css');const e=require("vue"),d=require("@phila/phila-ui-core"),z=["disabled"],y=e.defineComponent({inheritAttrs:!1,__name:"PhlButton",props:{href:{},to:{},target:{},rel:{},disabled:{type:Boolean,default:!1},clickTarget:{},variant:{default:"primary"},size:{default:"medium"},iconOnly:{type:Boolean,default:!1},iconRight:{type:Boolean},text:{},className:{},iconDefinition:{},iconClass:{},src:{},svgRaw:{}},setup(o){const t=o,a=l=>"href"in l&&l.href!==void 0||"to"in l&&l.to!==void 0,i=e.computed(()=>d.cn("phila-button",`phila-button--${t.variant}`,t.size&&`is-${t.size}`,t.iconOnly&&"icon-button",t.iconOnly&&t.variant==="standard"&&"icon-button--standard",t.className)),n=e.computed(()=>a(t)?"to"in t&&t.to!==void 0?{to:t.to,disabled:t.disabled,className:i.value}:{href:t.href,target:t.target,rel:t.rel,disabled:t.disabled,className:i.value}:{}),r=e.computed(()=>({iconDefinition:t.iconDefinition,iconClass:t.iconClass,src:t.src,iconRight:t.iconRight,iconOnly:t.iconOnly,text:t.text,size:t.size}));return(l,m)=>a(t)?(e.openBlock(),e.createBlock(e.unref(d.BaseLink),e.mergeProps({key:0},{...n.value,...l.$attrs},{role:"button"}),{default:e.withCtx(()=>[e.createVNode(e.unref(d.ActionContent),e.normalizeProps(e.guardReactiveProps(r.value)),{default:e.withCtx(()=>[e.renderSlot(l.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.text),1)])]),_:3},16)]),_:3},16)):(e.openBlock(),e.createElementBlock("button",e.mergeProps({key:1,type:"button",disabled:t.disabled,class:i.value},l.$attrs),[e.createVNode(e.unref(d.ActionContent),e.normalizeProps(e.guardReactiveProps(r.value)),{default:e.withCtx(()=>[e.renderSlot(l.$slots,"default",{},()=>[e.createTextVNode(e.toDisplayString(t.text),1)])]),_:3},16)],16,z))}});var B={prefix:"fas",iconName:"xmark",icon:[384,512,[128473,10005,10006,10060,215,"close","multiply","remove","times"],"f00d","M55.1 73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L147.2 256 9.9 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192.5 301.3 329.9 438.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.8 256 375.1 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192.5 210.7 55.1 73.4z"]};const P=["id"],S={key:0,class:"tooltip__tail","aria-hidden":"true"},V={key:1,class:"tooltip__plain-row has-text-body-small"},T={key:0,class:"tooltip__title-row"},D={key:0},L=e.defineComponent({__name:"TooltipBubble",props:{id:{},type:{default:"plain"},color:{default:"default"},tail:{type:Boolean,default:!1},placement:{default:"top-center"},title:{},dismissable:{type:Boolean,default:!1},className:{}},emits:["dismiss"],setup(o){const t=o,a=e.computed(()=>d.cn("tooltip","content","resets-link-colors",`tooltip--${t.type}`,`tooltip--${t.color}`,t.tail&&`tooltip--${t.placement}`,t.className));return(i,n)=>(e.openBlock(),e.createElementBlock("div",{id:o.id,class:e.normalizeClass(a.value),role:"tooltip"},[o.tail?(e.openBlock(),e.createElementBlock("div",S)):e.createCommentVNode("",!0),o.type==="plain"?(e.openBlock(),e.createElementBlock("div",V,[e.renderSlot(i.$slots,"default",{},void 0,!0),o.dismissable?(e.openBlock(),e.createBlock(e.unref(y),{key:0,class:"tooltip__dismiss",variant:"standard",size:"extra-small","icon-only":!0,"icon-definition":e.unref(B),"aria-label":"Dismiss tooltip",onClick:n[0]||(n[0]=r=>i.$emit("dismiss"))},null,8,["icon-definition"])):e.createCommentVNode("",!0)])):(e.openBlock(),e.createElementBlock(e.Fragment,{key:2},[o.title||o.dismissable?(e.openBlock(),e.createElementBlock("div",T,[o.title?(e.openBlock(),e.createElementBlock("h6",D,e.toDisplayString(o.title),1)):e.createCommentVNode("",!0),o.dismissable?(e.openBlock(),e.createBlock(e.unref(y),{key:1,class:"tooltip__dismiss",variant:"standard",size:"extra-small","icon-only":!0,"icon-definition":e.unref(B),"aria-label":"Dismiss tooltip",onClick:n[1]||(n[1]=r=>i.$emit("dismiss"))},null,8,["icon-definition"])):e.createCommentVNode("",!0)])):e.createCommentVNode("",!0),e.renderSlot(i.$slots,"default",{},void 0,!0)],64))],10,P))}}),h=(o,t)=>{const a=o.__vccOpts||o;for(const[i,n]of t)a[i]=n;return a},C=h(L,[["__scopeId","data-v-0155bbdd"]]),R=e.defineComponent({__name:"Tooltip",props:{trigger:{default:"hover"},type:{default:"plain"},color:{default:"default"},tail:{type:Boolean,default:!1},placement:{default:"auto"},title:{},dismissable:{type:Boolean},className:{}},setup(o){const t=o,a=e.useId(),i=e.ref(!1),n=e.ref(null),r=e.ref(null),l=e.ref("top-center"),m=()=>{const s=n.value?.getBoundingClientRect();if(!s)return"top-center";const{innerWidth:u,innerHeight:N}=window,k=s.top,_=N-s.bottom,b=r.value?.firstElementChild?.getBoundingClientRect().height??0,w=(b>0?k>=b:k>=_)?"top":"bottom",g=s.left+s.width/2,x=g<u/3?"left":g>u*2/3?"right":"center";return`${w}-${x}`},f=s=>{s.key==="Escape"&&c()},v=s=>{n.value&&!n.value.contains(s.target)&&c()},p=()=>{t.placement==="auto"?l.value=m():l.value=t.placement,i.value=!0,document.addEventListener("keydown",f),t.trigger==="click"&&document.addEventListener("click",v)},c=()=>{i.value=!1,document.removeEventListener("keydown",f),document.removeEventListener("click",v)},$=()=>{i.value?c():p()};e.onUnmounted(c);const E=e.computed(()=>({type:t.type,color:t.color,tail:t.tail,placement:l.value,title:t.title,dismissable:t.dismissable}));return(s,u)=>(e.openBlock(),e.createElementBlock("span",e.mergeProps({ref_key:"wrapperEl",ref:n,class:e.unref(d.cn)("tooltip-trigger",t.className)},o.trigger==="click"?{onClick:$}:{onMouseenter:p,onMouseleave:c,onFocusin:p,onFocusout:c}),[e.renderSlot(s.$slots,"default",{tooltipId:e.unref(a)},void 0,!0),e.createElementVNode("span",{ref_key:"positionerEl",ref:r,class:e.normalizeClass(["tooltip-trigger__positioner",`tooltip-trigger__positioner--${l.value}`]),style:e.normalizeStyle({visibility:i.value?"visible":"hidden","--positioner-gap":o.tail?"var(--spacing-l)":"0.5rem"}),onClick:u[0]||(u[0]=e.withModifiers(()=>{},["stop"]))},[e.createVNode(C,e.mergeProps(E.value,{id:e.unref(a),onDismiss:c}),{default:e.withCtx(()=>[e.renderSlot(s.$slots,"body",{},void 0,!0)]),_:3},16,["id"])],6)],16))}}),O=h(R,[["__scopeId","data-v-5dcd06cf"]]);exports.Tooltip=O;exports.TooltipBubble=C;
package/dist/index.mjs ADDED
@@ -0,0 +1,237 @@
1
+ import { defineComponent as B, computed as v, createBlock as h, createElementBlock as c, openBlock as n, unref as r, mergeProps as g, withCtx as y, createVNode as $, normalizeProps as R, guardReactiveProps as D, renderSlot as m, createTextVNode as O, toDisplayString as _, normalizeClass as V, createCommentVNode as f, Fragment as X, useId as j, ref as b, onUnmounted as q, createElementVNode as G, withModifiers as J, normalizeStyle as K } from "vue";
2
+ import { cn as C, BaseLink as Q, ActionContent as P } from "@phila/phila-ui-core";
3
+ import './index.css';const Y = ["disabled"], T = /* @__PURE__ */ B({
4
+ inheritAttrs: !1,
5
+ __name: "PhlButton",
6
+ props: {
7
+ href: {},
8
+ to: {},
9
+ target: {},
10
+ rel: {},
11
+ disabled: { type: Boolean, default: !1 },
12
+ clickTarget: {},
13
+ variant: { default: "primary" },
14
+ size: { default: "medium" },
15
+ iconOnly: { type: Boolean, default: !1 },
16
+ iconRight: { type: Boolean },
17
+ text: {},
18
+ className: {},
19
+ iconDefinition: {},
20
+ iconClass: {},
21
+ src: {},
22
+ svgRaw: {}
23
+ },
24
+ setup(t) {
25
+ const e = t, a = (o) => "href" in o && o.href !== void 0 || "to" in o && o.to !== void 0, i = v(() => C(
26
+ "phila-button",
27
+ `phila-button--${e.variant}`,
28
+ e.size && `is-${e.size}`,
29
+ e.iconOnly && "icon-button",
30
+ e.iconOnly && e.variant === "standard" && "icon-button--standard",
31
+ e.className
32
+ )), l = v(() => a(e) ? "to" in e && e.to !== void 0 ? {
33
+ to: e.to,
34
+ disabled: e.disabled,
35
+ className: i.value
36
+ } : {
37
+ href: e.href,
38
+ target: e.target,
39
+ rel: e.rel,
40
+ disabled: e.disabled,
41
+ className: i.value
42
+ } : {}), d = v(
43
+ () => ({
44
+ iconDefinition: e.iconDefinition,
45
+ iconClass: e.iconClass,
46
+ src: e.src,
47
+ iconRight: e.iconRight,
48
+ iconOnly: e.iconOnly,
49
+ text: e.text,
50
+ size: e.size
51
+ })
52
+ );
53
+ return (o, w) => a(e) ? (n(), h(r(Q), g({ key: 0 }, { ...l.value, ...o.$attrs }, { role: "button" }), {
54
+ default: y(() => [
55
+ $(r(P), R(D(d.value)), {
56
+ default: y(() => [
57
+ m(o.$slots, "default", {}, () => [
58
+ O(_(e.text), 1)
59
+ ])
60
+ ]),
61
+ _: 3
62
+ }, 16)
63
+ ]),
64
+ _: 3
65
+ }, 16)) : (n(), c("button", g({
66
+ key: 1,
67
+ type: "button",
68
+ disabled: e.disabled,
69
+ class: i.value
70
+ }, o.$attrs), [
71
+ $(r(P), R(D(d.value)), {
72
+ default: y(() => [
73
+ m(o.$slots, "default", {}, () => [
74
+ O(_(e.text), 1)
75
+ ])
76
+ ]),
77
+ _: 3
78
+ }, 16)
79
+ ], 16, Y));
80
+ }
81
+ });
82
+ var A = {
83
+ prefix: "fas",
84
+ iconName: "xmark",
85
+ icon: [384, 512, [128473, 10005, 10006, 10060, 215, "close", "multiply", "remove", "times"], "f00d", "M55.1 73.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3L147.2 256 9.9 393.4c-12.5 12.5-12.5 32.8 0 45.3s32.8 12.5 45.3 0L192.5 301.3 329.9 438.6c12.5 12.5 32.8 12.5 45.3 0s12.5-32.8 0-45.3L237.8 256 375.1 118.6c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L192.5 210.7 55.1 73.4z"]
86
+ };
87
+ const Z = ["id"], ee = {
88
+ key: 0,
89
+ class: "tooltip__tail",
90
+ "aria-hidden": "true"
91
+ }, te = {
92
+ key: 1,
93
+ class: "tooltip__plain-row has-text-body-small"
94
+ }, ie = {
95
+ key: 0,
96
+ class: "tooltip__title-row"
97
+ }, oe = { key: 0 }, le = /* @__PURE__ */ B({
98
+ __name: "TooltipBubble",
99
+ props: {
100
+ id: {},
101
+ type: { default: "plain" },
102
+ color: { default: "default" },
103
+ tail: { type: Boolean, default: !1 },
104
+ placement: { default: "top-center" },
105
+ title: {},
106
+ dismissable: { type: Boolean, default: !1 },
107
+ className: {}
108
+ },
109
+ emits: ["dismiss"],
110
+ setup(t) {
111
+ const e = t, a = v(
112
+ () => C(
113
+ "tooltip",
114
+ "content",
115
+ "resets-link-colors",
116
+ `tooltip--${e.type}`,
117
+ `tooltip--${e.color}`,
118
+ e.tail && `tooltip--${e.placement}`,
119
+ e.className
120
+ )
121
+ );
122
+ return (i, l) => (n(), c("div", {
123
+ id: t.id,
124
+ class: V(a.value),
125
+ role: "tooltip"
126
+ }, [
127
+ t.tail ? (n(), c("div", ee)) : f("", !0),
128
+ t.type === "plain" ? (n(), c("div", te, [
129
+ m(i.$slots, "default", {}, void 0, !0),
130
+ t.dismissable ? (n(), h(r(T), {
131
+ key: 0,
132
+ class: "tooltip__dismiss",
133
+ variant: "standard",
134
+ size: "extra-small",
135
+ "icon-only": !0,
136
+ "icon-definition": r(A),
137
+ "aria-label": "Dismiss tooltip",
138
+ onClick: l[0] || (l[0] = (d) => i.$emit("dismiss"))
139
+ }, null, 8, ["icon-definition"])) : f("", !0)
140
+ ])) : (n(), c(X, { key: 2 }, [
141
+ t.title || t.dismissable ? (n(), c("div", ie, [
142
+ t.title ? (n(), c("h6", oe, _(t.title), 1)) : f("", !0),
143
+ t.dismissable ? (n(), h(r(T), {
144
+ key: 1,
145
+ class: "tooltip__dismiss",
146
+ variant: "standard",
147
+ size: "extra-small",
148
+ "icon-only": !0,
149
+ "icon-definition": r(A),
150
+ "aria-label": "Dismiss tooltip",
151
+ onClick: l[1] || (l[1] = (d) => i.$emit("dismiss"))
152
+ }, null, 8, ["icon-definition"])) : f("", !0)
153
+ ])) : f("", !0),
154
+ m(i.$slots, "default", {}, void 0, !0)
155
+ ], 64))
156
+ ], 10, Z));
157
+ }
158
+ }), I = (t, e) => {
159
+ const a = t.__vccOpts || t;
160
+ for (const [i, l] of e)
161
+ a[i] = l;
162
+ return a;
163
+ }, se = /* @__PURE__ */ I(le, [["__scopeId", "data-v-0155bbdd"]]), ne = /* @__PURE__ */ B({
164
+ __name: "Tooltip",
165
+ props: {
166
+ trigger: { default: "hover" },
167
+ type: { default: "plain" },
168
+ color: { default: "default" },
169
+ tail: { type: Boolean, default: !1 },
170
+ placement: { default: "auto" },
171
+ title: {},
172
+ dismissable: { type: Boolean },
173
+ className: {}
174
+ },
175
+ setup(t) {
176
+ const e = t, a = j(), i = b(!1), l = b(null), d = b(null), o = b("top-center"), w = () => {
177
+ const s = l.value?.getBoundingClientRect();
178
+ if (!s) return "top-center";
179
+ const { innerWidth: p, innerHeight: S } = window, x = s.top, H = S - s.bottom, z = d.value?.firstElementChild?.getBoundingClientRect().height ?? 0, U = (z > 0 ? x >= z : x >= H) ? "top" : "bottom", L = s.left + s.width / 2, W = L < p / 3 ? "left" : L > p * 2 / 3 ? "right" : "center";
180
+ return `${U}-${W}`;
181
+ }, E = (s) => {
182
+ s.key === "Escape" && u();
183
+ }, N = (s) => {
184
+ l.value && !l.value.contains(s.target) && u();
185
+ }, k = () => {
186
+ e.placement === "auto" ? o.value = w() : o.value = e.placement, i.value = !0, document.addEventListener("keydown", E), e.trigger === "click" && document.addEventListener("click", N);
187
+ }, u = () => {
188
+ i.value = !1, document.removeEventListener("keydown", E), document.removeEventListener("click", N);
189
+ }, M = () => {
190
+ i.value ? u() : k();
191
+ };
192
+ q(u);
193
+ const F = v(() => ({
194
+ type: e.type,
195
+ color: e.color,
196
+ tail: e.tail,
197
+ placement: o.value,
198
+ title: e.title,
199
+ dismissable: e.dismissable
200
+ }));
201
+ return (s, p) => (n(), c("span", g(
202
+ {
203
+ ref_key: "wrapperEl",
204
+ ref: l,
205
+ class: r(C)("tooltip-trigger", e.className)
206
+ },
207
+ t.trigger === "click" ? { onClick: M } : { onMouseenter: k, onMouseleave: u, onFocusin: k, onFocusout: u }
208
+ ), [
209
+ m(s.$slots, "default", { tooltipId: r(a) }, void 0, !0),
210
+ G("span", {
211
+ ref_key: "positionerEl",
212
+ ref: d,
213
+ class: V(["tooltip-trigger__positioner", `tooltip-trigger__positioner--${o.value}`]),
214
+ style: K({
215
+ visibility: i.value ? "visible" : "hidden",
216
+ "--positioner-gap": t.tail ? "var(--spacing-l)" : "0.5rem"
217
+ }),
218
+ onClick: p[0] || (p[0] = J(() => {
219
+ }, ["stop"]))
220
+ }, [
221
+ $(se, g(F.value, {
222
+ id: r(a),
223
+ onDismiss: u
224
+ }), {
225
+ default: y(() => [
226
+ m(s.$slots, "body", {}, void 0, !0)
227
+ ]),
228
+ _: 3
229
+ }, 16, ["id"])
230
+ ], 6)
231
+ ], 16));
232
+ }
233
+ }), de = /* @__PURE__ */ I(ne, [["__scopeId", "data-v-5dcd06cf"]]);
234
+ export {
235
+ de as Tooltip,
236
+ se as TooltipBubble
237
+ };
package/package.json CHANGED
@@ -1,46 +1,56 @@
1
1
  {
2
2
  "name": "@phila/phila-ui-tooltip",
3
- "private": false,
4
- "version": "0.0.15",
3
+ "version": "0.1.0-beta.0",
5
4
  "type": "module",
6
- "files": [
7
- "dist"
8
- ],
9
- "main": "./dist/Tooltip.umd.cjs",
10
- "module": "./dist/Tooltip.js",
11
- "types": "./dist/types.d.ts",
5
+ "description": "Tooltip component for displaying simple or rich content on hover of an element",
6
+ "main": "./dist/index.js",
7
+ "module": "./dist/index.mjs",
8
+ "types": "./dist/index.d.ts",
12
9
  "exports": {
13
10
  ".": {
14
- "import": {
15
- "types": "./dist/types.d.ts",
16
- "default": "./dist/Tooltip.js"
17
- },
18
- "require": "./dist/Tooltip.umd.cjs"
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.mjs",
13
+ "require": "./dist/index.js"
19
14
  }
20
15
  },
21
- "scripts": {
22
- "dev": "vite",
23
- "prepublish": "npm i && npm run build",
24
- "build": "vue-tsc && vite build",
25
- "preview": "vite preview"
16
+ "files": [
17
+ "dist"
18
+ ],
19
+ "keywords": [
20
+ "ui",
21
+ "tooltip",
22
+ "vue",
23
+ "component"
24
+ ],
25
+ "author": "",
26
+ "license": "MIT",
27
+ "peerDependencies": {
28
+ "vue": "^3.0.0"
26
29
  },
27
30
  "dependencies": {
28
- "@phila/phila-ui-core": "^1.0.24",
29
- "vue": "^3.3.8"
31
+ "@fortawesome/pro-solid-svg-icons": "^7.1.0",
32
+ "@phila/phila-ui-button": "2.2.3-beta.1",
33
+ "@phila/phila-ui-core": "2.3.3-beta.1"
30
34
  },
31
35
  "devDependencies": {
32
- "@types/node": "^20.10.3",
33
- "@vitejs/plugin-vue": "^4.5.0",
34
- "sass": "^1.70.0",
35
- "typescript": "^5.8.2",
36
- "vite": "^5.0.0",
37
- "vite-plugin-dts": "^3.6.4",
38
- "vite-plugin-lib-inject-css": "^1.3.0",
39
- "vue-tsc": "^2.2.8"
36
+ "@types/node": "^24.0.0",
37
+ "@vitejs/plugin-vue": "^6.0.1",
38
+ "eslint": "^9.0.0",
39
+ "typescript": "^5.8.3",
40
+ "vite": "^7.0.6",
41
+ "vite-plugin-dts": "^4.5.4",
42
+ "vite-plugin-lib-inject-css": "^2.2.2",
43
+ "@phila/phila-ui-tags": "0.0.1-beta.1"
40
44
  },
41
- "publishConfig": {
42
- "registry": "https://registry.npmjs.com/",
43
- "access": "public"
44
- },
45
- "gitHead": "f00518592815b1bf558d88f77fc4b6b3a30296e5"
46
- }
45
+ "scripts": {
46
+ "build": "vite build",
47
+ "build-win": "vite build",
48
+ "dev": "vite build --watch",
49
+ "lint": "eslint src --ext .ts,.tsx,.vue",
50
+ "lint:fix": "eslint src --ext .ts,.tsx,.vue --fix",
51
+ "type-check": "tsc --noEmit",
52
+ "clean": "rm -rf dist",
53
+ "format": "prettier --write .",
54
+ "format:check": "prettier --check ."
55
+ }
56
+ }
package/dist/Tooltip.css DELETED
@@ -1 +0,0 @@
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}.tooltip{display:inline-block;margin-left:5px;vertical-align:middle}.tooltip button{color:#0f4d90;font-size:25px;border:0;background-color:transparent;box-shadow:none;padding:0;margin:0;cursor:pointer;vertical-align:middle;position:relative;top:-2px}.tooltip-box{display:block;visibility:hidden;z-index:-100;width:auto;max-width:500px;position:fixed;top:0;left:0;opacity:0;transition:opacity .25s ease-in-out;pointer-events:none}.tooltip-box .tooltip-message{line-height:20px;color:#fff;background-color:#444;font-size:12px;padding:10px 8px 8px}@media screen and (max-width: 768px){.tooltip-box .tooltip-message{padding-top:36px}.tooltip-box .tooltip-message:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;content:"";position:absolute;top:12px;right:16px;font-family:"Font Awesome 5 Pro",sans-serif;font-weight:900;font-size:20px}}@media screen and (max-width: 500px){.tooltip-box{width:auto;max-width:100%}}.tooltip-box .tooltip-arrow{position:fixed;left:0;top:0;border:solid 8px transparent;border-top-color:#444}.tooltip-box .tooltip-arrow.arrow-up{border-top-color:transparent;border-bottom-color:#444}.tooltip-box.light .tooltip-message{color:#444;background-color:#f0f0f0}.tooltip-box.light .tooltip-arrow{border-top-color:#f0f0f0}.tooltip-box.light .tooltip-arrow.arrow-up{border-top-color:transparent;border-bottom-color:#f0f0f0}.tooltip-box.show{visibility:visible;opacity:1;z-index:9999}
package/dist/Tooltip.js DELETED
@@ -1,112 +0,0 @@
1
- import "./Tooltip.css";
2
- import { defineComponent as p, ref as n, onMounted as h, createElementBlock as a, openBlock as r, renderSlot as d } from "vue";
3
- class c {
4
- constructor(t, o, i, s) {
5
- this.htmlBody = document.getElementsByTagName("body")[0], this.tooltip = t, this.tooltipIcon = null, this.tooltipIconClasses = "fas fa-info-circle", this.tooltipArrow = null, this.tooltipBox = null, this.tooltipText = o, this.tooltipBoxClasses = "tooltip-box", this.tooltipMessageClasses = "tooltip-message", this.tooltipArrowClasses = "tooltip-arrow", this.tooltipMode = i || "dark", this.currentTooltipPosition = null, this.initPositionSet = !1, this.tooltipID = s, this.tooltipBtnID = `btn-${s}`, this.padding = 8, this.arrowAttrs = {
6
- height: 8,
7
- width: 16
8
- }, this.clickedToOpen = !1, this.newTooltip();
9
- }
10
- newTooltip() {
11
- this.makeTooltipContainer(), this.setTooltipEvents(), this.setTooltipMsg(), this.setTooltipMode(), this.addTooltip();
12
- const t = this;
13
- var o = setInterval(function() {
14
- const i = document.getElementById(t.tooltipID);
15
- i && i.offsetHeight > 0 && (t.addTooltipIcon(), t.setInitTooltipPosition(), t.updateArrowPosition(), clearInterval(o));
16
- }, 500);
17
- }
18
- makeTooltipContainer() {
19
- this.tooltipArrow = document.createElement("div"), this.tooltipArrow.className = this.tooltipArrowClasses, this.tooltipBox = document.createElement("div"), this.tooltipBox.className = this.tooltipBoxClasses, this.tooltipBox.setAttribute("id", this.tooltipID), this.tooltipMessage = document.createElement("div"), this.tooltipMessage.className = this.tooltipMessageClasses, this.tooltipIcon = document.createElement("button"), this.tooltipIcon.setAttribute("aria-label", "tooltip"), this.tooltipIcon.className = this.tooltipIconClasses, this.tooltipIcon.setAttribute("id", this.tooltipBtnID);
20
- }
21
- addTooltipIcon() {
22
- this.tooltip.appendChild(this.tooltipIcon);
23
- }
24
- addTooltip() {
25
- this.tooltipBox.appendChild(this.tooltipMessage), this.tooltipBox.appendChild(this.tooltipArrow), this.htmlBody.appendChild(this.tooltipBox);
26
- }
27
- setTooltipMode() {
28
- this.tooltipBox.className = this.tooltipBoxClasses, this.tooltipBox.classList.add(this.tooltipMode);
29
- }
30
- setTooltipMsg() {
31
- this.tooltipMessage.innerText = this.tooltipText;
32
- }
33
- setTooltipEvents() {
34
- const t = this;
35
- window.addEventListener("resize", function() {
36
- t.updateTooltipPosition();
37
- }, !0), this.tooltipIcon.addEventListener("mouseenter", function() {
38
- t.updateTooltipPosition(), t.showTooltip();
39
- }), window.addEventListener("scroll", function() {
40
- t.tooltipBox.classList.contains("show") && t.hideTooltip();
41
- }), this.tooltipIcon.addEventListener("focus", function() {
42
- t.updateTooltipPosition(), t.showTooltip();
43
- }), this.tooltipIcon.addEventListener("mouseleave", function() {
44
- t.clickedToOpen || t.hideTooltip();
45
- }), this.tooltipIcon.addEventListener("blur", function() {
46
- t.hideTooltip();
47
- }), this.tooltipIcon.addEventListener("click", function() {
48
- t.clickedToOpen = !0, t.updateTooltipPosition(), t.toggleTooltip();
49
- }, !1), window.addEventListener("click", function(o) {
50
- o.target !== t.tooltipIcon && t.clickedToOpen && (t.hideTooltip(), t.clickedToOpen = !1);
51
- });
52
- }
53
- toggleTooltip() {
54
- this.clickedToOpen ? this.showTooltip() : this.hideTooltip();
55
- }
56
- showTooltip() {
57
- this.tooltipBox.classList.add("show"), this.tooltipBox.setAttribute("aria-hidden", !1);
58
- }
59
- hideTooltip() {
60
- this.tooltipBox.classList.remove("show"), this.tooltipBox.setAttribute("aria-hidden", !0);
61
- }
62
- updateArrowPosition() {
63
- const t = this.tooltipIcon.getBoundingClientRect(), o = this.tooltipBox.getBoundingClientRect();
64
- this.tooltipArrow.style.left = `${t.left + this.tooltipIcon.offsetWidth / 2 - this.arrowAttrs.width / 2}px`, o.top > t.top ? (this.tooltipArrow.style.top = `${o.top - this.arrowAttrs.height * 2}px`, this.tooltipArrow.classList.add("arrow-up")) : (this.tooltipArrow.style.top = `${o.top + this.tooltipBox.offsetHeight}px`, this.tooltipArrow.classList.remove("arrow-up"));
65
- }
66
- setInitTooltipPosition() {
67
- const t = this.tooltipIcon.getBoundingClientRect();
68
- this.tooltipBox.style.left = `${t.left + this.tooltipIcon.offsetWidth / 2 - this.tooltipBox.offsetWidth / 2}px`, this.tooltipBox.style.top = `${t.top - this.tooltipBox.offsetHeight - this.arrowAttrs.height}px`;
69
- }
70
- updateTooltipPosition(t = !0) {
71
- t && this.setInitTooltipPosition();
72
- const o = window.innerWidth;
73
- let i = o - this.padding * 2;
74
- i <= 500 && (this.tooltipBox.style.maxWidth = `${i}px`);
75
- const s = this.tooltipIcon.getBoundingClientRect(), e = this.tooltipBox.getBoundingClientRect();
76
- if (e.left < this.padding) {
77
- this.tooltipBox.style.left = `${this.padding}px`, this.tooltipBox.style.top = `${s.top - this.tooltipBox.offsetHeight - this.arrowAttrs.height}px`, this.updateTooltipPosition(!1);
78
- return;
79
- } else if (e.left + this.tooltipBox.offsetWidth > o - this.padding) {
80
- this.tooltipBox.style.left = `${window.innerWidth - this.padding - this.tooltipBox.offsetWidth}px`, this.tooltipBox.style.top = `${s.top - this.tooltipBox.offsetHeight - this.arrowAttrs.height}px`, this.updateTooltipPosition(!1);
81
- return;
82
- } else if (e.top < this.padding) {
83
- this.tooltipBox.style.left = `${e.left}px`, this.tooltipBox.style.top = `${s.bottom + this.arrowAttrs.height}px`, this.updateTooltipPosition(!1);
84
- return;
85
- }
86
- this.updateArrowPosition();
87
- }
88
- }
89
- const f = ["aria-describedby"], x = /* @__PURE__ */ p({
90
- __name: "Tooltip",
91
- props: {
92
- mode: { default: "light" },
93
- message: {}
94
- },
95
- setup(l) {
96
- const t = l, o = n(Math.floor((1 + Math.random()) * 65536).toString(16).substring(1)), i = n(null);
97
- return h(() => {
98
- t.message.length >= 250 && console.warn("The tooltip message should be no longer than 250 characters"), new c(i.value, t.message, t.mode, o.value);
99
- }), (s, e) => (r(), a("div", {
100
- ref_key: "tooltip",
101
- ref: i,
102
- class: "tooltip",
103
- role: "tooltip",
104
- "aria-describedby": o.value
105
- }, [
106
- d(s.$slots, "default")
107
- ], 8, f));
108
- }
109
- });
110
- export {
111
- x as default
112
- };
@@ -1,2 +0,0 @@
1
- (function(i,l){typeof exports=="object"&&typeof module<"u"?module.exports=l(require("vue")):typeof define=="function"&&define.amd?define(["vue"],l):(i=typeof globalThis<"u"?globalThis:i||self,i.Tooltip=l(i.Vue))})(this,function(i){"use strict";var l=document.createElement("style");l.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}.tooltip{display:inline-block;margin-left:5px;vertical-align:middle}.tooltip button{color:#0f4d90;font-size:25px;border:0;background-color:transparent;box-shadow:none;padding:0;margin:0;cursor:pointer;vertical-align:middle;position:relative;top:-2px}.tooltip-box{display:block;visibility:hidden;z-index:-100;width:auto;max-width:500px;position:fixed;top:0;left:0;opacity:0;transition:opacity .25s ease-in-out;pointer-events:none}.tooltip-box .tooltip-message{line-height:20px;color:#fff;background-color:#444;font-size:12px;padding:10px 8px 8px}@media screen and (max-width: 768px){.tooltip-box .tooltip-message{padding-top:36px}.tooltip-box .tooltip-message:before{display:inline-block;font-style:normal;font-variant:normal;text-rendering:auto;-webkit-font-smoothing:antialiased;content:"";position:absolute;top:12px;right:16px;font-family:"Font Awesome 5 Pro",sans-serif;font-weight:900;font-size:20px}}@media screen and (max-width: 500px){.tooltip-box{width:auto;max-width:100%}}.tooltip-box .tooltip-arrow{position:fixed;left:0;top:0;border:solid 8px transparent;border-top-color:#444}.tooltip-box .tooltip-arrow.arrow-up{border-top-color:transparent;border-bottom-color:#444}.tooltip-box.light .tooltip-message{color:#444;background-color:#f0f0f0}.tooltip-box.light .tooltip-arrow{border-top-color:#f0f0f0}.tooltip-box.light .tooltip-arrow.arrow-up{border-top-color:transparent;border-bottom-color:#f0f0f0}.tooltip-box.show{visibility:visible;opacity:1;z-index:9999}
2
- /*$vite$:1*/`,document.head.appendChild(l);class p{constructor(t,o,s,e){this.htmlBody=document.getElementsByTagName("body")[0],this.tooltip=t,this.tooltipIcon=null,this.tooltipIconClasses="fas fa-info-circle",this.tooltipArrow=null,this.tooltipBox=null,this.tooltipText=o,this.tooltipBoxClasses="tooltip-box",this.tooltipMessageClasses="tooltip-message",this.tooltipArrowClasses="tooltip-arrow",this.tooltipMode=s||"dark",this.currentTooltipPosition=null,this.initPositionSet=!1,this.tooltipID=e,this.tooltipBtnID=`btn-${e}`,this.padding=8,this.arrowAttrs={height:8,width:16},this.clickedToOpen=!1,this.newTooltip()}newTooltip(){this.makeTooltipContainer(),this.setTooltipEvents(),this.setTooltipMsg(),this.setTooltipMode(),this.addTooltip();const t=this;var o=setInterval(function(){const s=document.getElementById(t.tooltipID);s&&s.offsetHeight>0&&(t.addTooltipIcon(),t.setInitTooltipPosition(),t.updateArrowPosition(),clearInterval(o))},500)}makeTooltipContainer(){this.tooltipArrow=document.createElement("div"),this.tooltipArrow.className=this.tooltipArrowClasses,this.tooltipBox=document.createElement("div"),this.tooltipBox.className=this.tooltipBoxClasses,this.tooltipBox.setAttribute("id",this.tooltipID),this.tooltipMessage=document.createElement("div"),this.tooltipMessage.className=this.tooltipMessageClasses,this.tooltipIcon=document.createElement("button"),this.tooltipIcon.setAttribute("aria-label","tooltip"),this.tooltipIcon.className=this.tooltipIconClasses,this.tooltipIcon.setAttribute("id",this.tooltipBtnID)}addTooltipIcon(){this.tooltip.appendChild(this.tooltipIcon)}addTooltip(){this.tooltipBox.appendChild(this.tooltipMessage),this.tooltipBox.appendChild(this.tooltipArrow),this.htmlBody.appendChild(this.tooltipBox)}setTooltipMode(){this.tooltipBox.className=this.tooltipBoxClasses,this.tooltipBox.classList.add(this.tooltipMode)}setTooltipMsg(){this.tooltipMessage.innerText=this.tooltipText}setTooltipEvents(){const t=this;window.addEventListener("resize",function(){t.updateTooltipPosition()},!0),this.tooltipIcon.addEventListener("mouseenter",function(){t.updateTooltipPosition(),t.showTooltip()}),window.addEventListener("scroll",function(){t.tooltipBox.classList.contains("show")&&t.hideTooltip()}),this.tooltipIcon.addEventListener("focus",function(){t.updateTooltipPosition(),t.showTooltip()}),this.tooltipIcon.addEventListener("mouseleave",function(){t.clickedToOpen||t.hideTooltip()}),this.tooltipIcon.addEventListener("blur",function(){t.hideTooltip()}),this.tooltipIcon.addEventListener("click",function(){t.clickedToOpen=!0,t.updateTooltipPosition(),t.toggleTooltip()},!1),window.addEventListener("click",function(o){o.target!==t.tooltipIcon&&t.clickedToOpen&&(t.hideTooltip(),t.clickedToOpen=!1)})}toggleTooltip(){this.clickedToOpen?this.showTooltip():this.hideTooltip()}showTooltip(){this.tooltipBox.classList.add("show"),this.tooltipBox.setAttribute("aria-hidden",!1)}hideTooltip(){this.tooltipBox.classList.remove("show"),this.tooltipBox.setAttribute("aria-hidden",!0)}updateArrowPosition(){const t=this.tooltipIcon.getBoundingClientRect(),o=this.tooltipBox.getBoundingClientRect();this.tooltipArrow.style.left=`${t.left+this.tooltipIcon.offsetWidth/2-this.arrowAttrs.width/2}px`,o.top>t.top?(this.tooltipArrow.style.top=`${o.top-this.arrowAttrs.height*2}px`,this.tooltipArrow.classList.add("arrow-up")):(this.tooltipArrow.style.top=`${o.top+this.tooltipBox.offsetHeight}px`,this.tooltipArrow.classList.remove("arrow-up"))}setInitTooltipPosition(){const t=this.tooltipIcon.getBoundingClientRect();this.tooltipBox.style.left=`${t.left+this.tooltipIcon.offsetWidth/2-this.tooltipBox.offsetWidth/2}px`,this.tooltipBox.style.top=`${t.top-this.tooltipBox.offsetHeight-this.arrowAttrs.height}px`}updateTooltipPosition(t=!0){t&&this.setInitTooltipPosition();const o=window.innerWidth;let s=o-this.padding*2;s<=500&&(this.tooltipBox.style.maxWidth=`${s}px`);const e=this.tooltipIcon.getBoundingClientRect(),n=this.tooltipBox.getBoundingClientRect();if(n.left<this.padding){this.tooltipBox.style.left=`${this.padding}px`,this.tooltipBox.style.top=`${e.top-this.tooltipBox.offsetHeight-this.arrowAttrs.height}px`,this.updateTooltipPosition(!1);return}else if(n.left+this.tooltipBox.offsetWidth>o-this.padding){this.tooltipBox.style.left=`${window.innerWidth-this.padding-this.tooltipBox.offsetWidth}px`,this.tooltipBox.style.top=`${e.top-this.tooltipBox.offsetHeight-this.arrowAttrs.height}px`,this.updateTooltipPosition(!1);return}else if(n.top<this.padding){this.tooltipBox.style.left=`${n.left}px`,this.tooltipBox.style.top=`${e.bottom+this.arrowAttrs.height}px`,this.updateTooltipPosition(!1);return}this.updateArrowPosition()}}const r=["aria-describedby"];return i.defineComponent({__name:"Tooltip",props:{mode:{default:"light"},message:{}},setup(a){const t=a,o=i.ref(Math.floor((1+Math.random())*65536).toString(16).substring(1)),s=i.ref(null);return i.onMounted(()=>{t.message.length>=250&&console.warn("The tooltip message should be no longer than 250 characters"),new p(s.value,t.message,t.mode,o.value)}),(e,n)=>(i.openBlock(),i.createElementBlock("div",{ref_key:"tooltip",ref:s,class:"tooltip",role:"tooltip","aria-describedby":o.value},[i.renderSlot(e.$slots,"default")],8,r))}})});
package/dist/types.d.ts DELETED
@@ -1,12 +0,0 @@
1
- import { default as Tooltip } from './Tooltip.vue';
2
-
3
- declare module "vue" {
4
- interface GlobalComponents {
5
- Tooltip: typeof Tooltip;
6
- }
7
- }
8
- export interface TooltipProps {
9
- mode: "light" | "dark";
10
- message: string;
11
- }
12
- export default Tooltip;