mirror of
https://github.com/ionic-team/ionic-framework.git
synced 2026-03-13 10:22:08 +08:00
Compare commits
8 Commits
cb/module-
...
st/os-chec
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
bb789354b0 | ||
|
|
7f35114ef7 | ||
|
|
df06bf53b3 | ||
|
|
d85aacf0f1 | ||
|
|
0a58f90dd0 | ||
|
|
f85a92b18b | ||
|
|
c8dcdfa5a7 | ||
|
|
c795995393 |
4
.github/COMPONENT-GUIDE.md
vendored
4
.github/COMPONENT-GUIDE.md
vendored
@@ -328,7 +328,7 @@ The ripple effect should be added to elements for Material Design. It *requires*
|
||||
|
||||
```jsx
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
@@ -338,7 +338,7 @@ return (
|
||||
>
|
||||
<button>
|
||||
<slot></slot>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
</Host>
|
||||
);
|
||||
|
||||
59
core/api.txt
59
core/api.txt
@@ -3,6 +3,7 @@ ion-accordion,shadow
|
||||
ion-accordion,prop,disabled,boolean,false,false,false
|
||||
ion-accordion,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-accordion,prop,readonly,boolean,false,false,false
|
||||
ion-accordion,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-accordion,prop,toggleIcon,string,chevronDown,false,false
|
||||
ion-accordion,prop,toggleIconSlot,"end" | "start",'end',false,false
|
||||
ion-accordion,prop,value,string,`ion-accordion-${accordionIds++}`,false,false
|
||||
@@ -17,6 +18,7 @@ ion-accordion-group,prop,expand,"compact" | "inset",'compact',false,false
|
||||
ion-accordion-group,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-accordion-group,prop,multiple,boolean | undefined,undefined,false,false
|
||||
ion-accordion-group,prop,readonly,boolean,false,false,false
|
||||
ion-accordion-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-accordion-group,prop,value,null | string | string[] | undefined,undefined,false,false
|
||||
ion-accordion-group,event,ionChange,AccordionGroupChangeEventDetail<any>,true
|
||||
|
||||
@@ -33,6 +35,7 @@ ion-action-sheet,prop,keyboardClose,boolean,true,false,false
|
||||
ion-action-sheet,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-action-sheet,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-action-sheet,prop,subHeader,string | undefined,undefined,false,false
|
||||
ion-action-sheet,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-action-sheet,prop,translucent,boolean,false,false,false
|
||||
ion-action-sheet,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-action-sheet,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
@@ -86,6 +89,7 @@ ion-alert,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefin
|
||||
ion-alert,prop,message,IonicSafeString | string | undefined,undefined,false,false
|
||||
ion-alert,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-alert,prop,subHeader,string | undefined,undefined,false,false
|
||||
ion-alert,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-alert,prop,translucent,boolean,false,false,false
|
||||
ion-alert,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-alert,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
@@ -112,6 +116,7 @@ ion-alert,css-prop,--width
|
||||
ion-app,none
|
||||
|
||||
ion-avatar,shadow
|
||||
ion-avatar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-avatar,css-prop,--border-radius
|
||||
|
||||
ion-back-button,shadow
|
||||
@@ -122,6 +127,7 @@ ion-back-button,prop,icon,null | string | undefined,undefined,false,false
|
||||
ion-back-button,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-back-button,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-back-button,prop,text,null | string | undefined,undefined,false,false
|
||||
ion-back-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-back-button,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-back-button,css-prop,--background
|
||||
ion-back-button,css-prop,--background-focused
|
||||
@@ -162,12 +168,14 @@ ion-back-button,part,text
|
||||
ion-backdrop,shadow
|
||||
ion-backdrop,prop,stopPropagation,boolean,true,false,false
|
||||
ion-backdrop,prop,tappable,boolean,true,false,false
|
||||
ion-backdrop,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-backdrop,prop,visible,boolean,true,false,false
|
||||
ion-backdrop,event,ionBackdropTap,void,true
|
||||
|
||||
ion-badge,shadow
|
||||
ion-badge,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-badge,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-badge,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-badge,css-prop,--background
|
||||
ion-badge,css-prop,--color
|
||||
ion-badge,css-prop,--padding-bottom
|
||||
@@ -187,6 +195,7 @@ ion-breadcrumb,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | u
|
||||
ion-breadcrumb,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||
ion-breadcrumb,prop,separator,boolean | undefined,undefined,false,false
|
||||
ion-breadcrumb,prop,target,string | undefined,undefined,false,false
|
||||
ion-breadcrumb,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-breadcrumb,event,ionBlur,void,true
|
||||
ion-breadcrumb,event,ionFocus,void,true
|
||||
ion-breadcrumb,css-prop,--background-focused
|
||||
@@ -204,6 +213,7 @@ ion-breadcrumbs,prop,itemsAfterCollapse,number,1,false,false
|
||||
ion-breadcrumbs,prop,itemsBeforeCollapse,number,1,false,false
|
||||
ion-breadcrumbs,prop,maxItems,number | undefined,undefined,false,false
|
||||
ion-breadcrumbs,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-breadcrumbs,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-breadcrumbs,event,ionCollapsedClick,BreadcrumbCollapsedClickEventDetail,true
|
||||
|
||||
ion-button,shadow
|
||||
@@ -223,6 +233,7 @@ ion-button,prop,shape,"round" | undefined,undefined,false,true
|
||||
ion-button,prop,size,"default" | "large" | "small" | undefined,undefined,false,true
|
||||
ion-button,prop,strong,boolean,false,false,false
|
||||
ion-button,prop,target,string | undefined,undefined,false,false
|
||||
ion-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-button,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-button,event,ionBlur,void,true
|
||||
ion-button,event,ionFocus,void,true
|
||||
@@ -253,6 +264,7 @@ ion-button,part,native
|
||||
|
||||
ion-buttons,scoped
|
||||
ion-buttons,prop,collapse,boolean,false,false,false
|
||||
ion-buttons,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
|
||||
ion-card,shadow
|
||||
ion-card,prop,button,boolean,false,false,false
|
||||
@@ -265,6 +277,7 @@ ion-card,prop,rel,string | undefined,undefined,false,false
|
||||
ion-card,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-card,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||
ion-card,prop,target,string | undefined,undefined,false,false
|
||||
ion-card,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-card,css-prop,--background
|
||||
ion-card,css-prop,--color
|
||||
@@ -272,20 +285,24 @@ ion-card,part,native
|
||||
|
||||
ion-card-content,none
|
||||
ion-card-content,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
|
||||
ion-card-header,shadow
|
||||
ion-card-header,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-card-header,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card-header,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card-header,prop,translucent,boolean,false,false,false
|
||||
|
||||
ion-card-subtitle,shadow
|
||||
ion-card-subtitle,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-card-subtitle,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card-subtitle,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card-subtitle,css-prop,--color
|
||||
|
||||
ion-card-title,shadow
|
||||
ion-card-title,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-card-title,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-card-title,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-card-title,css-prop,--color
|
||||
|
||||
ion-checkbox,shadow
|
||||
@@ -299,6 +316,8 @@ ion-checkbox,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',f
|
||||
ion-checkbox,prop,legacy,boolean | undefined,undefined,false,false
|
||||
ion-checkbox,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-checkbox,prop,name,string,this.inputId,false,false
|
||||
ion-checkbox,prop,required,boolean,false,false,false
|
||||
ion-checkbox,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-checkbox,prop,value,any,'on',false,false
|
||||
ion-checkbox,event,ionBlur,void,true
|
||||
ion-checkbox,event,ionChange,CheckboxChangeEventDetail<any>,true
|
||||
@@ -323,6 +342,7 @@ ion-chip,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "second
|
||||
ion-chip,prop,disabled,boolean,false,false,false
|
||||
ion-chip,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-chip,prop,outline,boolean,false,false,false
|
||||
ion-chip,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-chip,css-prop,--background
|
||||
ion-chip,css-prop,--color
|
||||
|
||||
@@ -414,6 +434,7 @@ ion-datetime,prop,showDefaultButtons,boolean,false,false,false
|
||||
ion-datetime,prop,showDefaultTimeLabel,boolean,true,false,false
|
||||
ion-datetime,prop,showDefaultTitle,boolean,false,false,false
|
||||
ion-datetime,prop,size,"cover" | "fixed",'fixed',false,false
|
||||
ion-datetime,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-datetime,prop,titleSelectedDatesFormatter,((selectedDates: string[]) => string) | undefined,undefined,false,false
|
||||
ion-datetime,prop,value,null | string | string[] | undefined,undefined,false,false
|
||||
ion-datetime,prop,yearValues,number | number[] | string | undefined,undefined,false,false
|
||||
@@ -444,6 +465,7 @@ ion-datetime-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary
|
||||
ion-datetime-button,prop,datetime,string | undefined,undefined,false,false
|
||||
ion-datetime-button,prop,disabled,boolean,false,false,true
|
||||
ion-datetime-button,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-datetime-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-datetime-button,part,native
|
||||
|
||||
ion-fab,shadow
|
||||
@@ -467,6 +489,7 @@ ion-fab-button,prop,routerDirection,"back" | "forward" | "root",'forward',false,
|
||||
ion-fab-button,prop,show,boolean,false,false,false
|
||||
ion-fab-button,prop,size,"small" | undefined,undefined,false,false
|
||||
ion-fab-button,prop,target,string | undefined,undefined,false,false
|
||||
ion-fab-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-fab-button,prop,translucent,boolean,false,false,false
|
||||
ion-fab-button,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-fab-button,event,ionBlur,void,true
|
||||
@@ -504,6 +527,7 @@ ion-fab-list,prop,side,"bottom" | "end" | "start" | "top",'bottom',false,false
|
||||
ion-footer,none
|
||||
ion-footer,prop,collapse,"fade" | undefined,undefined,false,false
|
||||
ion-footer,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-footer,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-footer,prop,translucent,boolean,false,false,false
|
||||
|
||||
ion-grid,shadow
|
||||
@@ -524,6 +548,7 @@ ion-grid,css-prop,--ion-grid-width-xs
|
||||
ion-header,none
|
||||
ion-header,prop,collapse,"condense" | "fade" | undefined,undefined,false,false
|
||||
ion-header,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-header,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-header,prop,translucent,boolean,false,false,false
|
||||
|
||||
ion-img,shadow
|
||||
@@ -544,6 +569,7 @@ ion-infinite-scroll,event,ionInfinite,void,true
|
||||
ion-infinite-scroll-content,none
|
||||
ion-infinite-scroll-content,prop,loadingSpinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | null | undefined,undefined,false,false
|
||||
ion-infinite-scroll-content,prop,loadingText,IonicSafeString | string | undefined,undefined,false,false
|
||||
ion-infinite-scroll-content,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
|
||||
ion-input,scoped
|
||||
ion-input,prop,accept,string | undefined,undefined,false,false
|
||||
@@ -581,6 +607,7 @@ ion-input,prop,shape,"round" | undefined,undefined,false,false
|
||||
ion-input,prop,size,number | undefined,undefined,false,false
|
||||
ion-input,prop,spellcheck,boolean,false,false,false
|
||||
ion-input,prop,step,string | undefined,undefined,false,false
|
||||
ion-input,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-input,prop,type,"date" | "datetime-local" | "email" | "month" | "number" | "password" | "search" | "tel" | "text" | "time" | "url" | "week",'text',false,false
|
||||
ion-input,prop,value,null | number | string | undefined,'',false,false
|
||||
ion-input,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
|
||||
@@ -625,6 +652,7 @@ ion-item,prop,routerAnimation,((baseEl: any, opts?: any) => Animation) | undefin
|
||||
ion-item,prop,routerDirection,"back" | "forward" | "root",'forward',false,false
|
||||
ion-item,prop,shape,"round" | undefined,undefined,false,false
|
||||
ion-item,prop,target,string | undefined,undefined,false,false
|
||||
ion-item,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-item,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-item,css-prop,--background
|
||||
ion-item,css-prop,--background-activated
|
||||
@@ -668,6 +696,7 @@ ion-item-divider,shadow
|
||||
ion-item-divider,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-item-divider,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-item-divider,prop,sticky,boolean,false,false,false
|
||||
ion-item-divider,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-item-divider,css-prop,--background
|
||||
ion-item-divider,css-prop,--color
|
||||
ion-item-divider,css-prop,--inner-padding-bottom
|
||||
@@ -680,6 +709,7 @@ ion-item-divider,css-prop,--padding-start
|
||||
ion-item-divider,css-prop,--padding-top
|
||||
|
||||
ion-item-group,none
|
||||
ion-item-group,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
|
||||
ion-item-option,shadow
|
||||
ion-item-option,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
@@ -690,6 +720,7 @@ ion-item-option,prop,href,string | undefined,undefined,false,false
|
||||
ion-item-option,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-item-option,prop,rel,string | undefined,undefined,false,false
|
||||
ion-item-option,prop,target,string | undefined,undefined,false,false
|
||||
ion-item-option,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-item-option,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-item-option,css-prop,--background
|
||||
ion-item-option,css-prop,--color
|
||||
@@ -697,6 +728,7 @@ ion-item-option,part,native
|
||||
|
||||
ion-item-options,none
|
||||
ion-item-options,prop,side,"end" | "start",'end',false,false
|
||||
ion-item-options,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-item-options,event,ionSwipe,any,true
|
||||
|
||||
ion-item-sliding,none
|
||||
@@ -712,18 +744,21 @@ ion-label,scoped
|
||||
ion-label,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-label,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-label,prop,position,"fixed" | "floating" | "stacked" | undefined,undefined,false,false
|
||||
ion-label,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-label,css-prop,--color
|
||||
|
||||
ion-list,none
|
||||
ion-list,prop,inset,boolean,false,false,false
|
||||
ion-list,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
|
||||
ion-list,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-list,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-list,method,closeSlidingItems,closeSlidingItems() => Promise<boolean>
|
||||
|
||||
ion-list-header,shadow
|
||||
ion-list-header,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-list-header,prop,lines,"full" | "inset" | "none" | undefined,undefined,false,false
|
||||
ion-list-header,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-list-header,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-list-header,css-prop,--background
|
||||
ion-list-header,css-prop,--border-color
|
||||
ion-list-header,css-prop,--border-style
|
||||
@@ -745,6 +780,7 @@ ion-loading,prop,message,IonicSafeString | string | undefined,undefined,false,fa
|
||||
ion-loading,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-loading,prop,showBackdrop,boolean,true,false,false
|
||||
ion-loading,prop,spinner,"bubbles" | "circles" | "circular" | "crescent" | "dots" | "lines" | "lines-sharp" | "lines-sharp-small" | "lines-small" | null | undefined,undefined,false,false
|
||||
ion-loading,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-loading,prop,translucent,boolean,false,false,false
|
||||
ion-loading,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-loading,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
@@ -776,6 +812,7 @@ ion-menu,prop,maxEdgeStart,number,50,false,false
|
||||
ion-menu,prop,menuId,string | undefined,undefined,false,true
|
||||
ion-menu,prop,side,"end" | "start",'start',false,true
|
||||
ion-menu,prop,swipeGesture,boolean,true,false,false
|
||||
ion-menu,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-menu,prop,type,string | undefined,undefined,false,false
|
||||
ion-menu,method,close,close(animated?: boolean) => Promise<boolean>
|
||||
ion-menu,method,isActive,isActive() => Promise<boolean>
|
||||
@@ -803,6 +840,7 @@ ion-menu-button,prop,color,"danger" | "dark" | "light" | "medium" | "primary" |
|
||||
ion-menu-button,prop,disabled,boolean,false,false,false
|
||||
ion-menu-button,prop,menu,string | undefined,undefined,false,false
|
||||
ion-menu-button,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-menu-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-menu-button,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-menu-button,css-prop,--background
|
||||
ion-menu-button,css-prop,--background-focused
|
||||
@@ -842,6 +880,7 @@ ion-modal,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefin
|
||||
ion-modal,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-modal,prop,presentingElement,HTMLElement | undefined,undefined,false,false
|
||||
ion-modal,prop,showBackdrop,boolean,true,false,false
|
||||
ion-modal,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-modal,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-modal,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
ion-modal,method,getCurrentBreakpoint,getCurrentBreakpoint() => Promise<number | undefined>
|
||||
@@ -905,6 +944,7 @@ ion-nav-link,prop,routerDirection,"back" | "forward" | "root",'forward',false,fa
|
||||
ion-note,shadow
|
||||
ion-note,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-note,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-note,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-note,css-prop,--color
|
||||
|
||||
ion-picker,scoped
|
||||
@@ -921,6 +961,7 @@ ion-picker,prop,keyboardClose,boolean,true,false,false
|
||||
ion-picker,prop,leaveAnimation,((baseEl: any, opts?: any) => Animation) | undefined,undefined,false,false
|
||||
ion-picker,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-picker,prop,showBackdrop,boolean,true,false,false
|
||||
ion-picker,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-picker,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-picker,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
ion-picker,method,getColumn,getColumn(name: string) => Promise<PickerColumn | undefined>
|
||||
@@ -969,6 +1010,7 @@ ion-popover,prop,reference,"event" | "trigger",'trigger',false,false
|
||||
ion-popover,prop,showBackdrop,boolean,true,false,false
|
||||
ion-popover,prop,side,"bottom" | "end" | "left" | "right" | "start" | "top",'bottom',false,false
|
||||
ion-popover,prop,size,"auto" | "cover",'auto',false,false
|
||||
ion-popover,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-popover,prop,translucent,boolean,false,false,false
|
||||
ion-popover,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-popover,prop,triggerAction,"click" | "context-menu" | "hover",'click',false,false
|
||||
@@ -1004,6 +1046,7 @@ ion-progress-bar,prop,buffer,number,1,false,false
|
||||
ion-progress-bar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-progress-bar,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-progress-bar,prop,reversed,boolean,false,false,false
|
||||
ion-progress-bar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-progress-bar,prop,type,"determinate" | "indeterminate",'determinate',false,false
|
||||
ion-progress-bar,prop,value,number,0,false,false
|
||||
ion-progress-bar,css-prop,--background
|
||||
@@ -1022,6 +1065,7 @@ ion-radio,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',fals
|
||||
ion-radio,prop,legacy,boolean | undefined,undefined,false,false
|
||||
ion-radio,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-radio,prop,name,string,this.inputId,false,false
|
||||
ion-radio,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-radio,prop,value,any,undefined,false,false
|
||||
ion-radio,event,ionBlur,void,true
|
||||
ion-radio,event,ionFocus,void,true
|
||||
@@ -1057,6 +1101,7 @@ ion-range,prop,pin,boolean,false,false,false
|
||||
ion-range,prop,pinFormatter,(value: number) => string | number,(value: number): number => Math.round(value),false,false
|
||||
ion-range,prop,snaps,boolean,false,false,false
|
||||
ion-range,prop,step,number,1,false,false
|
||||
ion-range,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-range,prop,ticks,boolean,true,false,false
|
||||
ion-range,prop,value,number | { lower: number; upper: number; },0,false,false
|
||||
ion-range,event,ionBlur,void,true
|
||||
@@ -1092,6 +1137,7 @@ ion-refresher,prop,pullFactor,number,1,false,false
|
||||
ion-refresher,prop,pullMax,number,this.pullMin + 60,false,false
|
||||
ion-refresher,prop,pullMin,number,60,false,false
|
||||
ion-refresher,prop,snapbackDuration,string,'280ms',false,false
|
||||
ion-refresher,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-refresher,method,cancel,cancel() => Promise<void>
|
||||
ion-refresher,method,complete,complete() => Promise<void>
|
||||
ion-refresher,method,getProgress,getProgress() => Promise<number>
|
||||
@@ -1106,6 +1152,7 @@ ion-refresher-content,prop,refreshingSpinner,"bubbles" | "circles" | "circular"
|
||||
ion-refresher-content,prop,refreshingText,IonicSafeString | string | undefined,undefined,false,false
|
||||
|
||||
ion-reorder,shadow
|
||||
ion-reorder,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-reorder,part,icon
|
||||
|
||||
ion-reorder-group,none
|
||||
@@ -1174,6 +1221,7 @@ ion-searchbar,prop,searchIcon,string | undefined,undefined,false,false
|
||||
ion-searchbar,prop,showCancelButton,"always" | "focus" | "never",'never',false,false
|
||||
ion-searchbar,prop,showClearButton,"always" | "focus" | "never",'always',false,false
|
||||
ion-searchbar,prop,spellcheck,boolean,false,false,false
|
||||
ion-searchbar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-searchbar,prop,type,"email" | "number" | "password" | "search" | "tel" | "text" | "url",'search',false,false
|
||||
ion-searchbar,prop,value,null | string | undefined,'',false,false
|
||||
ion-searchbar,method,getInputElement,getInputElement() => Promise<HTMLInputElement>
|
||||
@@ -1203,6 +1251,7 @@ ion-segment,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-segment,prop,scrollable,boolean,false,false,false
|
||||
ion-segment,prop,selectOnFocus,boolean,false,false,false
|
||||
ion-segment,prop,swipeGesture,boolean,true,false,false
|
||||
ion-segment,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-segment,prop,value,number | string | undefined,undefined,false,false
|
||||
ion-segment,event,ionChange,SegmentChangeEventDetail,true
|
||||
ion-segment,css-prop,--background
|
||||
@@ -1211,6 +1260,7 @@ ion-segment-button,shadow
|
||||
ion-segment-button,prop,disabled,boolean,false,false,false
|
||||
ion-segment-button,prop,layout,"icon-bottom" | "icon-end" | "icon-hide" | "icon-start" | "icon-top" | "label-hide" | undefined,'icon-top',false,false
|
||||
ion-segment-button,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-segment-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-segment-button,prop,type,"button" | "reset" | "submit",'button',false,false
|
||||
ion-segment-button,prop,value,number | string,'ion-sb-' + ids++,false,false
|
||||
ion-segment-button,css-prop,--background
|
||||
@@ -1265,6 +1315,7 @@ ion-select,prop,okText,string,'OK',false,false
|
||||
ion-select,prop,placeholder,string | undefined,undefined,false,false
|
||||
ion-select,prop,selectedText,null | string | undefined,undefined,false,false
|
||||
ion-select,prop,shape,"round" | undefined,undefined,false,false
|
||||
ion-select,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-select,prop,toggleIcon,string | undefined,undefined,false,false
|
||||
ion-select,prop,value,any,undefined,false,false
|
||||
ion-select,method,open,open(event?: UIEvent) => Promise<any>
|
||||
@@ -1314,6 +1365,7 @@ ion-spinner,css-prop,--color
|
||||
ion-split-pane,shadow
|
||||
ion-split-pane,prop,contentId,string | undefined,undefined,false,true
|
||||
ion-split-pane,prop,disabled,boolean,false,false,false
|
||||
ion-split-pane,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-split-pane,prop,when,boolean | string,QUERY['lg'],false,false
|
||||
ion-split-pane,event,ionSplitPaneVisible,{ visible: boolean; },true
|
||||
ion-split-pane,css-prop,--border
|
||||
@@ -1330,6 +1382,7 @@ ion-tab-bar,shadow
|
||||
ion-tab-bar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-tab-bar,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-tab-bar,prop,selectedTab,string | undefined,undefined,false,false
|
||||
ion-tab-bar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-tab-bar,prop,translucent,boolean,false,false,false
|
||||
ion-tab-bar,css-prop,--background
|
||||
ion-tab-bar,css-prop,--border
|
||||
@@ -1345,6 +1398,7 @@ ion-tab-button,prop,rel,string | undefined,undefined,false,false
|
||||
ion-tab-button,prop,selected,boolean,false,false,false
|
||||
ion-tab-button,prop,tab,string | undefined,undefined,false,false
|
||||
ion-tab-button,prop,target,string | undefined,undefined,false,false
|
||||
ion-tab-button,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-tab-button,css-prop,--background
|
||||
ion-tab-button,css-prop,--background-focused
|
||||
ion-tab-button,css-prop,--background-focused-opacity
|
||||
@@ -1398,6 +1452,7 @@ ion-textarea,prop,required,boolean,false,false,false
|
||||
ion-textarea,prop,rows,number | undefined,undefined,false,false
|
||||
ion-textarea,prop,shape,"round" | undefined,undefined,false,false
|
||||
ion-textarea,prop,spellcheck,boolean,false,false,false
|
||||
ion-textarea,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-textarea,prop,value,null | string | undefined,'',false,false
|
||||
ion-textarea,prop,wrap,"hard" | "off" | "soft" | undefined,undefined,false,false
|
||||
ion-textarea,method,getInputElement,getInputElement() => Promise<HTMLTextAreaElement>
|
||||
@@ -1431,6 +1486,7 @@ ion-thumbnail,css-prop,--size
|
||||
ion-title,shadow
|
||||
ion-title,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-title,prop,size,"large" | "small" | undefined,undefined,false,false
|
||||
ion-title,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-title,css-prop,--color
|
||||
|
||||
ion-toast,shadow
|
||||
@@ -1452,6 +1508,7 @@ ion-toast,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-toast,prop,position,"bottom" | "middle" | "top",'bottom',false,false
|
||||
ion-toast,prop,positionAnchor,HTMLElement | string | undefined,undefined,false,false
|
||||
ion-toast,prop,swipeGesture,"vertical" | undefined,undefined,false,false
|
||||
ion-toast,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-toast,prop,translucent,boolean,false,false,false
|
||||
ion-toast,prop,trigger,string | undefined,undefined,false,false
|
||||
ion-toast,method,dismiss,dismiss(data?: any, role?: string) => Promise<boolean>
|
||||
@@ -1501,6 +1558,7 @@ ion-toggle,prop,labelPlacement,"end" | "fixed" | "stacked" | "start",'start',fal
|
||||
ion-toggle,prop,legacy,boolean | undefined,undefined,false,false
|
||||
ion-toggle,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-toggle,prop,name,string,this.inputId,false,false
|
||||
ion-toggle,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-toggle,prop,value,null | string | undefined,'on',false,false
|
||||
ion-toggle,event,ionBlur,void,true
|
||||
ion-toggle,event,ionChange,ToggleChangeEventDetail<any>,true
|
||||
@@ -1524,6 +1582,7 @@ ion-toggle,part,track
|
||||
ion-toolbar,shadow
|
||||
ion-toolbar,prop,color,"danger" | "dark" | "light" | "medium" | "primary" | "secondary" | "success" | "tertiary" | "warning" | string & Record<never, never> | undefined,undefined,false,true
|
||||
ion-toolbar,prop,mode,"ios" | "md",undefined,false,false
|
||||
ion-toolbar,prop,theme,"ios" | "md" | "ionic",undefined,false,false
|
||||
ion-toolbar,css-prop,--background
|
||||
ion-toolbar,css-prop,--border-color
|
||||
ion-toolbar,css-prop,--border-style
|
||||
|
||||
712
core/src/components.d.ts
vendored
712
core/src/components.d.ts
vendored
File diff suppressed because it is too large
Load Diff
@@ -2,18 +2,20 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Listen, Method, Prop, Watch, h } from '@stencil/core';
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
import type { AccordionGroupChangeEventDetail } from './accordion-group-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-accordion-group',
|
||||
styleUrls: {
|
||||
ios: 'accordion-group.ios.scss',
|
||||
md: 'accordion-group.md.scss',
|
||||
ionic: 'accordion-group.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -279,12 +281,12 @@ export class AccordionGroup implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { disabled, readonly, expand } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'accordion-group-disabled': disabled,
|
||||
'accordion-group-readonly': readonly,
|
||||
[`accordion-group-expand-${expand}`]: true,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { addEventListener, getElementRoot, raf, removeEventListener, transitionE
|
||||
import { chevronDown } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
const enum AccordionState {
|
||||
Collapsed = 1 << 0,
|
||||
@@ -14,7 +14,8 @@ const enum AccordionState {
|
||||
}
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot header - Content is placed at the top and is used to
|
||||
* expand or collapse the accordion item.
|
||||
@@ -31,6 +32,7 @@ const enum AccordionState {
|
||||
styleUrls: {
|
||||
ios: 'accordion.ios.scss',
|
||||
md: 'accordion.md.scss',
|
||||
ionic: 'accordion.md.scss',
|
||||
},
|
||||
shadow: {
|
||||
delegatesFocus: true,
|
||||
@@ -402,7 +404,7 @@ export class Accordion implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { disabled, readonly } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const expanded = this.state === AccordionState.Expanded || this.state === AccordionState.Expanding;
|
||||
const headerPart = expanded ? 'header expanded' : 'header';
|
||||
const contentPart = expanded ? 'content expanded' : 'content';
|
||||
@@ -412,7 +414,7 @@ export class Accordion implements ComponentInterface {
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'accordion-expanding': this.state === AccordionState.Expanding,
|
||||
'accordion-expanded': this.state === AccordionState.Expanded,
|
||||
'accordion-collapsing': this.state === AccordionState.Collapsing,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AnimationBuilder, LiteralUnion, Mode } from '../../interface';
|
||||
import type { AnimationBuilder, LiteralUnion, Mode, Theme } from '../../interface';
|
||||
|
||||
export interface ActionSheetOptions {
|
||||
header?: string;
|
||||
@@ -8,7 +8,11 @@ export interface ActionSheetOptions {
|
||||
backdropDismiss?: boolean;
|
||||
translucent?: boolean;
|
||||
animated?: boolean;
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
mode?: Mode;
|
||||
theme?: Theme;
|
||||
keyboardClose?: boolean;
|
||||
id?: string;
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
|
||||
@@ -18,7 +18,7 @@ import {
|
||||
} from '@utils/overlays';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, CssClassMap, FrameworkDelegate, OverlayInterface } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
|
||||
@@ -29,13 +29,15 @@ import { mdEnterAnimation } from './animations/md.enter';
|
||||
import { mdLeaveAnimation } from './animations/md.leave';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-action-sheet',
|
||||
styleUrls: {
|
||||
ios: 'action-sheet.ios.scss',
|
||||
md: 'action-sheet.md.scss',
|
||||
ionic: 'action-sheet.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -314,15 +316,16 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
}
|
||||
|
||||
componentDidLoad() {
|
||||
const mode = getIonMode(this);
|
||||
/**
|
||||
* Only create gesture if:
|
||||
* 1. A gesture does not already exist
|
||||
* 2. App is running in iOS mode
|
||||
* 2. App is running on iOS platform
|
||||
* 3. A wrapper ref exists
|
||||
* 4. A group ref exists
|
||||
*/
|
||||
const { groupEl, wrapperEl } = this;
|
||||
if (!this.gesture && getIonMode(this) === 'ios' && wrapperEl && groupEl) {
|
||||
if (!this.gesture && mode === 'ios' && wrapperEl && groupEl) {
|
||||
readTask(() => {
|
||||
const isScrollable = groupEl.scrollHeight > groupEl.clientHeight;
|
||||
if (!isScrollable) {
|
||||
@@ -356,7 +359,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
|
||||
render() {
|
||||
const { header, htmlAttributes, overlayIndex } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const allButtons = this.getButtons();
|
||||
const cancelButton = allButtons.find((b) => b.role === 'cancel');
|
||||
const buttons = allButtons.filter((b) => b.role !== 'cancel');
|
||||
@@ -373,7 +376,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
zIndex: `${20000 + this.overlayIndex}`,
|
||||
}}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
...getClassMap(this.cssClass),
|
||||
'overlay-hidden': true,
|
||||
'action-sheet-translucent': this.translucent,
|
||||
@@ -412,7 +415,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
{b.icon && <ion-icon icon={b.icon} aria-hidden="true" lazy={false} class="action-sheet-icon" />}
|
||||
{b.text}
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -431,7 +434,7 @@ export class ActionSheet implements ComponentInterface, OverlayInterface {
|
||||
)}
|
||||
{cancelButton.text}
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { AnimationBuilder, LiteralUnion, Mode, TextFieldTypes } from '../../interface';
|
||||
import type { AnimationBuilder, LiteralUnion, Mode, TextFieldTypes, Theme } from '../../interface';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
|
||||
export interface AlertOptions {
|
||||
@@ -13,7 +13,12 @@ export interface AlertOptions {
|
||||
animated?: boolean;
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
mode?: Mode;
|
||||
theme?: Theme;
|
||||
|
||||
keyboardClose?: boolean;
|
||||
id?: string;
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import { sanitizeDOMString } from '@utils/sanitization';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, CssClassMap, OverlayInterface, FrameworkDelegate } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
@@ -35,13 +35,15 @@ import { mdLeaveAnimation } from './animations/md.leave';
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-alert',
|
||||
styleUrls: {
|
||||
ios: 'alert.ios.scss',
|
||||
md: 'alert.md.scss',
|
||||
ionic: 'alert.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -533,7 +535,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
|
||||
private renderCheckbox() {
|
||||
const inputs = this.processedInputs;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
if (inputs.length === 0) {
|
||||
return null;
|
||||
@@ -565,7 +567,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
</div>
|
||||
<div class="alert-checkbox-label">{i.label}</div>
|
||||
</div>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -682,7 +684,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
|
||||
private renderAlertButtons() {
|
||||
const buttons = this.processedButtons;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const alertButtonGroupClass = {
|
||||
'alert-button-group': true,
|
||||
'alert-button-group-vertical': buttons.length > 2,
|
||||
@@ -699,7 +701,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
onClick={() => this.buttonClick(button)}
|
||||
>
|
||||
<span class="alert-button-inner">{button.text}</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
@@ -721,7 +723,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
|
||||
render() {
|
||||
const { overlayIndex, header, subHeader, message, htmlAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const hdrId = `alert-${overlayIndex}-hdr`;
|
||||
const subHdrId = `alert-${overlayIndex}-sub-hdr`;
|
||||
const msgId = `alert-${overlayIndex}-msg`;
|
||||
@@ -746,7 +748,7 @@ export class Alert implements ComponentInterface, OverlayInterface {
|
||||
}}
|
||||
class={{
|
||||
...getClassMap(this.cssClass),
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'overlay-hidden': true,
|
||||
'alert-translucent': this.translucent,
|
||||
}}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { printIonWarning } from '@utils/logging';
|
||||
import { isPlatform } from '@utils/platform';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-app',
|
||||
@@ -78,11 +78,11 @@ export class App implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'ion-page': true,
|
||||
'force-statusbar-padding': config.getBoolean('_forceStatusbarPadding'),
|
||||
}}
|
||||
|
||||
@@ -1,20 +1,29 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-avatar',
|
||||
styleUrls: {
|
||||
ios: 'avatar.ios.scss',
|
||||
md: 'avatar.md.scss',
|
||||
ionic: 'avatar.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
export class Avatar implements ComponentInterface {
|
||||
render() {
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host class={getIonMode(this)}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -7,11 +7,12 @@ import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
import { arrowBackSharp, chevronBack } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML button element that wraps all child elements.
|
||||
* @part icon - The back button icon (uses ion-icon).
|
||||
@@ -22,6 +23,7 @@ import type { AnimationBuilder, Color } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'back-button.ios.scss',
|
||||
md: 'back-button.md.scss',
|
||||
ionic: 'back-button.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -84,7 +86,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
return icon;
|
||||
}
|
||||
|
||||
if (getIonMode(this) === 'ios') {
|
||||
if (getIonTheme(this) === 'ios') {
|
||||
// default ios back button icon
|
||||
return config.get('backButtonIcon', chevronBack);
|
||||
}
|
||||
@@ -94,7 +96,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
}
|
||||
|
||||
get backButtonText() {
|
||||
const defaultBackButtonText = getIonMode(this) === 'ios' ? 'Back' : null;
|
||||
const defaultBackButtonText = getIonTheme(this) === 'ios' ? 'Back' : null;
|
||||
return this.text != null ? this.text : config.get('backButtonText', defaultBackButtonText);
|
||||
}
|
||||
|
||||
@@ -135,14 +137,14 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
inheritedAttributes,
|
||||
} = this;
|
||||
const showBackButton = defaultHref !== undefined;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const ariaLabel = inheritedAttributes['aria-label'] || backButtonText || 'back';
|
||||
|
||||
return (
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
button: true, // ion-buttons target .button
|
||||
'back-button-disabled': disabled,
|
||||
'back-button-has-icon-only': hasIconOnly,
|
||||
@@ -170,7 +172,7 @@ export class BackButton implements ComponentInterface, ButtonInterface {
|
||||
</span>
|
||||
)}
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
|
||||
</button>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -2,13 +2,17 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Event, Host, Listen, Prop, h } from '@stencil/core';
|
||||
import { GESTURE_CONTROLLER } from '@utils/gesture';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-backdrop',
|
||||
styleUrls: {
|
||||
ios: 'backdrop.ios.scss',
|
||||
md: 'backdrop.md.scss',
|
||||
ionic: 'backdrop.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -63,13 +67,13 @@ export class Backdrop implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
tabindex="-1"
|
||||
aria-hidden="true"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'backdrop-hide': !this.visible,
|
||||
'backdrop-no-tappable': !this.tappable,
|
||||
}}
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-badge',
|
||||
styleUrls: {
|
||||
ios: 'badge.ios.scss',
|
||||
md: 'badge.md.scss',
|
||||
ionic: 'badge.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -25,11 +27,11 @@ export class Badge implements ComponentInterface {
|
||||
@Prop({ reflect: true }) color?: Color;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -5,14 +5,15 @@ import { inheritAriaAttributes } from '@utils/helpers';
|
||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
import { chevronForwardOutline, ellipsisHorizontal } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
import type { BreadcrumbCollapsedClickEventDetail } from './breadcrumb-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML anchor or div element that wraps all child elements.
|
||||
* @part separator - The separator element between each breadcrumb.
|
||||
@@ -23,6 +24,7 @@ import type { BreadcrumbCollapsedClickEventDetail } from './breadcrumb-interface
|
||||
styleUrls: {
|
||||
ios: 'breadcrumb.ios.scss',
|
||||
md: 'breadcrumb.md.scss',
|
||||
ionic: 'breadcrumb.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -168,7 +170,7 @@ export class Breadcrumb implements ComponentInterface {
|
||||
// Links can still be tabbed to when set to disabled if they have an href
|
||||
// in order to truly disable them we can keep it as an anchor but remove the href
|
||||
const href = disabled ? undefined : this.href;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const attrs =
|
||||
TagType === 'span'
|
||||
? {}
|
||||
@@ -188,7 +190,7 @@ export class Breadcrumb implements ComponentInterface {
|
||||
onClick={(ev: Event) => openURL(href, ev, routerDirection, routerAnimation)}
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'breadcrumb-active': active,
|
||||
'breadcrumb-collapsed': collapsed,
|
||||
'breadcrumb-disabled': disabled,
|
||||
@@ -233,7 +235,7 @@ export class Breadcrumb implements ComponentInterface {
|
||||
*/
|
||||
<span class="breadcrumb-separator" part="separator" aria-hidden="true">
|
||||
<slot name="separator">
|
||||
{mode === 'ios' ? (
|
||||
{theme === 'ios' ? (
|
||||
<ion-icon icon={chevronForwardOutline} lazy={false} flip-rtl></ion-icon>
|
||||
) : (
|
||||
<span>/</span>
|
||||
|
||||
@@ -2,19 +2,20 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Listen, Prop, State, Watch, h } from '@stencil/core';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
import type { BreadcrumbCollapsedClickEventDetail } from '../breadcrumb/breadcrumb-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
*
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-breadcrumbs',
|
||||
styleUrls: {
|
||||
ios: 'breadcrumbs.ios.scss',
|
||||
md: 'breadcrumbs.md.scss',
|
||||
ionic: 'breadcrumbs.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -170,12 +171,12 @@ export class Breadcrumbs implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { color, collapsed } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-toolbar': hostContext('ion-toolbar', this.el),
|
||||
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
|
||||
'breadcrumbs-collapsed': collapsed,
|
||||
|
||||
1
core/src/components/button/button.ionic.scss
Normal file
1
core/src/components/button/button.ionic.scss
Normal file
@@ -0,0 +1 @@
|
||||
@import "./button";
|
||||
@@ -6,12 +6,13 @@ import { inheritAriaAttributes, hasShadowDom } from '@utils/helpers';
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot icon-only - Should be used on an icon in a button that has no text.
|
||||
@@ -25,6 +26,7 @@ import type { RouterDirection } from '../router/utils/interface';
|
||||
styleUrls: {
|
||||
ios: 'button.ios.scss',
|
||||
md: 'button.md.scss',
|
||||
ionic: 'button.ionic.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -296,7 +298,8 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
};
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
const {
|
||||
buttonType,
|
||||
type,
|
||||
@@ -312,6 +315,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
strong,
|
||||
inheritedAttributes,
|
||||
} = this;
|
||||
|
||||
const finalSize = size === undefined && this.inItem ? 'small' : size;
|
||||
const TagType = href === undefined ? 'button' : ('a' as any);
|
||||
const attrs =
|
||||
@@ -348,7 +352,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
onClick={this.handleClick}
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[buttonType]: true,
|
||||
[`${buttonType}-${expand}`]: expand !== undefined,
|
||||
[`${buttonType}-${finalSize}`]: finalSize !== undefined,
|
||||
@@ -379,7 +383,7 @@ export class Button implements ComponentInterface, AnchorInterface, ButtonInterf
|
||||
<slot></slot>
|
||||
<slot name="end"></slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect type={this.rippleType}></ion-ripple-effect>}
|
||||
</TagType>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -1,13 +1,17 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-buttons',
|
||||
styleUrls: {
|
||||
ios: 'buttons.ios.scss',
|
||||
md: 'buttons.md.scss',
|
||||
ionic: 'buttons.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -27,11 +31,11 @@ export class Buttons implements ComponentInterface {
|
||||
@Prop() collapse = false;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
['buttons-collapse']: this.collapse,
|
||||
}}
|
||||
></Host>
|
||||
|
||||
@@ -1,28 +1,30 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-card-content',
|
||||
styleUrls: {
|
||||
ios: 'card-content.ios.scss',
|
||||
md: 'card-content.md.scss',
|
||||
ionic: 'card-content.md.scss',
|
||||
},
|
||||
})
|
||||
export class CardContent implements ComponentInterface {
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`card-content-${mode}`]: true,
|
||||
[`card-content-${theme}`]: true,
|
||||
}}
|
||||
></Host>
|
||||
);
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-card-header',
|
||||
styleUrls: {
|
||||
ios: 'card-header.ios.scss',
|
||||
md: 'card-header.md.scss',
|
||||
ionic: 'card-header.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -32,13 +34,13 @@ export class CardHeader implements ComponentInterface {
|
||||
@Prop() translucent = false;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
'card-header-translucent': this.translucent,
|
||||
'ion-inherit-color': true,
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-card-subtitle',
|
||||
styleUrls: {
|
||||
ios: 'card-subtitle.ios.scss',
|
||||
md: 'card-subtitle.md.scss',
|
||||
ionic: 'card-subtitle.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -25,14 +27,14 @@ export class CardSubtitle implements ComponentInterface {
|
||||
@Prop({ reflect: true }) color?: Color;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="heading"
|
||||
aria-level="3"
|
||||
class={createColorClasses(this.color, {
|
||||
'ion-inherit-color': true,
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-card-title',
|
||||
styleUrls: {
|
||||
ios: 'card-title.ios.scss',
|
||||
md: 'card-title.md.scss',
|
||||
ionic: 'card-title.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -25,14 +27,14 @@ export class CardTitle implements ComponentInterface {
|
||||
@Prop({ reflect: true }) color?: Color;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="heading"
|
||||
aria-level="2"
|
||||
class={createColorClasses(this.color, {
|
||||
'ion-inherit-color': true,
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -5,12 +5,13 @@ import type { Attributes } from '@utils/helpers';
|
||||
import { inheritAttributes } from '@utils/helpers';
|
||||
import { createColorClasses, openURL } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color, Mode } from '../../interface';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color, Theme } from '../../interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML button, anchor, or div element that wraps all child elements.
|
||||
*/
|
||||
@@ -19,6 +20,7 @@ import type { RouterDirection } from '../router/utils/interface';
|
||||
styleUrls: {
|
||||
ios: 'card.ios.scss',
|
||||
md: 'card.md.scss',
|
||||
ionic: 'card.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -95,7 +97,7 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
return this.href !== undefined || this.button;
|
||||
}
|
||||
|
||||
private renderCard(mode: Mode) {
|
||||
private renderCard(theme: Theme) {
|
||||
const clickable = this.isClickable();
|
||||
|
||||
if (!clickable) {
|
||||
@@ -123,22 +125,23 @@ export class Card implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
onClick={(ev: Event) => openURL(href, ev, routerDirection, routerAnimation)}
|
||||
>
|
||||
<slot></slot>
|
||||
{clickable && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{clickable && theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</TagType>
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'card-disabled': this.disabled,
|
||||
'ion-activatable': this.isClickable(),
|
||||
})}
|
||||
>
|
||||
{this.renderCard(mode)}
|
||||
{this.renderCard(theme)}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
154
core/src/components/checkbox/checkbox.ionic.scss
Normal file
154
core/src/components/checkbox/checkbox.ionic.scss
Normal file
@@ -0,0 +1,154 @@
|
||||
@import "./checkbox";
|
||||
@import "./checkbox.ionic.vars";
|
||||
|
||||
// Material Design Checkbox
|
||||
// --------------------------------------------------
|
||||
|
||||
:host {
|
||||
// Border
|
||||
--border-radius: calc(var(--size) * 0.125);
|
||||
--border-width: #{$checkbox-ionic-icon-border-width};
|
||||
--border-style: #{$checkbox-ionic-icon-border-style};
|
||||
--border-color: #{$checkbox-ionic-icon-border-color-off};
|
||||
--checkmark-width: 1.5;
|
||||
|
||||
// Background
|
||||
--checkbox-background: #{$checkbox-ionic-icon-background-color-off};
|
||||
--checkbox-background-checked: #1068eb;
|
||||
--border-color-checked: #1068eb;
|
||||
|
||||
// Transition
|
||||
--transition: #{background $checkbox-ionic-transition-duration $checkbox-ionic-transition-easing};
|
||||
|
||||
// Size
|
||||
--size: #{$checkbox-ionic-icon-size};
|
||||
|
||||
// margin is required to make room for outline on focus, otherwise the outline may get cut off
|
||||
@include margin($checkbox-ionic-outline-width);
|
||||
}
|
||||
|
||||
.checkbox-icon path {
|
||||
stroke-dasharray: 30;
|
||||
stroke-dashoffset: 30;
|
||||
}
|
||||
|
||||
// Checkbox: Focused
|
||||
// --------------------------------------------------------
|
||||
|
||||
:host(.ion-focusable) .checkbox-icon {
|
||||
outline: $checkbox-ionic-outline-width solid $checkbox-ionic-outline-color;
|
||||
}
|
||||
|
||||
:host(.ion-focusable.checkbox-checked) .checkbox-icon,
|
||||
:host(.ion-focusable.checkbox-indeterminate) .checkbox-icon {
|
||||
outline: $checkbox-ionic-outline-width solid $checkbox-ionic-outline-color;
|
||||
}
|
||||
|
||||
// unchecked checkbox with `required` property set to true
|
||||
:host(.ion-focusable.checkbox-required:not(.checkbox-checked):not(.checkbox-indeterminate)) .checkbox-icon {
|
||||
outline-color: #ffafaf;
|
||||
}
|
||||
|
||||
// Checkbox: Hover
|
||||
// --------------------------------------------------------
|
||||
|
||||
@media (any-hover: hover) {
|
||||
:host(:hover) .checkbox-icon {
|
||||
background-color: #ececec;
|
||||
}
|
||||
|
||||
:host(:hover.checkbox-checked) .checkbox-icon,
|
||||
:host(:hover.checkbox-indeterminate) .checkbox-icon {
|
||||
background-color: #1061da;
|
||||
}
|
||||
}
|
||||
|
||||
// Checkbox: Active
|
||||
// --------------------------------------------------------
|
||||
|
||||
:host(.ion-activated) .checkbox-icon {
|
||||
background-color: #e3e3e3;
|
||||
}
|
||||
|
||||
:host(.ion-activated.checkbox-checked) .checkbox-icon,
|
||||
:host(.ion-activated.checkbox-indeterminate) .checkbox-icon {
|
||||
background-color: #105ed1;
|
||||
}
|
||||
|
||||
// Material Design Checkbox: Checked / Indeterminate
|
||||
// --------------------------------------------------------
|
||||
|
||||
:host(.checkbox-checked) .checkbox-icon path,
|
||||
:host(.checkbox-indeterminate) .checkbox-icon path {
|
||||
stroke-dashoffset: 0;
|
||||
|
||||
transition: stroke-dashoffset 90ms linear 90ms;
|
||||
}
|
||||
|
||||
// Material Design Checkbox: Disabled
|
||||
// --------------------------------------------------------
|
||||
// The checkbox itself should use the disabled
|
||||
// opacity set by its spec, while the label
|
||||
// should match the other form controls
|
||||
|
||||
:host(.legacy-checkbox.checkbox-disabled),
|
||||
:host(.checkbox-disabled) .label-text-wrapper {
|
||||
opacity: $checkbox-ionic-disabled-opacity;
|
||||
}
|
||||
|
||||
:host(.checkbox-disabled) .native-wrapper {
|
||||
opacity: $checkbox-ionic-icon-disabled-opacity;
|
||||
}
|
||||
|
||||
:host(.checkbox-disabled.checkbox-checked) .checkbox-icon {
|
||||
border-width: 0;
|
||||
|
||||
background-color: #c9c9c9;
|
||||
}
|
||||
|
||||
:host(.checkbox-disabled.checkbox-indeterminate) .checkbox-icon {
|
||||
border-width: 0;
|
||||
|
||||
background-color: #74aafc;
|
||||
}
|
||||
|
||||
// disabled, unchecked checkbox
|
||||
:host(.checkbox-disabled) .checkbox-icon {
|
||||
border-color: #c9c9c9;
|
||||
|
||||
background-color: #f5f5f5;
|
||||
}
|
||||
|
||||
// unchecked checkbox with `required` property set to true
|
||||
:host(.checkbox-required:not(.checkbox-checked):not(.checkbox-indeterminate)) {
|
||||
.checkbox-icon {
|
||||
border-color: #f72c2c;
|
||||
}
|
||||
}
|
||||
|
||||
// Material Design Checkbox Within An Item
|
||||
// TODO(FW-3100): remove this
|
||||
// --------------------------------------------------------
|
||||
|
||||
:host(.in-item.legacy-checkbox) {
|
||||
// end position by default
|
||||
@include margin(
|
||||
$checkbox-ionic-item-end-margin-top,
|
||||
$checkbox-ionic-item-end-margin-end,
|
||||
$checkbox-ionic-item-end-margin-bottom,
|
||||
$checkbox-ionic-item-end-margin-start
|
||||
);
|
||||
|
||||
display: block;
|
||||
|
||||
position: static;
|
||||
}
|
||||
|
||||
:host(.in-item.legacy-checkbox[slot="start"]) {
|
||||
@include margin(
|
||||
$checkbox-ionic-item-start-margin-top,
|
||||
$checkbox-ionic-item-start-margin-end,
|
||||
$checkbox-ionic-item-start-margin-bottom,
|
||||
$checkbox-ionic-item-start-margin-start
|
||||
);
|
||||
}
|
||||
70
core/src/components/checkbox/checkbox.ionic.vars.scss
Normal file
70
core/src/components/checkbox/checkbox.ionic.vars.scss
Normal file
@@ -0,0 +1,70 @@
|
||||
@import "../../themes/ionic.globals.md";
|
||||
@import "../item/item.md.vars";
|
||||
|
||||
// Material Design Checkbox
|
||||
// --------------------------------------------------
|
||||
|
||||
/// @prop - Opacity of the disabled checkbox label
|
||||
$checkbox-ionic-disabled-opacity: $form-control-md-disabled-opacity !default;
|
||||
|
||||
/// @prop - Background color of the checkbox icon when off
|
||||
$checkbox-ionic-icon-background-color-off: $item-md-background !default;
|
||||
|
||||
/// @prop - Size of the checkbox icon
|
||||
/// The icon size does not use dynamic font
|
||||
/// because it does not scale in native.
|
||||
$checkbox-ionic-icon-size: 24px !default;
|
||||
|
||||
/// @prop - Border width of the checkbox icon
|
||||
$checkbox-ionic-icon-border-width: 1px !default;
|
||||
|
||||
/// @prop - Border style of the checkbox icon
|
||||
$checkbox-ionic-icon-border-style: solid !default;
|
||||
|
||||
/// @prop - Border color of the checkbox icon when off
|
||||
$checkbox-ionic-icon-border-color-off: #9a9a9a !default;
|
||||
|
||||
/// @prop - Outline width of the checkbox
|
||||
$checkbox-ionic-outline-width: 2px !default;
|
||||
|
||||
/// @prop - Outline color of the checkbox
|
||||
$checkbox-ionic-outline-color: #9ec4fd !default;
|
||||
|
||||
/// @prop - Transition duration of the checkbox
|
||||
$checkbox-ionic-transition-duration: 180ms !default;
|
||||
|
||||
/// @prop - Transition easing of the checkbox
|
||||
$checkbox-ionic-transition-easing: cubic-bezier(0.4, 0, 0.2, 1) !default;
|
||||
|
||||
/// @prop - Margin top of the start checkbox item
|
||||
$checkbox-ionic-item-start-margin-top: 18px !default;
|
||||
|
||||
/// @prop - Margin end of the start checkbox item
|
||||
$checkbox-ionic-item-start-margin-end: 36px !default;
|
||||
|
||||
/// @prop - Margin bottom of the start checkbox item
|
||||
$checkbox-ionic-item-start-margin-bottom: $checkbox-ionic-item-start-margin-top !default;
|
||||
|
||||
/// @prop - Margin start of the start checkbox item
|
||||
$checkbox-ionic-item-start-margin-start: 4px !default;
|
||||
|
||||
/// @prop - Margin top of the end checkbox item
|
||||
$checkbox-ionic-item-end-margin-top: 18px !default;
|
||||
|
||||
/// @prop - Margin end of the end checkbox item
|
||||
$checkbox-ionic-item-end-margin-end: 0 !default;
|
||||
|
||||
/// @prop - Margin bottom of the end checkbox item
|
||||
$checkbox-ionic-item-end-margin-bottom: $checkbox-ionic-item-end-margin-top !default;
|
||||
|
||||
/// @prop - Margin start of the end checkbox item
|
||||
$checkbox-ionic-item-end-margin-start: 0 !default;
|
||||
|
||||
/// @prop - Opacity of the disabled checkbox
|
||||
/// This value is used because the checkbox color is set to
|
||||
/// `rgb(0, 0, 0, 0.60)` when enabled and we need it to be
|
||||
/// `rgb(0, 0, 0, 0.38)` when disabled but the disabled
|
||||
/// opacity is applied on top of the transparent color so
|
||||
/// this opacity gets us the equivalent of applying `0.38`
|
||||
/// on top of an opaque checkbox `rgb(0, 0, 0, 1.0)`
|
||||
$checkbox-ionic-icon-disabled-opacity: 0.63 !default;
|
||||
@@ -7,13 +7,14 @@ import { getAriaLabel, inheritAriaAttributes, renderHiddenInput } from '@utils/h
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { Color, Mode, StyleEventDetail } from '../../interface';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail, Theme } from '../../interface';
|
||||
|
||||
import type { CheckboxChangeEventDetail } from './checkbox-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - The label text to associate with the checkbox. Use the "labelPlacement" property to control where the label is placed relative to the checkbox.
|
||||
*
|
||||
@@ -26,6 +27,7 @@ import type { CheckboxChangeEventDetail } from './checkbox-interface';
|
||||
styleUrls: {
|
||||
ios: 'checkbox.ios.scss',
|
||||
md: 'checkbox.md.scss',
|
||||
ionic: 'checkbox.ionic.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -68,6 +70,11 @@ export class Checkbox implements ComponentInterface {
|
||||
*/
|
||||
@Prop() disabled = false;
|
||||
|
||||
/**
|
||||
* If `true`, the checkbox will be presented with an error style when it is unchecked.
|
||||
*/
|
||||
@Prop() required = false;
|
||||
|
||||
/**
|
||||
* The value of the checkbox does not mean if it's checked or not, use the `checked`
|
||||
* property for that.
|
||||
@@ -241,26 +248,31 @@ export class Checkbox implements ComponentInterface {
|
||||
justify,
|
||||
labelPlacement,
|
||||
name,
|
||||
required,
|
||||
value,
|
||||
alignment,
|
||||
} = this;
|
||||
const mode = getIonMode(this);
|
||||
const path = getSVGPath(mode, indeterminate);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
const path = getSVGPath(theme, indeterminate);
|
||||
|
||||
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'checkbox-checked': checked,
|
||||
'checkbox-disabled': disabled,
|
||||
'checkbox-indeterminate': indeterminate,
|
||||
'checkbox-required': required,
|
||||
interactive: true,
|
||||
[`checkbox-justify-${justify}`]: true,
|
||||
[`checkbox-alignment-${alignment}`]: true,
|
||||
[`checkbox-label-placement-${labelPlacement}`]: true,
|
||||
'ion-activatable': true,
|
||||
'ion-focusable': true,
|
||||
})}
|
||||
onClick={this.onClick}
|
||||
>
|
||||
@@ -278,6 +290,8 @@ export class Checkbox implements ComponentInterface {
|
||||
onFocus={() => this.onFocus()}
|
||||
onBlur={() => this.onBlur()}
|
||||
ref={(focusEl) => (this.focusEl = focusEl)}
|
||||
aria-checked={indeterminate ? 'mixed' : `${checked}`}
|
||||
required={required}
|
||||
{...inheritedAttributes}
|
||||
/>
|
||||
<div
|
||||
@@ -324,9 +338,9 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
}
|
||||
|
||||
const { color, checked, disabled, el, getSVGPath, indeterminate, inputId, name, value } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { label, labelId, labelText } = getAriaLabel(el, inputId);
|
||||
const path = getSVGPath(mode, indeterminate);
|
||||
const path = getSVGPath(theme, indeterminate);
|
||||
|
||||
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
||||
|
||||
@@ -337,7 +351,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
aria-hidden={disabled ? 'true' : null}
|
||||
role="checkbox"
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'checkbox-checked': checked,
|
||||
'checkbox-disabled': disabled,
|
||||
@@ -365,14 +379,14 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
);
|
||||
}
|
||||
|
||||
private getSVGPath(mode: Mode, indeterminate: boolean): HTMLElement {
|
||||
private getSVGPath(theme: Theme, indeterminate: boolean): HTMLElement {
|
||||
let path = indeterminate ? (
|
||||
<path d="M6 12L18 12" part="mark" />
|
||||
) : (
|
||||
<path d="M5.9,12.5l3.8,3.8l8.8-8.8" part="mark" />
|
||||
);
|
||||
|
||||
if (mode === 'md') {
|
||||
if (theme === 'md') {
|
||||
path = indeterminate ? (
|
||||
<path d="M2 12H22" part="mark" />
|
||||
) : (
|
||||
@@ -380,6 +394,14 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
);
|
||||
}
|
||||
|
||||
if (theme === 'ionic') {
|
||||
path = indeterminate ? (
|
||||
<path d="M6.5 12H17.5" stroke-linecap="round" part="mark" />
|
||||
) : (
|
||||
<path d="M6 12.5L10 16.5L18.5 8" stroke-linecap="round" stroke-linejoin="round" part="mark" />
|
||||
);
|
||||
}
|
||||
|
||||
return path;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-chip',
|
||||
styleUrls: {
|
||||
ios: 'chip.ios.scss',
|
||||
md: 'chip.md.scss',
|
||||
ionic: 'chip.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -35,20 +37,20 @@ export class Chip implements ComponentInterface {
|
||||
@Prop() disabled = false;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
aria-disabled={this.disabled ? 'true' : null}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'chip-outline': this.outline,
|
||||
'chip-disabled': this.disabled,
|
||||
'ion-activatable': true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Listen, Prop, forceUpdate, h } from '@stencil/core';
|
||||
import { matchBreakpoint } from '@utils/media';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
const win = typeof (window as any) !== 'undefined' ? (window as any) : undefined;
|
||||
// eslint-disable-next-line @typescript-eslint/prefer-optional-chain
|
||||
@@ -249,11 +249,11 @@ export class Col implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const isRTL = document.dir === 'rtl';
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
}}
|
||||
style={{
|
||||
...this.calculateOffset(isRTL),
|
||||
|
||||
@@ -5,7 +5,7 @@ import { isPlatform } from '@utils/platform';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
import type { ScrollBaseDetail, ScrollDetail } from './content-interface';
|
||||
@@ -425,9 +425,9 @@ export class Content implements ComponentInterface {
|
||||
render() {
|
||||
const { isMainContent, scrollX, scrollY, el } = this;
|
||||
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const forceOverscroll = this.shouldForceOverscroll();
|
||||
const transitionShadow = mode === 'ios';
|
||||
const transitionShadow = theme === 'ios';
|
||||
const TagType = isMainContent ? 'main' : ('div' as any);
|
||||
|
||||
this.resize();
|
||||
@@ -435,7 +435,7 @@ export class Content implements ComponentInterface {
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'content-sizing': hostContext('ion-popover', this.el),
|
||||
overscroll: forceOverscroll,
|
||||
[`content-${rtl}`]: true,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { componentOnReady, addEventListener } from '@utils/helpers';
|
||||
import { printIonError } from '@utils/logging';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
import type { DatetimePresentation } from '../datetime/datetime-interface';
|
||||
import { getToday } from '../datetime/utils/data';
|
||||
@@ -12,7 +12,8 @@ import { getMonthAndYear, getMonthDayAndYear, getLocalizedDateTime, getLocalized
|
||||
import { getHourCycle } from '../datetime/utils/helpers';
|
||||
import { parseDate } from '../datetime/utils/parse';
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot date-target - Content displayed inside of the date button.
|
||||
* @slot time-target - Content displayed inside of the time button.
|
||||
@@ -413,12 +414,12 @@ export class DatetimeButton implements ComponentInterface {
|
||||
render() {
|
||||
const { color, dateText, timeText, selectedButton, datetimeActive, disabled } = this;
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`${selectedButton}-active`]: datetimeActive,
|
||||
['datetime-button-disabled']: disabled,
|
||||
})}
|
||||
@@ -434,7 +435,7 @@ export class DatetimeButton implements ComponentInterface {
|
||||
ref={(el) => (this.dateTargetEl = el)}
|
||||
>
|
||||
<slot name="date-target">{dateText}</slot>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
)}
|
||||
|
||||
@@ -449,7 +450,7 @@ export class DatetimeButton implements ComponentInterface {
|
||||
ref={(el) => (this.timeTargetEl = el)}
|
||||
>
|
||||
<slot name="time-target">{timeText}</slot>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
)}
|
||||
</Host>
|
||||
|
||||
@@ -7,8 +7,8 @@ import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
import { caretDownSharp, caretUpSharp, chevronBack, chevronDown, chevronForward } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { Color, Mode, StyleEventDetail } from '../../interface';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail, Theme } from '../../interface';
|
||||
import type { PickerColumnItem } from '../picker-column-internal/picker-column-internal-interfaces';
|
||||
|
||||
import type {
|
||||
@@ -70,7 +70,8 @@ import {
|
||||
} from './utils/state';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot title - The title of the datetime.
|
||||
* @slot buttons - The buttons in the datetime.
|
||||
@@ -98,6 +99,7 @@ import {
|
||||
styleUrls: {
|
||||
ios: 'datetime.ios.scss',
|
||||
md: 'datetime.md.scss',
|
||||
ionic: 'datetime.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -2048,10 +2050,10 @@ export class Datetime implements ComponentInterface {
|
||||
* Grid Render Methods
|
||||
*/
|
||||
|
||||
private renderCalendarHeader(mode: Mode) {
|
||||
private renderCalendarHeader(theme: Theme) {
|
||||
const { disabled } = this;
|
||||
const expandedIcon = mode === 'ios' ? chevronDown : caretUpSharp;
|
||||
const collapsedIcon = mode === 'ios' ? chevronForward : caretDownSharp;
|
||||
const expandedIcon = theme === 'ios' ? chevronDown : caretUpSharp;
|
||||
const collapsedIcon = theme === 'ios' ? chevronForward : caretDownSharp;
|
||||
|
||||
const prevMonthDisabled = disabled || isPrevMonthDisabled(this.workingParts, this.minParts, this.maxParts);
|
||||
const nextMonthDisabled = disabled || isNextMonthDisabled(this.workingParts, this.maxParts);
|
||||
@@ -2129,7 +2131,7 @@ export class Datetime implements ComponentInterface {
|
||||
</div>
|
||||
</div>
|
||||
<div class="calendar-days-of-week" aria-hidden="true">
|
||||
{getDaysOfWeek(this.locale, mode, this.firstDayOfWeek % 7).map((d) => {
|
||||
{getDaysOfWeek(this.locale, theme, this.firstDayOfWeek % 7).map((d) => {
|
||||
return <div class="day-of-week">{d}</div>;
|
||||
})}
|
||||
</div>
|
||||
@@ -2336,10 +2338,10 @@ export class Datetime implements ComponentInterface {
|
||||
</div>
|
||||
);
|
||||
}
|
||||
private renderCalendar(mode: Mode) {
|
||||
private renderCalendar(theme: Theme) {
|
||||
return (
|
||||
<div class="datetime-calendar" key="datetime-calendar">
|
||||
{this.renderCalendarHeader(mode)}
|
||||
{this.renderCalendarHeader(theme)}
|
||||
{this.renderCalendarBody()}
|
||||
</div>
|
||||
);
|
||||
@@ -2494,7 +2496,7 @@ export class Datetime implements ComponentInterface {
|
||||
* All presentation types are rendered from here.
|
||||
*/
|
||||
|
||||
private renderDatetime(mode: Mode) {
|
||||
private renderDatetime(theme: Theme) {
|
||||
const { presentation, preferWheel } = this;
|
||||
|
||||
/**
|
||||
@@ -2510,7 +2512,7 @@ export class Datetime implements ComponentInterface {
|
||||
case 'date-time':
|
||||
return [
|
||||
this.renderHeader(),
|
||||
this.renderCalendar(mode),
|
||||
this.renderCalendar(theme),
|
||||
this.renderCalendarViewMonthYearPicker(),
|
||||
this.renderTime(),
|
||||
this.renderFooter(),
|
||||
@@ -2519,7 +2521,7 @@ export class Datetime implements ComponentInterface {
|
||||
return [
|
||||
this.renderHeader(),
|
||||
this.renderTime(),
|
||||
this.renderCalendar(mode),
|
||||
this.renderCalendar(theme),
|
||||
this.renderCalendarViewMonthYearPicker(),
|
||||
this.renderFooter(),
|
||||
];
|
||||
@@ -2532,7 +2534,7 @@ export class Datetime implements ComponentInterface {
|
||||
default:
|
||||
return [
|
||||
this.renderHeader(),
|
||||
this.renderCalendar(mode),
|
||||
this.renderCalendar(theme),
|
||||
this.renderCalendarViewMonthYearPicker(),
|
||||
this.renderFooter(),
|
||||
];
|
||||
@@ -2553,7 +2555,7 @@ export class Datetime implements ComponentInterface {
|
||||
size,
|
||||
isGridStyle,
|
||||
} = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const isMonthAndYearPresentation =
|
||||
presentation === 'year' || presentation === 'month' || presentation === 'month-year';
|
||||
const shouldShowMonthAndYear = showMonthAndYear || isMonthAndYearPresentation;
|
||||
@@ -2570,7 +2572,7 @@ export class Datetime implements ComponentInterface {
|
||||
onBlur={this.onBlur}
|
||||
class={{
|
||||
...createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
['datetime-readonly']: readonly,
|
||||
['datetime-disabled']: disabled,
|
||||
'show-month-and-year': shouldShowMonthAndYear,
|
||||
@@ -2582,7 +2584,7 @@ export class Datetime implements ComponentInterface {
|
||||
}),
|
||||
}}
|
||||
>
|
||||
{this.renderDatetime(mode)}
|
||||
{this.renderDatetime(theme)}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { Mode } from '../../../interface';
|
||||
import type { Theme } from '../../../interface';
|
||||
import type { PickerColumnItem } from '../../picker-column-internal/picker-column-internal-interfaces';
|
||||
import type { DatetimeParts, DatetimeHourCycle } from '../datetime-interface';
|
||||
|
||||
@@ -65,13 +65,13 @@ const hour24 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 1
|
||||
* MD should display days such as "M"
|
||||
* or "T".
|
||||
*/
|
||||
export const getDaysOfWeek = (locale: string, mode: Mode, firstDayOfWeek = 0) => {
|
||||
export const getDaysOfWeek = (locale: string, theme: Theme, firstDayOfWeek = 0) => {
|
||||
/**
|
||||
* Nov 1st, 2020 starts on a Sunday.
|
||||
* ion-datetime assumes weeks start on Sunday,
|
||||
* but is configurable via `firstDayOfWeek`.
|
||||
*/
|
||||
const weekdayFormat = mode === 'ios' ? 'short' : 'narrow';
|
||||
const weekdayFormat = theme === 'ios' ? 'short' : 'narrow';
|
||||
const intl = new Intl.DateTimeFormat(locale, { weekday: weekdayFormat });
|
||||
const startDate = new Date('11/01/2020');
|
||||
const daysOfWeek = [];
|
||||
|
||||
@@ -6,12 +6,13 @@ import type { Attributes } from '@utils/helpers';
|
||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
import { close } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML button or anchor element that wraps all child elements.
|
||||
* @part close-icon - The close icon that is displayed when a fab list opens (uses ion-icon).
|
||||
@@ -21,6 +22,7 @@ import type { RouterDirection } from '../router/utils/interface';
|
||||
styleUrls: {
|
||||
ios: 'fab-button.ios.scss',
|
||||
md: 'fab-button.md.scss',
|
||||
ionic: 'fab-button.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -153,7 +155,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
render() {
|
||||
const { el, disabled, color, href, activated, show, translucent, size, inheritedAttributes } = this;
|
||||
const inList = hostContext('ion-fab-list', el);
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const TagType = href === undefined ? 'button' : ('a' as any);
|
||||
const attrs =
|
||||
TagType === 'button'
|
||||
@@ -170,7 +172,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
onClick={this.onClick}
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'fab-button-in-list': inList,
|
||||
'fab-button-translucent-in-list': inList && translucent,
|
||||
'fab-button-close-active': activated,
|
||||
@@ -202,7 +204,7 @@ export class FabButton implements ComponentInterface, AnchorInterface, ButtonInt
|
||||
<span class="button-inner">
|
||||
<slot></slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</TagType>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Prop, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-fab-list',
|
||||
@@ -33,11 +33,11 @@ export class FabList implements ComponentInterface {
|
||||
@Prop() side: 'start' | 'end' | 'top' | 'bottom' = 'bottom';
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'fab-list-active': this.activated,
|
||||
[`fab-list-side-${this.side}`]: true,
|
||||
}}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Method, Prop, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-fab',
|
||||
@@ -76,11 +76,11 @@ export class Fab implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { horizontal, vertical, edge } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`fab-horizontal-${horizontal}`]: horizontal !== undefined,
|
||||
[`fab-vertical-${vertical}`]: vertical !== undefined,
|
||||
'fab-edge': edge,
|
||||
|
||||
@@ -4,18 +4,20 @@ import { findIonContent, getScrollElement, printIonContentErrorMsg } from '@util
|
||||
import type { KeyboardController } from '@utils/keyboard/keyboard-controller';
|
||||
import { createKeyboardController } from '@utils/keyboard/keyboard-controller';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
import { handleFooterFade } from './footer.utils';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-footer',
|
||||
styleUrls: {
|
||||
ios: 'footer.ios.scss',
|
||||
md: 'footer.md.scss',
|
||||
ionic: 'footer.md.scss',
|
||||
},
|
||||
})
|
||||
export class Footer implements ComponentInterface {
|
||||
@@ -73,8 +75,8 @@ export class Footer implements ComponentInterface {
|
||||
}
|
||||
|
||||
private checkCollapsibleFooter = () => {
|
||||
const mode = getIonMode(this);
|
||||
if (mode !== 'ios') {
|
||||
const theme = getIonTheme(this);
|
||||
if (theme !== 'ios') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -119,7 +121,7 @@ export class Footer implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { translucent, collapse } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const tabs = this.el.closest('ion-tabs');
|
||||
const tabBar = tabs?.querySelector(':scope > ion-tab-bar');
|
||||
|
||||
@@ -127,19 +129,19 @@ export class Footer implements ComponentInterface {
|
||||
<Host
|
||||
role="contentinfo"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`footer-${mode}`]: true,
|
||||
[`footer-${theme}`]: true,
|
||||
|
||||
[`footer-translucent`]: translucent,
|
||||
[`footer-translucent-${mode}`]: translucent,
|
||||
[`footer-translucent-${theme}`]: translucent,
|
||||
['footer-toolbar-padding']: !this.keyboardVisible && (!tabBar || tabBar.slot !== 'bottom'),
|
||||
|
||||
[`footer-collapse-${collapse}`]: collapse !== undefined,
|
||||
}}
|
||||
>
|
||||
{mode === 'ios' && translucent && <div class="footer-background"></div>}
|
||||
{theme === 'ios' && translucent && <div class="footer-background"></div>}
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-grid',
|
||||
@@ -15,11 +15,11 @@ export class Grid implements ComponentInterface {
|
||||
@Prop() fixed = false;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'grid-fixed': this.fixed,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Attributes } from '@utils/helpers';
|
||||
import { inheritAriaAttributes } from '@utils/helpers';
|
||||
import { hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
import {
|
||||
cloneElement,
|
||||
@@ -18,13 +18,15 @@ import {
|
||||
} from './header.utils';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-header',
|
||||
styleUrls: {
|
||||
ios: 'header.ios.scss',
|
||||
md: 'header.md.scss',
|
||||
ionic: 'header.md.scss',
|
||||
},
|
||||
})
|
||||
export class Header implements ComponentInterface {
|
||||
@@ -71,9 +73,9 @@ export class Header implements ComponentInterface {
|
||||
}
|
||||
|
||||
private async checkCollapsibleHeader() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
if (mode !== 'ios') {
|
||||
if (theme !== 'ios') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -206,7 +208,7 @@ export class Header implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { translucent, inheritedAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const collapse = this.collapse || 'none';
|
||||
|
||||
// banner role must be at top level, so remove role if inside a menu
|
||||
@@ -216,18 +218,18 @@ export class Header implements ComponentInterface {
|
||||
<Host
|
||||
role={roleType}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`header-${mode}`]: true,
|
||||
[`header-${theme}`]: true,
|
||||
|
||||
[`header-translucent`]: this.translucent,
|
||||
[`header-collapse-${collapse}`]: true,
|
||||
[`header-translucent-${mode}`]: this.translucent,
|
||||
[`header-translucent-${theme}`]: this.translucent,
|
||||
}}
|
||||
{...inheritedAttributes}
|
||||
>
|
||||
{mode === 'ios' && translucent && <div class="header-background"></div>}
|
||||
{theme === 'ios' && translucent && <div class="header-background"></div>}
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Component, Element, Event, Host, Prop, State, Watch, h } from '@stencil
|
||||
import type { Attributes } from '@utils/helpers';
|
||||
import { inheritAttributes } from '@utils/helpers';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @part image - The inner `img` element.
|
||||
@@ -110,8 +110,13 @@ export class Img implements ComponentInterface {
|
||||
render() {
|
||||
const { loadSrc, alt, onLoad, loadError, inheritedAttributes } = this;
|
||||
const { draggable } = inheritedAttributes;
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host class={getIonMode(this)}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<img
|
||||
decoding="async"
|
||||
src={loadSrc}
|
||||
|
||||
@@ -4,15 +4,19 @@ import { ENABLE_HTML_CONTENT_DEFAULT } from '@utils/config';
|
||||
import { sanitizeDOMString } from '@utils/sanitization';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
import type { SpinnerTypes } from '../spinner/spinner-configs';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-infinite-scroll-content',
|
||||
styleUrls: {
|
||||
ios: 'infinite-scroll-content.ios.scss',
|
||||
md: 'infinite-scroll-content.md.scss',
|
||||
ionic: 'infinite-scroll-content.md.scss',
|
||||
},
|
||||
})
|
||||
export class InfiniteScrollContent implements ComponentInterface {
|
||||
@@ -41,10 +45,10 @@ export class InfiniteScrollContent implements ComponentInterface {
|
||||
|
||||
componentDidLoad() {
|
||||
if (this.loadingSpinner === undefined) {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
this.loadingSpinner = config.get(
|
||||
'infiniteLoadingSpinner',
|
||||
config.get('spinner', mode === 'ios' ? 'lines' : 'crescent')
|
||||
config.get('spinner', theme === 'ios' ? 'lines' : 'crescent')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -59,14 +63,14 @@ export class InfiniteScrollContent implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`infinite-scroll-content-${mode}`]: true,
|
||||
[`infinite-scroll-content-${theme}`]: true,
|
||||
}}
|
||||
>
|
||||
<div class="infinite-loading">
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Method, Prop, State, Watch, h, readTask, writeTask } from '@stencil/core';
|
||||
import { findClosestIonContent, getScrollElement, printIonContentErrorMsg } from '@utils/content';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-infinite-scroll',
|
||||
@@ -221,12 +221,12 @@ export class InfiniteScroll implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const disabled = this.disabled;
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'infinite-scroll-loading': this.isLoading,
|
||||
'infinite-scroll-enabled': !disabled,
|
||||
}}
|
||||
|
||||
@@ -16,14 +16,15 @@ import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
import { closeCircle, closeSharp } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AutocompleteTypes, Color, StyleEventDetail, TextFieldTypes } from '../../interface';
|
||||
|
||||
import type { InputChangeEventDetail, InputInputEventDetail } from './input-interface';
|
||||
import { getCounterText } from './input.utils';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot label - The label text to associate with the input. Use the `labelPlacement` property to control where the label is placed relative to the input. Use this if you need to render a label with custom HTML. (EXPERIMENTAL)
|
||||
* @slot start - Content to display at the leading edge of the input. (EXPERIMENTAL)
|
||||
@@ -34,6 +35,7 @@ import { getCounterText } from './input.utils';
|
||||
styleUrls: {
|
||||
ios: 'input.ios.scss',
|
||||
md: 'input.md.scss',
|
||||
ionic: 'input.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -690,8 +692,8 @@ export class Input implements ComponentInterface {
|
||||
* when fill="outline".
|
||||
*/
|
||||
private renderLabelContainer() {
|
||||
const mode = getIonMode(this);
|
||||
const hasOutlineFill = mode === 'md' && this.fill === 'outline';
|
||||
const theme = getIonTheme(this);
|
||||
const hasOutlineFill = theme === 'md' && this.fill === 'outline';
|
||||
|
||||
if (hasOutlineFill) {
|
||||
/**
|
||||
@@ -729,10 +731,10 @@ export class Input implements ComponentInterface {
|
||||
|
||||
private renderInput() {
|
||||
const { disabled, fill, readonly, shape, inputId, labelPlacement, el, hasFocus } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||
@@ -760,7 +762,7 @@ export class Input implements ComponentInterface {
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'has-value': hasValue,
|
||||
'has-focus': hasFocus,
|
||||
'label-floating': labelShouldFloat,
|
||||
@@ -833,7 +835,7 @@ export class Input implements ComponentInterface {
|
||||
}}
|
||||
onClick={this.clearTextInput}
|
||||
>
|
||||
<ion-icon aria-hidden="true" icon={mode === 'ios' ? closeCircle : closeSharp}></ion-icon>
|
||||
<ion-icon aria-hidden="true" icon={theme === 'ios' ? closeCircle : closeSharp}></ion-icon>
|
||||
</button>
|
||||
)}
|
||||
<slot name="end"></slot>
|
||||
@@ -872,7 +874,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
this.hasLoggedDeprecationWarning = true;
|
||||
}
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const labelId = this.inputId + '-lbl';
|
||||
const label = findItemLabel(this.el);
|
||||
@@ -884,7 +886,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
<Host
|
||||
aria-disabled={this.disabled ? 'true' : null}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'has-value': this.hasValue(),
|
||||
'has-focus': this.hasFocus,
|
||||
'legacy-input': true,
|
||||
@@ -940,7 +942,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
}}
|
||||
onClick={this.clearTextInput}
|
||||
>
|
||||
<ion-icon aria-hidden="true" icon={mode === 'ios' ? closeCircle : closeSharp}></ion-icon>
|
||||
<ion-icon aria-hidden="true" icon={theme === 'ios' ? closeCircle : closeSharp}></ion-icon>
|
||||
</button>
|
||||
)}
|
||||
</Host>
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot start - Content is placed to the left of the divider text in LTR, and to the right in RTL.
|
||||
@@ -17,6 +18,7 @@ import type { Color } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'item-divider.ios.scss',
|
||||
md: 'item-divider.md.scss',
|
||||
ionic: 'item-divider.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -40,11 +42,11 @@ export class ItemDivider implements ComponentInterface {
|
||||
@Prop() sticky = false;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'item-divider-sticky': this.sticky,
|
||||
item: true,
|
||||
})}
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-item-group',
|
||||
styleUrls: {
|
||||
ios: 'item-group.ios.scss',
|
||||
md: 'item-group.md.scss',
|
||||
ionic: 'item-group.md.scss',
|
||||
},
|
||||
})
|
||||
export class ItemGroup implements ComponentInterface {
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="group"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`item-group-${mode}`]: true,
|
||||
[`item-group-${theme}`]: true,
|
||||
|
||||
item: true,
|
||||
}}
|
||||
|
||||
@@ -3,11 +3,12 @@ import { Component, Element, Host, Prop, h } from '@stencil/core';
|
||||
import type { AnchorInterface, ButtonInterface } from '@utils/element-interface';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot start - Content is placed to the left of the option text in LTR, and to the right in RTL.
|
||||
@@ -23,6 +24,7 @@ import type { Color } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'item-option.ios.scss',
|
||||
md: 'item-option.md.scss',
|
||||
ionic: 'item-option.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -88,7 +90,7 @@ export class ItemOption implements ComponentInterface, AnchorInterface, ButtonIn
|
||||
render() {
|
||||
const { disabled, expandable, href } = this;
|
||||
const TagType = href === undefined ? 'button' : ('a' as any);
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const attrs =
|
||||
TagType === 'button'
|
||||
? { type: this.type }
|
||||
@@ -102,7 +104,7 @@ export class ItemOption implements ComponentInterface, AnchorInterface, ButtonIn
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'item-option-disabled': disabled,
|
||||
'item-option-expandable': expandable,
|
||||
'ion-activatable': true,
|
||||
@@ -119,7 +121,7 @@ export class ItemOption implements ComponentInterface, AnchorInterface, ButtonIn
|
||||
</div>
|
||||
<slot name="bottom"></slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</TagType>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -2,14 +2,18 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Method, Prop, h } from '@stencil/core';
|
||||
import { isEndSide } from '@utils/helpers';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Side } from '../menu/menu-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-item-options',
|
||||
styleUrls: {
|
||||
ios: 'item-options.ios.scss',
|
||||
md: 'item-options.md.scss',
|
||||
ionic: 'item-options.md.scss',
|
||||
},
|
||||
})
|
||||
export class ItemOptions implements ComponentInterface {
|
||||
@@ -35,15 +39,15 @@ export class ItemOptions implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const isEnd = isEndSide(this.side);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`item-options-${mode}`]: true,
|
||||
[`item-options-${theme}`]: true,
|
||||
|
||||
/**
|
||||
* Note: The "start" and "end" terms refer to the
|
||||
|
||||
@@ -4,7 +4,7 @@ import { findClosestIonContent, disableContentScrollY, resetContentScrollY } fro
|
||||
import { isEndSide } from '@utils/helpers';
|
||||
import { watchForOptions } from '@utils/watch-options';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Gesture, GestureDetail } from '../../interface';
|
||||
import type { Side } from '../menu/menu-interface';
|
||||
|
||||
@@ -482,11 +482,11 @@ export class ItemSliding implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'item-sliding-active-slide': this.state !== SlidingState.Disabled,
|
||||
'item-sliding-active-options-end': (this.state & SlidingState.End) !== 0,
|
||||
'item-sliding-active-options-start': (this.state & SlidingState.Start) !== 0,
|
||||
|
||||
@@ -7,7 +7,7 @@ import { printIonError, printIonWarning } from '@utils/logging';
|
||||
import { createColorClasses, hostContext, openURL } from '@utils/theme';
|
||||
import { chevronForward } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color, CssClassMap, StyleEventDetail } from '../../interface';
|
||||
import type { InputInputEventDetail } from '../input/input-interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
@@ -15,7 +15,8 @@ import type { RouterDirection } from '../router/utils/interface';
|
||||
import type { CounterFormatter } from './item-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot start - Content is placed to the left of the item text in LTR, and to the right in RTL.
|
||||
@@ -31,6 +32,7 @@ import type { CounterFormatter } from './item-interface';
|
||||
styleUrls: {
|
||||
ios: 'item.ios.scss',
|
||||
md: 'item.md.scss',
|
||||
ionic: 'item.md.scss',
|
||||
},
|
||||
shadow: {
|
||||
delegatesFocus: true,
|
||||
@@ -384,7 +386,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
multipleInputs,
|
||||
} = this;
|
||||
const childStyles = {} as StyleEventDetail;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const clickable = this.isClickable();
|
||||
const canActivate = this.canActivate();
|
||||
const TagType = clickable ? (href === undefined ? 'button' : 'a') : ('div' as any);
|
||||
@@ -433,7 +435,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
};
|
||||
}
|
||||
|
||||
const showDetail = detail !== undefined ? detail : mode === 'ios' && clickable;
|
||||
const showDetail = detail !== undefined ? detail : theme === 'ios' && clickable;
|
||||
this.itemStyles.forEach((value) => {
|
||||
Object.assign(childStyles, value);
|
||||
});
|
||||
@@ -449,7 +451,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
...labelColorStyles,
|
||||
...createColorClasses(this.color, {
|
||||
item: true,
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'item-lines-default': lines === undefined,
|
||||
[`item-lines-${lines}`]: lines !== undefined,
|
||||
[`item-fill-${fillValue}`]: true,
|
||||
@@ -491,7 +493,7 @@ export class Item implements ComponentInterface, AnchorInterface, ButtonInterfac
|
||||
)}
|
||||
<div class="item-inner-highlight"></div>
|
||||
</div>
|
||||
{canActivate && mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{canActivate && theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
<div class="item-highlight"></div>
|
||||
</TagType>
|
||||
<div class="item-bottom">
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Prop, State, Watch, h } from '@stencil/core';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-label',
|
||||
styleUrls: {
|
||||
ios: 'label.ios.scss',
|
||||
md: 'label.md.scss',
|
||||
ionic: 'label.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -97,11 +99,11 @@ export class Label implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const position = this.position;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item-color': hostContext('ion-item.ion-color', this.el),
|
||||
[`label-${position}`]: position !== undefined,
|
||||
[`label-no-animate`]: this.noAnimate,
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-list-header',
|
||||
styleUrls: {
|
||||
ios: 'list-header.ios.scss',
|
||||
md: 'list-header.md.scss',
|
||||
ionic: 'list-header.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -31,12 +33,12 @@ export class ListHeader implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { lines } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`list-header-lines-${lines}`]: lines !== undefined,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -1,16 +1,18 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Method, Prop, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-list',
|
||||
styleUrls: {
|
||||
ios: 'list.ios.scss',
|
||||
md: 'list.md.scss',
|
||||
ionic: 'list.md.scss',
|
||||
},
|
||||
})
|
||||
export class List implements ComponentInterface {
|
||||
@@ -42,20 +44,20 @@ export class List implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { lines, inset } = this;
|
||||
return (
|
||||
<Host
|
||||
role="list"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`list-${mode}`]: true,
|
||||
[`list-${theme}`]: true,
|
||||
|
||||
'list-inset': inset,
|
||||
[`list-lines-${lines}`]: lines !== undefined,
|
||||
[`list-${mode}-lines-${lines}`]: lines !== undefined,
|
||||
[`list-${theme}-lines-${lines}`]: lines !== undefined,
|
||||
}}
|
||||
></Host>
|
||||
);
|
||||
|
||||
@@ -17,7 +17,7 @@ import { sanitizeDOMString } from '@utils/sanitization';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, FrameworkDelegate, OverlayInterface } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
@@ -31,13 +31,15 @@ import { mdLeaveAnimation } from './animations/md.leave';
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-loading',
|
||||
styleUrls: {
|
||||
ios: 'loading.ios.scss',
|
||||
md: 'loading.md.scss',
|
||||
ionic: 'loading.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -211,8 +213,8 @@ export class Loading implements ComponentInterface, OverlayInterface {
|
||||
|
||||
componentWillLoad() {
|
||||
if (this.spinner === undefined) {
|
||||
const mode = getIonMode(this);
|
||||
this.spinner = config.get('loadingSpinner', config.get('spinner', mode === 'ios' ? 'lines' : 'crescent'));
|
||||
const theme = getIonTheme(this);
|
||||
this.spinner = config.get('loadingSpinner', config.get('spinner', theme === 'ios' ? 'lines' : 'crescent'));
|
||||
}
|
||||
setOverlayId(this.el);
|
||||
}
|
||||
@@ -326,7 +328,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
|
||||
|
||||
render() {
|
||||
const { message, spinner, htmlAttributes, overlayIndex } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const msgId = `loading-${overlayIndex}-msg`;
|
||||
/**
|
||||
* If the message is defined, use that as the label.
|
||||
@@ -347,7 +349,7 @@ export class Loading implements ComponentInterface, OverlayInterface {
|
||||
onIonBackdropTap={this.onBackdropTap}
|
||||
class={{
|
||||
...getClassMap(this.cssClass),
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'overlay-hidden': true,
|
||||
'loading-translucent': this.translucent,
|
||||
}}
|
||||
|
||||
@@ -8,12 +8,13 @@ import { createColorClasses, hostContext } from '@utils/theme';
|
||||
import { menuOutline, menuSharp } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
import { updateVisibility } from '../menu-toggle/menu-toggle-util';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML button element that wraps all child elements.
|
||||
* @part icon - The menu button icon (uses ion-icon).
|
||||
@@ -23,6 +24,7 @@ import { updateVisibility } from '../menu-toggle/menu-toggle-util';
|
||||
styleUrls: {
|
||||
ios: 'menu-button.ios.scss',
|
||||
md: 'menu-button.md.scss',
|
||||
ionic: 'menu-button.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -80,8 +82,8 @@ export class MenuButton implements ComponentInterface, ButtonInterface {
|
||||
|
||||
render() {
|
||||
const { color, disabled, inheritedAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
const menuIcon = config.get('menuIcon', mode === 'ios' ? menuOutline : menuSharp);
|
||||
const theme = getIonTheme(this);
|
||||
const menuIcon = config.get('menuIcon', theme === 'ios' ? menuOutline : menuSharp);
|
||||
const hidden = this.autoHide && !this.visible;
|
||||
|
||||
const attrs = {
|
||||
@@ -96,7 +98,7 @@ export class MenuButton implements ComponentInterface, ButtonInterface {
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
aria-hidden={hidden ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
button: true, // ion-buttons target .button
|
||||
'menu-button-hidden': hidden,
|
||||
'menu-button-disabled': disabled,
|
||||
@@ -109,10 +111,11 @@ export class MenuButton implements ComponentInterface, ButtonInterface {
|
||||
<button {...attrs} disabled={disabled} class="button-native" part="native" aria-label={ariaLabel}>
|
||||
<span class="button-inner">
|
||||
<slot>
|
||||
<ion-icon part="icon" icon={menuIcon} mode={mode} lazy={false} aria-hidden="true"></ion-icon>
|
||||
{/* TODO double check the mode/theme attribute */}
|
||||
<ion-icon part="icon" icon={menuIcon} mode={theme} lazy={false} aria-hidden="true"></ion-icon>
|
||||
</slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect type="unbounded"></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect type="unbounded"></ion-ripple-effect>}
|
||||
</button>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Listen, Prop, State, h } from '@stencil/core';
|
||||
import { menuController } from '@utils/menu-controller';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
import { updateVisibility } from './menu-toggle-util';
|
||||
|
||||
@@ -50,7 +50,7 @@ export class MenuToggle implements ComponentInterface {
|
||||
};
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const hidden = this.autoHide && !this.visible;
|
||||
|
||||
return (
|
||||
@@ -58,7 +58,7 @@ export class MenuToggle implements ComponentInterface {
|
||||
onClick={this.onClick}
|
||||
aria-hidden={hidden ? 'true' : null}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'menu-toggle-hidden': hidden,
|
||||
}}
|
||||
>
|
||||
|
||||
@@ -9,7 +9,7 @@ import { menuController } from '@utils/menu-controller';
|
||||
import { getPresentedOverlay } from '@utils/overlays';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { Animation, Gesture, GestureDetail } from '../../interface';
|
||||
|
||||
import type { MenuChangeEventDetail, MenuI, Side } from './menu-interface';
|
||||
@@ -22,6 +22,8 @@ const focusableQueryString =
|
||||
'[tabindex]:not([tabindex^="-"]), input:not([type=hidden]):not([tabindex^="-"]), textarea:not([tabindex^="-"]), button:not([tabindex^="-"]), select:not([tabindex^="-"]), .ion-focusable:not([tabindex^="-"])';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part container - The container for the menu content.
|
||||
* @part backdrop - The backdrop that appears over the main content when the menu is open.
|
||||
*/
|
||||
@@ -30,6 +32,7 @@ const focusableQueryString =
|
||||
styleUrls: {
|
||||
ios: 'menu.ios.scss',
|
||||
md: 'menu.md.scss',
|
||||
ionic: 'menu.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -779,7 +782,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
|
||||
render() {
|
||||
const { type, disabled, isPaneVisible, inheritedAttributes, side } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
/**
|
||||
* If the Close Watcher is enabled then
|
||||
@@ -792,7 +795,7 @@ export class Menu implements ComponentInterface, MenuI {
|
||||
role="navigation"
|
||||
aria-label={inheritedAttributes['aria-label'] || 'menu'}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`menu-type-${type}`]: true,
|
||||
'menu-enabled': !disabled,
|
||||
[`menu-side-${side}`]: true,
|
||||
|
||||
@@ -21,7 +21,7 @@ import { getClassMap } from '@utils/theme';
|
||||
import { deepReady, waitForMount } from '@utils/transition';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type {
|
||||
Animation,
|
||||
AnimationBuilder,
|
||||
@@ -47,7 +47,8 @@ import { setCardStatusBarDark, setCardStatusBarDefault } from './utils';
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed inside of the `.modal-content` element.
|
||||
*
|
||||
@@ -60,6 +61,7 @@ import { setCardStatusBarDark, setCardStatusBarDefault } from './utils';
|
||||
styleUrls: {
|
||||
ios: 'modal.ios.scss',
|
||||
md: 'modal.md.scss',
|
||||
ionic: 'modal.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -871,8 +873,8 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
const { handle, isSheetModal, presentingElement, htmlAttributes, handleBehavior, inheritedAttributes } = this;
|
||||
|
||||
const showHandle = handle !== false && isSheetModal;
|
||||
const mode = getIonMode(this);
|
||||
const isCardModal = presentingElement !== undefined && mode === 'ios';
|
||||
const theme = getIonTheme(this);
|
||||
const isCardModal = presentingElement !== undefined && theme === 'ios';
|
||||
const isHandleCycle = handleBehavior === 'cycle';
|
||||
|
||||
return (
|
||||
@@ -884,7 +886,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
zIndex: `${20000 + this.overlayIndex}`,
|
||||
}}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
['modal-default']: !isCardModal && !isSheetModal,
|
||||
[`modal-card`]: isCardModal,
|
||||
[`modal-sheet`]: isSheetModal,
|
||||
@@ -904,7 +906,7 @@ export class Modal implements ComponentInterface, OverlayInterface {
|
||||
part="backdrop"
|
||||
/>
|
||||
|
||||
{mode === 'ios' && <div class="modal-shadow"></div>}
|
||||
{theme === 'ios' && <div class="modal-shadow"></div>}
|
||||
|
||||
<div
|
||||
/*
|
||||
|
||||
@@ -61,7 +61,7 @@ export class Nav implements NavOutlet {
|
||||
@Prop() animated = true;
|
||||
|
||||
/**
|
||||
* By default `ion-nav` animates transition between pages based in the mode (ios or material design).
|
||||
* By default `ion-nav` animates transition between pages based on the platform (ios or md).
|
||||
* However, this property allows to create custom transition using `AnimationBuilder` functions.
|
||||
*/
|
||||
@Prop() animation?: AnimationBuilder;
|
||||
|
||||
@@ -2,17 +2,19 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-note',
|
||||
styleUrls: {
|
||||
ios: 'note.ios.scss',
|
||||
md: 'note.md.scss',
|
||||
ionic: 'note.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -25,11 +27,11 @@ export class Note implements ComponentInterface {
|
||||
@Prop({ reflect: true }) color?: Color;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -5,14 +5,16 @@ import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from
|
||||
import { isPlatform } from '@utils/platform';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
import type { PickerInternalCustomEvent } from '../picker-internal/picker-internal-interfaces';
|
||||
|
||||
import type { PickerColumnItem } from './picker-column-internal-interfaces';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@Component({
|
||||
@@ -20,6 +22,7 @@ import type { PickerColumnItem } from './picker-column-internal-interfaces';
|
||||
styleUrls: {
|
||||
ios: 'picker-column-internal.ios.scss',
|
||||
md: 'picker-column-internal.md.scss',
|
||||
ionic: 'picker-column-internal.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -422,7 +425,7 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { items, color, disabled: pickerDisabled, isActive, numericInput } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
/**
|
||||
* exportparts is needed so ion-datetime can expose the parts
|
||||
@@ -437,7 +440,7 @@ export class PickerColumnInternal implements ComponentInterface {
|
||||
disabled={pickerDisabled}
|
||||
tabindex={pickerDisabled ? null : 0}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
['picker-column-active']: isActive,
|
||||
['picker-column-numeric-input']: numericInput,
|
||||
})}
|
||||
|
||||
@@ -4,11 +4,13 @@ import { clamp } from '@utils/helpers';
|
||||
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '@utils/native/haptic';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Gesture, GestureDetail } from '../../interface';
|
||||
import type { PickerColumn } from '../picker/picker-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@Component({
|
||||
@@ -16,6 +18,7 @@ import type { PickerColumn } from '../picker/picker-interface';
|
||||
styleUrls: {
|
||||
ios: 'picker-column.ios.scss',
|
||||
md: 'picker-column.md.scss',
|
||||
ionic: 'picker-column.md.scss',
|
||||
},
|
||||
})
|
||||
export class PickerColumnCmp implements ComponentInterface {
|
||||
@@ -61,9 +64,9 @@ export class PickerColumnCmp implements ComponentInterface {
|
||||
let pickerRotateFactor = 0;
|
||||
let pickerScaleFactor = 0.81;
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
if (mode === 'ios') {
|
||||
if (theme === 'ios') {
|
||||
pickerRotateFactor = -0.46;
|
||||
pickerScaleFactor = 1;
|
||||
}
|
||||
@@ -394,11 +397,11 @@ export class PickerColumnCmp implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const col = this.col;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'picker-col': true,
|
||||
'picker-opts-left': this.col.align === 'left',
|
||||
'picker-opts-right': this.col.align === 'right',
|
||||
|
||||
@@ -5,7 +5,9 @@ import { getElementRoot } from '@utils/helpers';
|
||||
import type { PickerInternalChangeEventDetail } from './picker-internal-interfaces';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@Component({
|
||||
@@ -13,6 +15,7 @@ import type { PickerInternalChangeEventDetail } from './picker-internal-interfac
|
||||
styleUrls: {
|
||||
ios: 'picker-internal.ios.scss',
|
||||
md: 'picker-internal.md.scss',
|
||||
ionic: 'picker-internal.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
|
||||
@@ -16,7 +16,7 @@ import {
|
||||
} from '@utils/overlays';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, CssClassMap, OverlayInterface, FrameworkDelegate } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
|
||||
@@ -27,13 +27,15 @@ import type { PickerButton, PickerColumn } from './picker-interface';
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-picker',
|
||||
styleUrls: {
|
||||
ios: 'picker.ios.scss',
|
||||
md: 'picker.md.scss',
|
||||
ionic: 'picker.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -349,7 +351,7 @@ export class Picker implements ComponentInterface, OverlayInterface {
|
||||
|
||||
render() {
|
||||
const { htmlAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
aria-modal="true"
|
||||
@@ -359,10 +361,10 @@ export class Picker implements ComponentInterface, OverlayInterface {
|
||||
zIndex: `${20000 + this.overlayIndex}`,
|
||||
}}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`picker-${mode}`]: true,
|
||||
[`picker-${theme}`]: true,
|
||||
'overlay-hidden': true,
|
||||
...getClassMap(this.cssClass),
|
||||
}}
|
||||
|
||||
@@ -5,6 +5,7 @@ import type {
|
||||
FrameworkDelegate,
|
||||
Mode,
|
||||
OverlayInterface,
|
||||
Theme,
|
||||
} from '../../interface';
|
||||
|
||||
export interface PopoverInterface extends OverlayInterface {
|
||||
@@ -22,7 +23,11 @@ export interface PopoverOptions<T extends ComponentRef = ComponentRef> {
|
||||
delegate?: FrameworkDelegate;
|
||||
animated?: boolean;
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
mode?: Mode;
|
||||
theme?: Theme;
|
||||
keyboardClose?: boolean;
|
||||
id?: string;
|
||||
htmlAttributes?: { [key: string]: any };
|
||||
|
||||
@@ -17,7 +17,7 @@ import { isPlatform } from '@utils/platform';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
import { deepReady, waitForMount } from '@utils/transition';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, ComponentProps, ComponentRef, FrameworkDelegate } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
|
||||
@@ -38,7 +38,8 @@ import { configureDismissInteraction, configureKeyboardInteraction, configureTri
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed inside of the `.popover-content` element.
|
||||
*
|
||||
@@ -51,6 +52,7 @@ import { configureDismissInteraction, configureKeyboardInteraction, configureTri
|
||||
styleUrls: {
|
||||
ios: 'popover.ios.scss',
|
||||
md: 'popover.md.scss',
|
||||
ionic: 'popover.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -350,7 +352,7 @@ export class Popover implements ComponentInterface, PopoverInterface {
|
||||
this.parentPopover = el.closest(`ion-popover:not(#${popoverId})`) as HTMLIonPopoverElement | null;
|
||||
|
||||
if (this.alignment === undefined) {
|
||||
this.alignment = getIonMode(this) === 'ios' ? 'center' : 'start';
|
||||
this.alignment = getIonTheme(this) === 'ios' ? 'center' : 'start';
|
||||
}
|
||||
}
|
||||
|
||||
@@ -662,7 +664,7 @@ export class Popover implements ComponentInterface, PopoverInterface {
|
||||
};
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { onLifecycle, parentPopover, dismissOnSelect, side, arrow, htmlAttributes } = this;
|
||||
const desktop = isPlatform('desktop');
|
||||
const enableArrow = arrow && !parentPopover;
|
||||
@@ -678,7 +680,7 @@ export class Popover implements ComponentInterface, PopoverInterface {
|
||||
}}
|
||||
class={{
|
||||
...getClassMap(this.cssClass),
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'popover-translucent': this.translucent,
|
||||
'overlay-hidden': true,
|
||||
'popover-desktop': desktop,
|
||||
|
||||
@@ -4,11 +4,12 @@ import { clamp } from '@utils/helpers';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part progress - The progress bar that shows the current value when `type` is `"determinate"` and slides back and forth when `type` is `"indeterminate"`.
|
||||
* @part stream - The animated circles that appear while buffering. This only shows when `buffer` is set and `type` is `"determinate"`.
|
||||
@@ -20,6 +21,7 @@ import type { Color } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'progress-bar.ios.scss',
|
||||
md: 'progress-bar.md.scss',
|
||||
ionic: 'progress-bar.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -58,7 +60,7 @@ export class ProgressBar implements ComponentInterface {
|
||||
render() {
|
||||
const { color, type, reversed, value, buffer } = this;
|
||||
const paused = config.getBoolean('_testing');
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="progressbar"
|
||||
@@ -66,7 +68,7 @@ export class ProgressBar implements ComponentInterface {
|
||||
aria-valuemin="0"
|
||||
aria-valuemax="1"
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`progress-bar-${type}`]: true,
|
||||
'progress-paused': paused,
|
||||
'progress-bar-reversed': document.dir === 'rtl' ? !reversed : reversed,
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Listen, Prop, Watch, h } from '@stencil/core';
|
||||
import { renderHiddenInput } from '@utils/helpers';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
import type { RadioGroupChangeEventDetail, RadioGroupCompareFn } from './radio-group-interface';
|
||||
|
||||
@@ -215,11 +215,20 @@ export class RadioGroup implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { label, labelId, el, name, value } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
renderHiddenInput(true, el, name, value, false);
|
||||
|
||||
return <Host role="radiogroup" aria-labelledby={label ? labelId : null} onClick={this.onClick} class={mode}></Host>;
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
role="radiogroup"
|
||||
aria-labelledby={label ? labelId : null}
|
||||
onClick={this.onClick}
|
||||
></Host>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -6,11 +6,12 @@ import { addEventListener, getAriaLabel, removeEventListener } from '@utils/help
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - The label text to associate with the radio. Use the "labelPlacement" property to control where the label is placed relative to the radio.
|
||||
*
|
||||
@@ -23,6 +24,7 @@ import type { Color, StyleEventDetail } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'radio.ios.scss',
|
||||
md: 'radio.md.scss',
|
||||
ionic: 'radio.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -267,7 +269,7 @@ export class Radio implements ComponentInterface {
|
||||
|
||||
private renderRadio() {
|
||||
const { checked, disabled, color, el, justify, labelPlacement, hasLabel, buttonTabindex, alignment } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const inItem = hostContext('ion-item', el);
|
||||
|
||||
return (
|
||||
@@ -276,7 +278,7 @@ export class Radio implements ComponentInterface {
|
||||
onBlur={this.onBlur}
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': inItem,
|
||||
'radio-checked': checked,
|
||||
'radio-disabled': disabled,
|
||||
@@ -333,7 +335,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
}
|
||||
|
||||
const { inputId, disabled, checked, color, el, buttonTabindex } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { label, labelId, labelText } = getAriaLabel(el, inputId);
|
||||
|
||||
return (
|
||||
@@ -347,7 +349,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
onBlur={this.onBlur}
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
interactive: true,
|
||||
'radio-checked': checked,
|
||||
|
||||
@@ -9,7 +9,7 @@ import { printIonWarning } from '@utils/logging';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, Gesture, GestureDetail, StyleEventDetail } from '../../interface';
|
||||
import { roundToMaxDecimalPlaces } from '../../utils/floating-point';
|
||||
|
||||
@@ -25,7 +25,8 @@ import type {
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot label - The label text to associate with the range. Use the "labelPlacement" property to control where the label is placed relative to the range.
|
||||
* @slot start - Content is placed to the left of the range slider in LTR, and to the right in RTL.
|
||||
@@ -44,6 +45,7 @@ import type {
|
||||
styleUrls: {
|
||||
ios: 'range.ios.scss',
|
||||
md: 'range.md.scss',
|
||||
ionic: 'range.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -592,7 +594,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
|
||||
const { el, pressedKnob, disabled, pin, rangeId } = this;
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
|
||||
|
||||
@@ -602,7 +604,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
onFocusout={this.onBlur}
|
||||
id={rangeId}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'range-disabled': disabled,
|
||||
'range-pressed': pressedKnob !== undefined,
|
||||
@@ -653,7 +655,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
|
||||
const needsEndAdjustment = inItem && !hasEndContent;
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
renderHiddenInput(true, el, this.name, JSON.stringify(this.getValue()), disabled);
|
||||
|
||||
@@ -663,7 +665,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
onFocusout={this.onBlur}
|
||||
id={rangeId}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': inItem,
|
||||
'range-disabled': disabled,
|
||||
'range-pressed': pressedKnob !== undefined,
|
||||
|
||||
@@ -5,7 +5,7 @@ import { sanitizeDOMString } from '@utils/sanitization';
|
||||
import { arrowDown, caretBackSharp } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
import { supportsRubberBandScrolling } from '../refresher/refresher.utils';
|
||||
import type { SpinnerTypes } from '../spinner/spinner-configs';
|
||||
@@ -62,6 +62,8 @@ export class RefresherContent implements ComponentInterface {
|
||||
@Prop() refreshingText?: string | IonicSafeString;
|
||||
|
||||
componentWillLoad() {
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
if (this.pullingIcon === undefined) {
|
||||
/**
|
||||
* The native iOS refresher uses a spinner instead of
|
||||
@@ -69,18 +71,16 @@ export class RefresherContent implements ComponentInterface {
|
||||
* the native iOS refresher.
|
||||
*/
|
||||
const hasRubberBandScrolling = supportsRubberBandScrolling();
|
||||
const mode = getIonMode(this);
|
||||
const overflowRefresher = hasRubberBandScrolling ? 'lines' : arrowDown;
|
||||
this.pullingIcon = config.get(
|
||||
'refreshingIcon',
|
||||
mode === 'ios' && hasRubberBandScrolling ? config.get('spinner', overflowRefresher) : 'circular'
|
||||
theme === 'ios' && hasRubberBandScrolling ? config.get('spinner', overflowRefresher) : 'circular'
|
||||
);
|
||||
}
|
||||
if (this.refreshingSpinner === undefined) {
|
||||
const mode = getIonMode(this);
|
||||
this.refreshingSpinner = config.get(
|
||||
'refreshingSpinner',
|
||||
config.get('spinner', mode === 'ios' ? 'lines' : 'circular')
|
||||
config.get('spinner', theme === 'ios' ? 'lines' : 'circular')
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -106,16 +106,20 @@ export class RefresherContent implements ComponentInterface {
|
||||
render() {
|
||||
const pullingIcon = this.pullingIcon;
|
||||
const hasSpinner = pullingIcon != null && (SPINNERS[pullingIcon] as any) !== undefined;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host class={mode}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<div class="refresher-pulling">
|
||||
{this.pullingIcon && hasSpinner && (
|
||||
<div class="refresher-pulling-icon">
|
||||
<div class="spinner-arrow-container">
|
||||
<ion-spinner name={this.pullingIcon as SpinnerTypes} paused></ion-spinner>
|
||||
{mode === 'md' && this.pullingIcon === 'circular' && (
|
||||
{theme === 'md' && this.pullingIcon === 'circular' && (
|
||||
<div class="arrow-container">
|
||||
<ion-icon icon={caretBackSharp} aria-hidden="true"></ion-icon>
|
||||
</div>
|
||||
|
||||
@@ -10,7 +10,7 @@ import {
|
||||
import { clamp, componentOnReady, getElementRoot, raf, transitionEndAsync } from '@utils/helpers';
|
||||
import { ImpactStyle, hapticImpact } from '@utils/native/haptic';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { Animation, Gesture, GestureDetail } from '../../interface';
|
||||
|
||||
import type { RefresherEventDetail } from './refresher-interface';
|
||||
@@ -26,13 +26,15 @@ import {
|
||||
} from './refresher.utils';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-refresher',
|
||||
styleUrls: {
|
||||
ios: 'refresher.ios.scss',
|
||||
md: 'refresher.md.scss',
|
||||
ionic: 'refresher.md.scss',
|
||||
},
|
||||
})
|
||||
export class Refresher implements ComponentInterface {
|
||||
@@ -801,15 +803,15 @@ export class Refresher implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
slot="fixed"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`refresher-${mode}`]: true,
|
||||
[`refresher-${theme}`]: true,
|
||||
'refresher-native': this.nativeRefresher,
|
||||
'refresher-active': this.state !== RefresherState.Inactive,
|
||||
'refresher-pulling': this.state === RefresherState.Pulling,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { findClosestIonContent, getScrollElement } from '@utils/content';
|
||||
import { raf } from '@utils/helpers';
|
||||
import { hapticSelectionChanged, hapticSelectionEnd, hapticSelectionStart } from '@utils/native/haptic';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Gesture, GestureDetail } from '../../interface';
|
||||
|
||||
import type { ItemReorderEventDetail } from './reorder-group-interface';
|
||||
@@ -301,11 +301,11 @@ export class ReorderGroup implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'reorder-enabled': !this.disabled,
|
||||
'reorder-list-active': this.state !== ReorderGroupState.Idle,
|
||||
}}
|
||||
|
||||
@@ -2,9 +2,11 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Listen, h } from '@stencil/core';
|
||||
import { reorderThreeOutline, reorderTwoSharp } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part icon - The icon of the reorder handle (uses ion-icon).
|
||||
*/
|
||||
@Component({
|
||||
@@ -12,6 +14,7 @@ import { getIonMode } from '../../global/ionic-global';
|
||||
styleUrls: {
|
||||
ios: 'reorder.ios.scss',
|
||||
md: 'reorder.md.scss',
|
||||
ionic: 'reorder.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -32,10 +35,14 @@ export class Reorder implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const reorderIcon = mode === 'ios' ? reorderThreeOutline : reorderTwoSharp;
|
||||
const theme = getIonTheme(this);
|
||||
const reorderIcon = theme === 'ios' ? reorderThreeOutline : reorderTwoSharp;
|
||||
return (
|
||||
<Host class={mode}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<slot>
|
||||
<ion-icon icon={reorderIcon} lazy={false} class="reorder-icon" part="icon" aria-hidden="true" />
|
||||
</slot>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Method, Prop, h, readTask, writeTask } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-ripple-effect',
|
||||
@@ -78,12 +78,12 @@ export class RippleEffect implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="presentation"
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
unbounded: this.unbounded,
|
||||
}}
|
||||
></Host>
|
||||
|
||||
@@ -2,7 +2,7 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses, openURL } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color } from '../../interface';
|
||||
import type { RouterDirection } from '../router/utils/interface';
|
||||
|
||||
@@ -55,7 +55,7 @@ export class RouterLink implements ComponentInterface {
|
||||
};
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const attrs = {
|
||||
href: this.href,
|
||||
rel: this.rel,
|
||||
@@ -65,7 +65,7 @@ export class RouterLink implements ComponentInterface {
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'ion-activatable': true,
|
||||
})}
|
||||
>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-row',
|
||||
@@ -10,8 +10,14 @@ import { getIonMode } from '../../global/ionic-global';
|
||||
})
|
||||
export class Row implements ComponentInterface {
|
||||
render() {
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host class={getIonMode(this)}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -6,19 +6,21 @@ import { createColorClasses } from '@utils/theme';
|
||||
import { arrowBackSharp, closeCircle, closeSharp, searchOutline, searchSharp } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { AutocompleteTypes, Color, StyleEventDetail } from '../../interface';
|
||||
|
||||
import type { SearchbarChangeEventDetail, SearchbarInputEventDetail } from './searchbar-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-searchbar',
|
||||
styleUrls: {
|
||||
ios: 'searchbar.ios.scss',
|
||||
md: 'searchbar.md.scss',
|
||||
ionic: 'searchbar.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -423,11 +425,11 @@ export class Searchbar implements ComponentInterface {
|
||||
private positionElements() {
|
||||
const value = this.getValue();
|
||||
const prevAlignLeft = this.shouldAlignLeft;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const shouldAlignLeft = !this.animated || value.trim() !== '' || !!this.focused;
|
||||
this.shouldAlignLeft = shouldAlignLeft;
|
||||
|
||||
if (mode !== 'ios') {
|
||||
if (theme !== 'ios') {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -559,9 +561,9 @@ export class Searchbar implements ComponentInterface {
|
||||
render() {
|
||||
const { cancelButtonText } = this;
|
||||
const animated = this.animated && config.getBoolean('animated', true);
|
||||
const mode = getIonMode(this);
|
||||
const clearIcon = this.clearIcon || (mode === 'ios' ? closeCircle : closeSharp);
|
||||
const searchIcon = this.searchIcon || (mode === 'ios' ? searchOutline : searchSharp);
|
||||
const theme = getIonTheme(this);
|
||||
const clearIcon = this.clearIcon || (theme === 'ios' ? closeCircle : closeSharp);
|
||||
const searchIcon = this.searchIcon || (theme === 'ios' ? searchOutline : searchSharp);
|
||||
const shouldShowCancelButton = this.shouldShowCancelButton();
|
||||
|
||||
const cancelButton = this.showCancelButton !== 'never' && (
|
||||
@@ -570,14 +572,15 @@ export class Searchbar implements ComponentInterface {
|
||||
// Screen readers should not announce button if it is not visible on screen
|
||||
aria-hidden={shouldShowCancelButton ? undefined : 'true'}
|
||||
type="button"
|
||||
tabIndex={mode === 'ios' && !shouldShowCancelButton ? -1 : undefined}
|
||||
tabIndex={theme === 'ios' && !shouldShowCancelButton ? -1 : undefined}
|
||||
onMouseDown={this.onCancelSearchbar}
|
||||
onTouchStart={this.onCancelSearchbar}
|
||||
class="searchbar-cancel-button"
|
||||
>
|
||||
<div aria-hidden="true">
|
||||
{mode === 'md' ? (
|
||||
<ion-icon aria-hidden="true" mode={mode} icon={this.cancelButtonIcon} lazy={false}></ion-icon>
|
||||
{theme === 'md' ? (
|
||||
// TODO look into the mode/theme
|
||||
<ion-icon aria-hidden="true" mode={theme} icon={this.cancelButtonIcon} lazy={false}></ion-icon>
|
||||
) : (
|
||||
cancelButtonText
|
||||
)}
|
||||
@@ -590,7 +593,7 @@ export class Searchbar implements ComponentInterface {
|
||||
role="search"
|
||||
aria-disabled={this.disabled ? 'true' : null}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'searchbar-animated': animated,
|
||||
'searchbar-disabled': this.disabled,
|
||||
'searchbar-no-animate': animated && this.noAnimate,
|
||||
@@ -622,11 +625,11 @@ export class Searchbar implements ComponentInterface {
|
||||
spellcheck={this.spellcheck}
|
||||
/>
|
||||
|
||||
{mode === 'md' && cancelButton}
|
||||
{theme === 'md' && cancelButton}
|
||||
|
||||
<ion-icon
|
||||
aria-hidden="true"
|
||||
mode={mode}
|
||||
mode={theme}
|
||||
icon={searchIcon}
|
||||
lazy={false}
|
||||
class="searchbar-search-icon"
|
||||
@@ -649,14 +652,14 @@ export class Searchbar implements ComponentInterface {
|
||||
>
|
||||
<ion-icon
|
||||
aria-hidden="true"
|
||||
mode={mode}
|
||||
mode={theme}
|
||||
icon={clearIcon}
|
||||
lazy={false}
|
||||
class="searchbar-clear-icon"
|
||||
></ion-icon>
|
||||
</button>
|
||||
</div>
|
||||
{mode === 'ios' && cancelButton}
|
||||
{theme === 'ios' && cancelButton}
|
||||
</Host>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Attributes } from '@utils/helpers';
|
||||
import { addEventListener, removeEventListener, inheritAttributes } from '@utils/helpers';
|
||||
import { hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { SegmentValue } from '../segment/segment-interface';
|
||||
|
||||
import type { SegmentButtonLayout } from './segment-button-interface';
|
||||
@@ -13,7 +13,8 @@ import type { SegmentButtonLayout } from './segment-button-interface';
|
||||
let ids = 0;
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML button element that wraps all child elements.
|
||||
* @part indicator - The indicator displayed on the checked segment button.
|
||||
@@ -24,6 +25,7 @@ let ids = 0;
|
||||
styleUrls: {
|
||||
ios: 'segment-button.ios.scss',
|
||||
md: 'segment-button.md.scss',
|
||||
ionic: 'segment-button.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -124,12 +126,12 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
|
||||
|
||||
render() {
|
||||
const { checked, type, disabled, hasIcon, hasLabel, layout, segmentEl } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const hasSegmentColor = () => segmentEl?.color !== undefined;
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-toolbar': hostContext('ion-toolbar', this.el),
|
||||
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
|
||||
'in-segment': hostContext('ion-segment', this.el),
|
||||
@@ -159,7 +161,7 @@ export class SegmentButton implements ComponentInterface, ButtonInterface {
|
||||
<span class="button-inner">
|
||||
<slot></slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect></ion-ripple-effect>}
|
||||
</button>
|
||||
<div
|
||||
part="indicator"
|
||||
|
||||
@@ -5,19 +5,21 @@ import { raf } from '@utils/helpers';
|
||||
import { isRTL } from '@utils/rtl';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail } from '../../interface';
|
||||
|
||||
import type { SegmentChangeEventDetail, SegmentValue } from './segment-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-segment',
|
||||
styleUrls: {
|
||||
ios: 'segment.ios.scss',
|
||||
md: 'segment.md.scss',
|
||||
ionic: 'segment.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -558,13 +560,13 @@ export class Segment implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
role="tablist"
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-toolbar': hostContext('ion-toolbar', this.el),
|
||||
'in-toolbar-color': hostContext('ion-toolbar[color]', this.el),
|
||||
'segment-activated': this.activated,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Prop, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-select-option',
|
||||
@@ -24,7 +24,16 @@ export class SelectOption implements ComponentInterface {
|
||||
@Prop() value?: any | null;
|
||||
|
||||
render() {
|
||||
return <Host role="option" id={this.inputId} class={getIonMode(this)}></Host>;
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
role="option"
|
||||
id={this.inputId}
|
||||
></Host>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -3,13 +3,15 @@ import { Element, Component, Host, Prop, h, forceUpdate } from '@stencil/core';
|
||||
import { safeCall } from '@utils/overlays';
|
||||
import { getClassMap } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { CheckboxCustomEvent } from '../checkbox/checkbox-interface';
|
||||
import type { RadioGroupCustomEvent } from '../radio-group/radio-group-interface';
|
||||
|
||||
import type { SelectPopoverOption } from './select-popover-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
@Component({
|
||||
@@ -17,6 +19,7 @@ import type { SelectPopoverOption } from './select-popover-interface';
|
||||
styleUrls: {
|
||||
ios: 'select-popover.ios.scss',
|
||||
md: 'select-popover.md.scss',
|
||||
ionic: 'select-popover.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -181,9 +184,14 @@ export class SelectPopover implements ComponentInterface {
|
||||
render() {
|
||||
const { header, message, options, subHeader } = this;
|
||||
const hasSubHeaderOrMessage = subHeader !== undefined || message !== undefined;
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host class={getIonMode(this)}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<ion-list>
|
||||
{header !== undefined && <ion-list-header>{header}</ion-list-header>}
|
||||
{hasSubHeaderOrMessage && (
|
||||
|
||||
@@ -12,7 +12,7 @@ import { createColorClasses, hostContext } from '@utils/theme';
|
||||
import { watchForOptions } from '@utils/watch-options';
|
||||
import { caretDownSharp, chevronExpand } from 'ionicons/icons';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type {
|
||||
ActionSheetOptions,
|
||||
AlertOptions,
|
||||
@@ -30,7 +30,8 @@ import type { SelectChangeEventDetail, SelectInterface, SelectCompareFn } from '
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot label - The label text to associate with the select. Use the `labelPlacement` property to control where the label is placed relative to the select. Use this if you need to render a label with custom HTML.
|
||||
* @slot start - Content to display at the leading edge of the select.
|
||||
@@ -47,6 +48,7 @@ import type { SelectChangeEventDetail, SelectInterface, SelectCompareFn } from '
|
||||
styleUrls: {
|
||||
ios: 'select.ios.scss',
|
||||
md: 'select.md.scss',
|
||||
ionic: 'select.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -507,8 +509,8 @@ export class Select implements ComponentInterface {
|
||||
private async openPopover(ev: UIEvent) {
|
||||
const { fill, labelPlacement } = this;
|
||||
const interfaceOptions = this.interfaceOptions;
|
||||
const mode = getIonMode(this);
|
||||
const showBackdrop = mode === 'md' ? false : true;
|
||||
const theme = getIonTheme(this);
|
||||
const showBackdrop = theme === 'md' ? false : true;
|
||||
const multiple = this.multiple;
|
||||
const value = this.value;
|
||||
|
||||
@@ -537,7 +539,7 @@ export class Select implements ComponentInterface {
|
||||
* when using a fill in MD mode or if the
|
||||
* label is floating/stacked.
|
||||
*/
|
||||
if (hasFloatingOrStackedLabel || (mode === 'md' && fill !== undefined)) {
|
||||
if (hasFloatingOrStackedLabel || (theme === 'md' && fill !== undefined)) {
|
||||
size = 'cover';
|
||||
|
||||
/**
|
||||
@@ -556,7 +558,7 @@ export class Select implements ComponentInterface {
|
||||
}
|
||||
|
||||
const popoverOpts: PopoverOptions = {
|
||||
mode,
|
||||
theme,
|
||||
event,
|
||||
alignment: 'center',
|
||||
size,
|
||||
@@ -592,10 +594,10 @@ export class Select implements ComponentInterface {
|
||||
}
|
||||
|
||||
private async openActionSheet() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const interfaceOptions = this.interfaceOptions;
|
||||
const actionSheetOpts: ActionSheetOptions = {
|
||||
mode,
|
||||
theme,
|
||||
...interfaceOptions,
|
||||
|
||||
buttons: this.createActionSheetButtons(this.childOpts, this.value),
|
||||
@@ -637,10 +639,10 @@ export class Select implements ComponentInterface {
|
||||
|
||||
const interfaceOptions = this.interfaceOptions;
|
||||
const inputType = this.multiple ? 'checkbox' : 'radio';
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
const alertOpts: AlertOptions = {
|
||||
mode,
|
||||
theme,
|
||||
...interfaceOptions,
|
||||
|
||||
header: interfaceOptions.header ? interfaceOptions.header : labelText,
|
||||
@@ -852,8 +854,8 @@ export class Select implements ComponentInterface {
|
||||
* when fill="outline".
|
||||
*/
|
||||
private renderLabelContainer() {
|
||||
const mode = getIonMode(this);
|
||||
const hasOutlineFill = mode === 'md' && this.fill === 'outline';
|
||||
const theme = getIonTheme(this);
|
||||
const hasOutlineFill = theme === 'md' && this.fill === 'outline';
|
||||
|
||||
if (hasOutlineFill) {
|
||||
/**
|
||||
@@ -892,12 +894,12 @@ export class Select implements ComponentInterface {
|
||||
private renderSelect() {
|
||||
const { disabled, el, isExpanded, expandedIcon, labelPlacement, justify, placeholder, fill, shape, name, value } =
|
||||
this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const hasFloatingOrStackedLabel = labelPlacement === 'floating' || labelPlacement === 'stacked';
|
||||
const justifyEnabled = !hasFloatingOrStackedLabel;
|
||||
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||
@@ -928,7 +930,7 @@ export class Select implements ComponentInterface {
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': inItem,
|
||||
'in-item-color': hostContext('ion-item.ion-color', el),
|
||||
'select-disabled': disabled,
|
||||
@@ -996,7 +998,7 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
}
|
||||
|
||||
const { disabled, el, inputId, isExpanded, expandedIcon, name, placeholder, value } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { labelText, labelId } = getAriaLabel(el, inputId);
|
||||
|
||||
renderHiddenInput(true, el, name, parseValue(value), disabled);
|
||||
@@ -1023,7 +1025,7 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
aria-disabled={disabled ? 'true' : null}
|
||||
aria-label={displayLabel}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'in-item-color': hostContext('ion-item.ion-color', el),
|
||||
'select-disabled': disabled,
|
||||
@@ -1076,14 +1078,14 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
* next to the select text.
|
||||
*/
|
||||
private renderSelectIcon() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { isExpanded, toggleIcon, expandedIcon } = this;
|
||||
let icon: string;
|
||||
|
||||
if (isExpanded && expandedIcon !== undefined) {
|
||||
icon = expandedIcon;
|
||||
} else {
|
||||
const defaultIcon = mode === 'ios' ? chevronExpand : caretDownSharp;
|
||||
const defaultIcon = theme === 'ios' ? chevronExpand : caretDownSharp;
|
||||
icon = toggleIcon ?? defaultIcon;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Component, Element, Event, Host, Prop, h } from '@stencil/core';
|
||||
import { hostContext } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { StyleEventDetail } from '../../interface';
|
||||
|
||||
@Component({
|
||||
@@ -43,12 +43,12 @@ export class SkeletonText implements ComponentInterface {
|
||||
render() {
|
||||
const animated = this.animated && config.getBoolean('animated', true);
|
||||
const inMedia = hostContext('ion-avatar', this.el) || hostContext('ion-thumbnail', this.el);
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'skeleton-text-animated': animated,
|
||||
'in-media': inMedia,
|
||||
}}
|
||||
|
||||
@@ -3,7 +3,7 @@ import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
import type { SpinnerTypes } from './spinner-configs';
|
||||
@@ -41,16 +41,16 @@ export class Spinner implements ComponentInterface {
|
||||
|
||||
private getName(): SpinnerTypes {
|
||||
const spinnerName = this.name || config.get('spinner');
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
if (spinnerName) {
|
||||
return spinnerName;
|
||||
}
|
||||
return mode === 'ios' ? 'lines' : 'circular';
|
||||
return theme === 'ios' ? 'lines' : 'circular';
|
||||
}
|
||||
|
||||
render() {
|
||||
const self = this;
|
||||
const mode = getIonMode(self);
|
||||
const theme = getIonTheme(self);
|
||||
const spinnerName = self.getName();
|
||||
const spinner = SPINNERS[spinnerName] ?? SPINNERS['lines'];
|
||||
const duration = typeof self.duration === 'number' && self.duration > 10 ? self.duration : spinner.dur;
|
||||
@@ -69,7 +69,7 @@ export class Spinner implements ComponentInterface {
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(self.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`spinner-${spinnerName}`]: true,
|
||||
'spinner-paused': self.paused || config.getBoolean('_testing'),
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Build, Component, Element, Event, Host, Prop, State, Watch, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
// TODO(FW-2832): types
|
||||
|
||||
@@ -16,11 +16,15 @@ const QUERY: { [key: string]: string } = {
|
||||
never: '',
|
||||
};
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-split-pane',
|
||||
styleUrls: {
|
||||
ios: 'split-pane.ios.scss',
|
||||
md: 'split-pane.md.scss',
|
||||
ionic: 'split-pane.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -157,14 +161,14 @@ export class SplitPane implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
|
||||
// Used internally for styling
|
||||
[`split-pane-${mode}`]: true,
|
||||
[`split-pane-${theme}`]: true,
|
||||
|
||||
'split-pane-visible': this.visible,
|
||||
}}
|
||||
|
||||
@@ -4,19 +4,21 @@ import type { KeyboardController } from '@utils/keyboard/keyboard-controller';
|
||||
import { createKeyboardController } from '@utils/keyboard/keyboard-controller';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
import type { TabBarChangedEventDetail } from './tab-bar-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-tab-bar',
|
||||
styleUrls: {
|
||||
ios: 'tab-bar.ios.scss',
|
||||
md: 'tab-bar.md.scss',
|
||||
ionic: 'tab-bar.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -96,7 +98,7 @@ export class TabBar implements ComponentInterface {
|
||||
|
||||
render() {
|
||||
const { color, translucent, keyboardVisible } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const shouldHide = keyboardVisible && this.el.getAttribute('slot') !== 'top';
|
||||
|
||||
return (
|
||||
@@ -104,7 +106,7 @@ export class TabBar implements ComponentInterface {
|
||||
role="tablist"
|
||||
aria-hidden={shouldHide ? 'true' : null}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'tab-bar-translucent': translucent,
|
||||
'tab-bar-hidden': shouldHide,
|
||||
})}
|
||||
|
||||
@@ -5,7 +5,7 @@ import type { Attributes } from '@utils/helpers';
|
||||
import { inheritAttributes } from '@utils/helpers';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type {
|
||||
TabBarChangedEventDetail,
|
||||
TabButtonClickEventDetail,
|
||||
@@ -13,7 +13,8 @@ import type {
|
||||
} from '../tab-bar/tab-bar-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part native - The native HTML anchor element that wraps all child elements.
|
||||
*/
|
||||
@@ -22,6 +23,7 @@ import type {
|
||||
styleUrls: {
|
||||
ios: 'tab-button.ios.scss',
|
||||
md: 'tab-button.md.scss',
|
||||
ionic: 'tab-button.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -138,7 +140,7 @@ export class TabButton implements ComponentInterface, AnchorInterface {
|
||||
|
||||
render() {
|
||||
const { disabled, hasIcon, hasLabel, href, rel, target, layout, selected, tab, inheritedAttributes } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const attrs = {
|
||||
download: this.download,
|
||||
href,
|
||||
@@ -152,7 +154,7 @@ export class TabButton implements ComponentInterface, AnchorInterface {
|
||||
onKeyup={this.onKeyUp}
|
||||
id={tab !== undefined ? `tab-button-${tab}` : null}
|
||||
class={{
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'tab-selected': selected,
|
||||
'tab-disabled': disabled,
|
||||
'tab-has-label': hasLabel,
|
||||
@@ -178,7 +180,7 @@ export class TabButton implements ComponentInterface, AnchorInterface {
|
||||
<span class="button-inner">
|
||||
<slot></slot>
|
||||
</span>
|
||||
{mode === 'md' && <ion-ripple-effect type="unbounded"></ion-ripple-effect>}
|
||||
{theme === 'md' && <ion-ripple-effect type="unbounded"></ion-ripple-effect>}
|
||||
</a>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -2,11 +2,11 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, Prop, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-text',
|
||||
@@ -22,11 +22,11 @@ export class Text implements ComponentInterface {
|
||||
@Prop({ reflect: true }) color?: Color;
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
})}
|
||||
>
|
||||
<slot></slot>
|
||||
|
||||
@@ -28,14 +28,15 @@ import { createSlotMutationController } from '@utils/slot-mutation-controller';
|
||||
import type { SlotMutationController } from '@utils/slot-mutation-controller';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail } from '../../interface';
|
||||
import { getCounterText } from '../input/input.utils';
|
||||
|
||||
import type { TextareaChangeEventDetail, TextareaInputEventDetail } from './textarea-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot label - The label text to associate with the textarea. Use the `labelPlacement` property to control where the label is placed relative to the textarea. Use this if you need to render a label with custom HTML. (EXPERIMENTAL)
|
||||
* @slot start - Content to display at the leading edge of the textarea. (EXPERIMENTAL)
|
||||
@@ -46,6 +47,7 @@ import type { TextareaChangeEventDetail, TextareaInputEventDetail } from './text
|
||||
styleUrls: {
|
||||
ios: 'textarea.ios.scss',
|
||||
md: 'textarea.md.scss',
|
||||
ionic: 'textarea.md.scss',
|
||||
},
|
||||
scoped: true,
|
||||
})
|
||||
@@ -572,7 +574,7 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
this.hasLoggedDeprecationWarning = true;
|
||||
}
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const labelId = this.inputId + '-lbl';
|
||||
const label = findItemLabel(this.el);
|
||||
@@ -584,7 +586,7 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
<Host
|
||||
aria-disabled={this.disabled ? 'true' : null}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'legacy-textarea': true,
|
||||
})}
|
||||
>
|
||||
@@ -659,8 +661,8 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
* Renders the border container when fill="outline".
|
||||
*/
|
||||
private renderLabelContainer() {
|
||||
const mode = getIonMode(this);
|
||||
const hasOutlineFill = mode === 'md' && this.fill === 'outline';
|
||||
const theme = getIonTheme(this);
|
||||
const hasOutlineFill = theme === 'md' && this.fill === 'outline';
|
||||
|
||||
if (hasOutlineFill) {
|
||||
/**
|
||||
@@ -741,10 +743,10 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
|
||||
private renderTextarea() {
|
||||
const { inputId, disabled, fill, shape, labelPlacement, el, hasFocus } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const inItem = hostContext('ion-item', this.el);
|
||||
const shouldRenderHighlight = mode === 'md' && fill !== 'outline' && !inItem;
|
||||
const shouldRenderHighlight = theme === 'md' && fill !== 'outline' && !inItem;
|
||||
|
||||
const hasValue = this.hasValue();
|
||||
const hasStartEndSlots = el.querySelector('[slot="start"], [slot="end"]') !== null;
|
||||
@@ -772,7 +774,7 @@ Developers can use the "legacy" property to continue using the legacy form marku
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'has-value': hasValue,
|
||||
'has-focus': hasFocus,
|
||||
'label-floating': labelShouldFloat,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Host, h } from '@stencil/core';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
|
||||
@Component({
|
||||
tag: 'ion-thumbnail',
|
||||
@@ -10,8 +10,13 @@ import { getIonMode } from '../../global/ionic-global';
|
||||
})
|
||||
export class Thumbnail implements ComponentInterface {
|
||||
render() {
|
||||
const theme = getIonTheme(this);
|
||||
return (
|
||||
<Host class={getIonMode(this)}>
|
||||
<Host
|
||||
class={{
|
||||
[theme]: true,
|
||||
}}
|
||||
>
|
||||
<slot></slot>
|
||||
</Host>
|
||||
);
|
||||
|
||||
@@ -2,14 +2,18 @@ import type { ComponentInterface, EventEmitter } from '@stencil/core';
|
||||
import { Component, Element, Event, Host, Prop, Watch, h } from '@stencil/core';
|
||||
import { createColorClasses } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, StyleEventDetail } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*/
|
||||
@Component({
|
||||
tag: 'ion-title',
|
||||
styleUrls: {
|
||||
ios: 'title.ios.scss',
|
||||
md: 'title.md.scss',
|
||||
ionic: 'title.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -56,13 +60,13 @@ export class ToolbarTitle implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const size = this.getSize();
|
||||
|
||||
return (
|
||||
<Host
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
[`title-${size}`]: true,
|
||||
'title-rtl': document.dir === 'rtl',
|
||||
})}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { win } from '@utils/browser';
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
import type { Mode } from 'src/interface';
|
||||
|
||||
import type { Mode } from '../../../interface';
|
||||
import type { ToastAnimationPosition, ToastPosition } from '../toast-interface';
|
||||
|
||||
/**
|
||||
@@ -18,7 +18,7 @@ import type { ToastAnimationPosition, ToastPosition } from '../toast-interface';
|
||||
* @param position The value of the toast's position prop.
|
||||
* @param positionAnchor The element the toast should be anchored to,
|
||||
* if applicable.
|
||||
* @param mode The toast component's mode (md, ios, etc).
|
||||
* @param mode The toast component's platform (md or ios).
|
||||
* @param toast A reference to the toast element itself.
|
||||
*/
|
||||
export function getAnimationPosition(
|
||||
|
||||
@@ -21,7 +21,7 @@ import { sanitizeDOMString } from '@utils/sanitization';
|
||||
import { createColorClasses, getClassMap } from '@utils/theme';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonMode, getIonTheme } from '../../global/ionic-global';
|
||||
import type { AnimationBuilder, Color, CssClassMap, OverlayInterface, FrameworkDelegate } from '../../interface';
|
||||
import type { OverlayEventDetail } from '../../utils/overlays-interface';
|
||||
import type { IonicSafeString } from '../../utils/sanitization';
|
||||
@@ -45,7 +45,8 @@ import type {
|
||||
// TODO(FW-2832): types
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @part button - Any button element that is displayed inside of the toast.
|
||||
* @part button cancel - Any button element with role "cancel" that is displayed inside of the toast.
|
||||
@@ -59,6 +60,7 @@ import type {
|
||||
styleUrls: {
|
||||
ios: 'toast.ios.scss',
|
||||
md: 'toast.md.scss',
|
||||
ionic: 'toast.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -350,13 +352,14 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
*/
|
||||
@Method()
|
||||
async present(): Promise<void> {
|
||||
const mode = getIonMode(this);
|
||||
const unlock = await this.lockController.lock();
|
||||
|
||||
await this.delegateController.attachViewToDom();
|
||||
|
||||
const { el, position } = this;
|
||||
const anchor = this.getAnchorElement();
|
||||
const animationPosition = getAnimationPosition(position, anchor, getIonMode(this), el);
|
||||
const animationPosition = getAnimationPosition(position, anchor, mode, el);
|
||||
|
||||
/**
|
||||
* Cache the calculated position of the toast, so we can re-use it
|
||||
@@ -608,7 +611,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
return;
|
||||
}
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const buttonGroupsClasses = {
|
||||
'toast-button-group': true,
|
||||
[`toast-button-group-${side}`]: true,
|
||||
@@ -635,7 +638,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
)}
|
||||
{b.text}
|
||||
</div>
|
||||
{mode === 'md' && (
|
||||
{theme === 'md' && (
|
||||
<ion-ripple-effect
|
||||
type={b.icon !== undefined && b.text === undefined ? 'unbounded' : 'bounded'}
|
||||
></ion-ripple-effect>
|
||||
@@ -690,7 +693,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
const allButtons = this.getButtons();
|
||||
const startButtons = allButtons.filter((b) => b.side === 'start');
|
||||
const endButtons = allButtons.filter((b) => b.side !== 'start');
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const wrapperClass = {
|
||||
'toast-wrapper': true,
|
||||
[`toast-${this.position}`]: true,
|
||||
@@ -716,7 +719,7 @@ export class Toast implements ComponentInterface, OverlayInterface {
|
||||
zIndex: `${60000 + this.overlayIndex}`,
|
||||
}}
|
||||
class={createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
...getClassMap(this.cssClass),
|
||||
'overlay-hidden': true,
|
||||
'toast-translucent': this.translucent,
|
||||
|
||||
@@ -11,13 +11,14 @@ import { createColorClasses, hostContext } from '@utils/theme';
|
||||
import { checkmarkOutline, removeOutline, ellipseOutline } from 'ionicons/icons';
|
||||
|
||||
import { config } from '../../global/config';
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import type { Color, Gesture, GestureDetail, Mode, StyleEventDetail } from '../../interface';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, Gesture, GestureDetail, StyleEventDetail, Theme } from '../../interface';
|
||||
|
||||
import type { ToggleChangeEventDetail } from './toggle-interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - The label text to associate with the toggle. Use the "labelPlacement" property to control where the label is placed relative to the toggle.
|
||||
*
|
||||
@@ -30,6 +31,7 @@ import type { ToggleChangeEventDetail } from './toggle-interface';
|
||||
styleUrls: {
|
||||
ios: 'toggle.ios.scss',
|
||||
md: 'toggle.md.scss',
|
||||
ionic: 'toggle.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -281,15 +283,15 @@ export class Toggle implements ComponentInterface {
|
||||
this.ionBlur.emit();
|
||||
};
|
||||
|
||||
private getSwitchLabelIcon = (mode: Mode, checked: boolean) => {
|
||||
if (mode === 'md') {
|
||||
private getSwitchLabelIcon = (theme: Theme, checked: boolean) => {
|
||||
if (theme === 'md') {
|
||||
return checked ? checkmarkOutline : removeOutline;
|
||||
}
|
||||
return checked ? removeOutline : ellipseOutline;
|
||||
};
|
||||
|
||||
private renderOnOffSwitchLabels(mode: Mode, checked: boolean) {
|
||||
const icon = this.getSwitchLabelIcon(mode, checked);
|
||||
private renderOnOffSwitchLabels(theme: Theme, checked: boolean) {
|
||||
const icon = this.getSwitchLabelIcon(theme, checked);
|
||||
|
||||
return (
|
||||
<ion-icon
|
||||
@@ -304,7 +306,7 @@ export class Toggle implements ComponentInterface {
|
||||
}
|
||||
|
||||
private renderToggleControl() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
|
||||
const { enableOnOffLabels, checked } = this;
|
||||
return (
|
||||
@@ -313,10 +315,10 @@ export class Toggle implements ComponentInterface {
|
||||
since the wrapper is translated when the handle is interacted with and
|
||||
this would move the on/off labels outside of the view box */}
|
||||
{enableOnOffLabels &&
|
||||
mode === 'ios' && [this.renderOnOffSwitchLabels(mode, true), this.renderOnOffSwitchLabels(mode, false)]}
|
||||
theme === 'ios' && [this.renderOnOffSwitchLabels(theme, true), this.renderOnOffSwitchLabels(theme, false)]}
|
||||
<div class="toggle-icon-wrapper">
|
||||
<div class="toggle-inner" part="handle">
|
||||
{enableOnOffLabels && mode === 'md' && this.renderOnOffSwitchLabels(mode, checked)}
|
||||
{enableOnOffLabels && theme === 'md' && this.renderOnOffSwitchLabels(theme, checked)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -336,7 +338,7 @@ export class Toggle implements ComponentInterface {
|
||||
private renderToggle() {
|
||||
const { activated, color, checked, disabled, el, justify, labelPlacement, inputId, name, alignment } = this;
|
||||
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const value = this.getValue();
|
||||
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
||||
renderHiddenInput(true, el, name, checked ? value : '', disabled);
|
||||
@@ -345,7 +347,7 @@ export class Toggle implements ComponentInterface {
|
||||
<Host
|
||||
onClick={this.onClick}
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'toggle-activated': activated,
|
||||
'toggle-checked': checked,
|
||||
@@ -413,7 +415,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
}
|
||||
|
||||
const { activated, color, checked, disabled, el, inputId, name } = this;
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const { label, labelId, labelText } = getAriaLabel(el, inputId);
|
||||
const value = this.getValue();
|
||||
const rtl = isRTL(el) ? 'rtl' : 'ltr';
|
||||
@@ -428,7 +430,7 @@ Developers can dismiss this warning by removing their usage of the "legacy" prop
|
||||
aria-hidden={disabled ? 'true' : null}
|
||||
role="switch"
|
||||
class={createColorClasses(color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-item': hostContext('ion-item', el),
|
||||
'toggle-activated': activated,
|
||||
'toggle-checked': checked,
|
||||
|
||||
@@ -2,11 +2,12 @@ import type { ComponentInterface } from '@stencil/core';
|
||||
import { Component, Element, Host, Listen, Prop, forceUpdate, h } from '@stencil/core';
|
||||
import { createColorClasses, hostContext } from '@utils/theme';
|
||||
|
||||
import { getIonMode } from '../../global/ionic-global';
|
||||
import { getIonTheme } from '../../global/ionic-global';
|
||||
import type { Color, CssClassMap, StyleEventDetail } from '../../interface';
|
||||
|
||||
/**
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines which platform styles to use.
|
||||
* @virtualProp {"ios" | "md"} mode - The mode determines the platform behaviors of components.
|
||||
* @virtualProp {"ios" | "md" | "ionic"} theme - The theme determines the appearance of components.
|
||||
*
|
||||
* @slot - Content is placed between the named slots if provided without a slot.
|
||||
* @slot start - Content is placed to the left of the toolbar text in LTR, and to the right in RTL.
|
||||
@@ -19,6 +20,7 @@ import type { Color, CssClassMap, StyleEventDetail } from '../../interface';
|
||||
styleUrls: {
|
||||
ios: 'toolbar.ios.scss',
|
||||
md: 'toolbar.md.scss',
|
||||
ionic: 'toolbar.md.scss',
|
||||
},
|
||||
shadow: true,
|
||||
})
|
||||
@@ -82,7 +84,7 @@ export class Toolbar implements ComponentInterface {
|
||||
}
|
||||
|
||||
render() {
|
||||
const mode = getIonMode(this);
|
||||
const theme = getIonTheme(this);
|
||||
const childStyles = {};
|
||||
this.childrenStyles.forEach((value) => {
|
||||
Object.assign(childStyles, value);
|
||||
@@ -92,7 +94,7 @@ export class Toolbar implements ComponentInterface {
|
||||
class={{
|
||||
...childStyles,
|
||||
...createColorClasses(this.color, {
|
||||
[mode]: true,
|
||||
[theme]: true,
|
||||
'in-toolbar': hostContext('ion-toolbar', this.el),
|
||||
}),
|
||||
}}
|
||||
|
||||
@@ -1,18 +1,58 @@
|
||||
import { getMode, setMode, setPlatformHelpers } from '@stencil/core';
|
||||
import { getMode, setMode, setPlatformHelpers, getElement } from '@stencil/core';
|
||||
import { printIonWarning } from '@utils/logging';
|
||||
|
||||
import type { IonicConfig, Mode } from '../interface';
|
||||
import type { IonicConfig, Mode, Theme } from '../interface';
|
||||
import { isPlatform, setupPlatforms } from '../utils/platform';
|
||||
|
||||
import { config, configFromSession, configFromURL, saveConfig } from './config';
|
||||
|
||||
// TODO(FW-2832): types
|
||||
|
||||
let defaultMode: Mode;
|
||||
let defaultTheme: Theme;
|
||||
|
||||
export const getIonMode = (ref?: any): Mode => {
|
||||
return (ref && getMode(ref)) || defaultMode;
|
||||
if (ref?.mode) {
|
||||
return ref.mode;
|
||||
}
|
||||
|
||||
const theme = getMode(ref);
|
||||
|
||||
if (theme === 'ios' || theme === 'md') {
|
||||
return theme;
|
||||
}
|
||||
|
||||
const el = getElement(ref);
|
||||
return el.closest('[mode]')?.getAttribute('mode') as Mode || defaultMode;
|
||||
|
||||
};
|
||||
|
||||
export const getIonTheme = (ref?: any): Theme => {
|
||||
return (ref && getMode(ref)) || getIonMode(ref) || defaultTheme;
|
||||
}
|
||||
|
||||
// export const getIonPlatform = (ref?: any): Platform => {
|
||||
// if (ref?.platform) {
|
||||
// return ref.platform;
|
||||
// }
|
||||
|
||||
// // TODO remove mode in the future
|
||||
// if (ref?.mode) {
|
||||
// return ref.mode;
|
||||
// }
|
||||
|
||||
// const el = getElement(ref);
|
||||
// return el.closest('[platform]')?.getAttribute('platform') as Platform || defaultPlatform;
|
||||
// }
|
||||
|
||||
|
||||
/**
|
||||
* @deprecated
|
||||
*/
|
||||
const isModeSupported = (elmMode: string) => ['ios', 'md'].includes(elmMode);
|
||||
|
||||
const isThemeSupported = (theme: string) => ['ios', 'md'].includes(theme);
|
||||
|
||||
const isIonicElement = (elm: HTMLElement) => elm.tagName?.startsWith('ION-');
|
||||
|
||||
export const initialize = (userConfig: IonicConfig = {}) => {
|
||||
if (typeof (window as any) === 'undefined') {
|
||||
return;
|
||||
@@ -56,35 +96,57 @@ export const initialize = (userConfig: IonicConfig = {}) => {
|
||||
// which could have been set by the user, or by pre-rendering
|
||||
// otherwise get the mode via config settings, and fallback to md
|
||||
Ionic.config = config;
|
||||
Ionic.mode = defaultMode = config.get(
|
||||
'mode',
|
||||
doc.documentElement.getAttribute('mode') || (isPlatform(win, 'ios') ? 'ios' : 'md')
|
||||
);
|
||||
config.set('mode', defaultMode);
|
||||
doc.documentElement.setAttribute('mode', defaultMode);
|
||||
doc.documentElement.classList.add(defaultMode);
|
||||
|
||||
const theme = config.get('theme', doc.documentElement.getAttribute('theme'));
|
||||
|
||||
if (theme) {
|
||||
Ionic.theme = defaultTheme = theme;
|
||||
config.set('theme', defaultTheme);
|
||||
doc.documentElement.setAttribute('theme', defaultTheme);
|
||||
doc.documentElement.classList.add(defaultTheme);
|
||||
} else {
|
||||
Ionic.mode = defaultMode = config.get(
|
||||
'mode',
|
||||
doc.documentElement.getAttribute('mode') || (isPlatform(win, 'ios') ? 'ios' : 'md')
|
||||
);
|
||||
config.set('mode', defaultMode);
|
||||
doc.documentElement.setAttribute('mode', defaultMode);
|
||||
doc.documentElement.classList.add(defaultMode);
|
||||
}
|
||||
|
||||
if (config.getBoolean('_testing')) {
|
||||
config.set('animated', false);
|
||||
}
|
||||
|
||||
const isIonicElement = (elm: any) => elm.tagName?.startsWith('ION-');
|
||||
|
||||
const isAllowedIonicModeValue = (elmMode: string) => ['ios', 'md'].includes(elmMode);
|
||||
|
||||
setMode((elm: any) => {
|
||||
while (elm) {
|
||||
const elmMode = (elm as any).mode || elm.getAttribute('mode');
|
||||
if (elmMode) {
|
||||
if (isAllowedIonicModeValue(elmMode)) {
|
||||
return elmMode;
|
||||
const theme = (elm as any).theme || elm.getAttribute('theme');
|
||||
|
||||
if (theme) {
|
||||
if (isThemeSupported(theme)) {
|
||||
return theme;
|
||||
} else if (isIonicElement(elm)) {
|
||||
console.warn('Invalid ionic mode: "' + elmMode + '", expected: "ios" or "md"');
|
||||
printIonWarning(`Invalid theme: "${theme}". Supported themes include: "ios" or "md".`);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* If a theme is not detected, then fallback to using the
|
||||
* `mode` attribute to determine the style sheets to use.
|
||||
*/
|
||||
const elmMode = (elm as any).mode || elm.getAttribute('mode');
|
||||
|
||||
if (elmMode) {
|
||||
if (isModeSupported(elmMode)) {
|
||||
return elmMode;
|
||||
} else if (isIonicElement(elm)) {
|
||||
printIonWarning(`Invalid mode: "${elmMode}". Ionic modes can be only "ios" or "md"`);
|
||||
}
|
||||
}
|
||||
|
||||
elm = elm.parentElement;
|
||||
}
|
||||
return defaultMode;
|
||||
return defaultTheme;
|
||||
});
|
||||
};
|
||||
|
||||
|
||||
3
core/src/interface.d.ts
vendored
3
core/src/interface.d.ts
vendored
@@ -134,6 +134,9 @@ export type PredefinedColors =
|
||||
export type LiteralUnion<T extends U, U = string> = T | (U & Record<never, never>);
|
||||
|
||||
export type Color = LiteralUnion<PredefinedColors, string>;
|
||||
|
||||
export type Theme = 'ios' | 'md' | 'ionic';
|
||||
|
||||
export type Mode = 'ios' | 'md';
|
||||
export type ComponentTags = string;
|
||||
// eslint-disable-next-line
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import type { SpinnerTypes } from '../components/spinner/spinner-configs';
|
||||
import type { TabButtonLayout } from '../components/tab-bar/tab-bar-interface';
|
||||
import type { AnimationBuilder, Mode } from '../interface';
|
||||
import type { AnimationBuilder, Mode, Theme } from '../interface';
|
||||
|
||||
import type { PlatformConfig } from './platform';
|
||||
|
||||
@@ -22,6 +22,11 @@ export interface IonicConfig {
|
||||
*/
|
||||
mode?: Mode;
|
||||
|
||||
/**
|
||||
* The theme determines the appearance of components.
|
||||
*/
|
||||
theme?: Theme;
|
||||
|
||||
/**
|
||||
* Wherever ionic will respond to hardware go back buttons in an Android device.
|
||||
* Defaults to `true` when ionic runs in a mobile device.
|
||||
|
||||
@@ -16,6 +16,7 @@ export const menuPushAnimation = (menu: MenuI): Animation => {
|
||||
|
||||
const mode = getIonMode(menu);
|
||||
const width = menu.width;
|
||||
const isIos = mode === 'ios';
|
||||
|
||||
if (menu.isEndSide) {
|
||||
contentOpenedX = -width + 'px';
|
||||
@@ -35,5 +36,5 @@ export const menuPushAnimation = (menu: MenuI): Animation => {
|
||||
|
||||
const backdropAnimation = createAnimation().addElement(menu.backdropEl!).fromTo('opacity', 0.01, 0.32);
|
||||
|
||||
return baseAnimation(mode === 'ios').addAnimation([menuAnimation, contentAnimation, backdropAnimation]);
|
||||
return baseAnimation(isIos).addAnimation([menuAnimation, contentAnimation, backdropAnimation]);
|
||||
};
|
||||
|
||||
@@ -12,10 +12,11 @@ import { baseAnimation } from './base';
|
||||
*/
|
||||
export const menuRevealAnimation = (menu: MenuI): Animation => {
|
||||
const mode = getIonMode(menu);
|
||||
const isIos = mode === 'ios';
|
||||
const openedX = menu.width * (menu.isEndSide ? -1 : 1) + 'px';
|
||||
const contentOpen = createAnimation()
|
||||
.addElement(menu.contentEl!) // REVIEW
|
||||
.fromTo('transform', 'translateX(0px)', `translateX(${openedX})`);
|
||||
|
||||
return baseAnimation(mode === 'ios').addAnimation(contentOpen);
|
||||
return baseAnimation(isIos).addAnimation(contentOpen);
|
||||
};
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user