@rdlabo/ionic-theme-md3 1.0.0 → 1.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,2 @@
1
+ export * from './transition/md.transition';
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,4BAA4B,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ export * from './transition/md.transition';
@@ -0,0 +1,13 @@
1
+ import type { Animation, NavOptions } from '@ionic/core';
2
+ export declare const getIonPageElement: (element: HTMLElement) => Element;
3
+ export interface TransitionOptions extends NavOptions {
4
+ progressCallback?: (ani: Animation | undefined) => void;
5
+ baseEl: any;
6
+ enteringEl: HTMLElement;
7
+ leavingEl: HTMLElement | undefined;
8
+ }
9
+ export interface TransitionResult {
10
+ hasCompleted: boolean;
11
+ animation?: Animation;
12
+ }
13
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/transition/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAEzD,eAAO,MAAM,iBAAiB,GAAI,SAAS,WAAW,YAWrD,CAAC;AAEF,MAAM,WAAW,iBAAkB,SAAQ,UAAU;IACnD,gBAAgB,CAAC,EAAE,CAAC,GAAG,EAAE,SAAS,GAAG,SAAS,KAAK,IAAI,CAAC;IACxD,MAAM,EAAE,GAAG,CAAC;IACZ,UAAU,EAAE,WAAW,CAAC;IACxB,SAAS,EAAE,WAAW,GAAG,SAAS,CAAC;CACpC;AAED,MAAM,WAAW,gBAAgB;IAC/B,YAAY,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB"}
@@ -0,0 +1,10 @@
1
+ export const getIonPageElement = (element) => {
2
+ if (element.classList.contains('ion-page')) {
3
+ return element;
4
+ }
5
+ const ionPage = element.querySelector(':scope > .ion-page, :scope > ion-nav, :scope > ion-tabs');
6
+ if (ionPage) {
7
+ return ionPage;
8
+ }
9
+ return element;
10
+ };
@@ -0,0 +1,4 @@
1
+ import type { Animation } from '@ionic/core/dist/types/utils/animation/animation-interface';
2
+ import type { TransitionOptions } from './index';
3
+ export declare const mdTransitionAnimation: (_: HTMLElement, opts: TransitionOptions) => Animation;
4
+ //# sourceMappingURL=md.transition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"md.transition.d.ts","sourceRoot":"","sources":["../../src/transition/md.transition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,4DAA4D,CAAC;AAE5F,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAGjD,eAAO,MAAM,qBAAqB,GAAI,GAAG,WAAW,EAAE,MAAM,iBAAiB,KAAG,SAwE/E,CAAC"}
@@ -0,0 +1,63 @@
1
+ import { createAnimation } from '@ionic/core';
2
+ import { getIonPageElement } from './index';
3
+ export const mdTransitionAnimation = (_, opts) => {
4
+ const OFF_BOTTOM = 40;
5
+ const CENTER = 0;
6
+ const backDirection = opts.direction === 'back';
7
+ const enteringEl = opts.enteringEl;
8
+ const leavingEl = opts.leavingEl;
9
+ const ionPageElement = getIonPageElement(enteringEl);
10
+ const enteringToolbarEle = ionPageElement.querySelector('ion-toolbar');
11
+ const rootTransition = createAnimation();
12
+ rootTransition.addElement(ionPageElement).fill('both').beforeRemoveClass('ion-page-invisible');
13
+ if (backDirection) {
14
+ rootTransition.duration((opts.duration ?? 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
15
+ }
16
+ else {
17
+ rootTransition
18
+ .duration((opts.duration ?? 0) || 280)
19
+ .easing('cubic-bezier(0.36,0.66,0.04,1)')
20
+ .fromTo('transform', `translateX(${OFF_BOTTOM}px)`, `translateX(${CENTER}px)`)
21
+ .fromTo('opacity', 0.01, 1);
22
+ }
23
+ if (enteringToolbarEle) {
24
+ const enteringToolBar = createAnimation();
25
+ enteringToolBar.addElement(enteringToolbarEle);
26
+ rootTransition.addAnimation(enteringToolBar);
27
+ }
28
+ if (leavingEl) {
29
+ const stackedTransition = createAnimation();
30
+ const stackedElement = getIonPageElement(leavingEl);
31
+ const stackedAnimationElement = stackedElement.querySelectorAll('ion-toolbar, ion-content > *');
32
+ if (!backDirection) {
33
+ stackedTransition.addElement(stackedAnimationElement);
34
+ stackedTransition
35
+ .duration((opts.duration ?? 0) || 280)
36
+ .easing('cubic-bezier(0.36,0.66,0.04,1)')
37
+ .fromTo('transform', `translateX(${CENTER}px)`, `translateX(${OFF_BOTTOM * -1}px)`);
38
+ }
39
+ else if (backDirection) {
40
+ stackedTransition.addElement(ionPageElement);
41
+ stackedTransition
42
+ .duration((opts.duration ?? 0) || 200)
43
+ .easing('cubic-bezier(0.36,0.66,0.04,1)')
44
+ .fromTo('transform', `translateX(${OFF_BOTTOM * -1}px)`, `translateX(${CENTER}px)`);
45
+ }
46
+ rootTransition.addAnimation(stackedTransition);
47
+ }
48
+ if (leavingEl && backDirection) {
49
+ rootTransition.duration((opts.duration ?? 0) || 200).easing('cubic-bezier(0.47,0,0.745,0.715)');
50
+ const leavingPage = createAnimation();
51
+ leavingPage
52
+ .addElement(getIonPageElement(leavingEl))
53
+ .onFinish((currentStep) => {
54
+ if (currentStep === 1 && leavingPage.elements.length > 0) {
55
+ leavingPage.elements[0].style.setProperty('display', 'none');
56
+ }
57
+ })
58
+ .fromTo('transform', `translateX(${CENTER}px)`, `translateX(${OFF_BOTTOM}px)`)
59
+ .fromTo('opacity', 1, 0);
60
+ rootTransition.addAnimation(leavingPage);
61
+ }
62
+ return rootTransition;
63
+ };
package/package.json CHANGED
@@ -1,14 +1,27 @@
1
1
  {
2
2
  "name": "@rdlabo/ionic-theme-md3",
3
- "version": "1.0.0",
3
+ "version": "1.0.1",
4
4
  "description": "Material Design 3 Theme for Ionic Framework",
5
+ "main": "./dist/index.js",
6
+ "module": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "exports": {
9
+ ".": {
10
+ "types": "./dist/index.d.ts",
11
+ "import": "./dist/index.js"
12
+ },
13
+ "./dist/css/*": "./dist/css/*",
14
+ "./src/styles/*": "./src/styles/*"
15
+ },
5
16
  "files": [
6
17
  "dist",
7
18
  "src",
8
19
  "package.json"
9
20
  ],
10
21
  "scripts": {
11
- "build": "rm -rf dist/css && sass src/styles:dist/css --style=compressed --no-source-map",
22
+ "build": "npm run build:css && npm run build:ts",
23
+ "build:css": "rm -rf dist/css && sass src/styles:dist/css --style=compressed --no-source-map",
24
+ "build:ts": "tsc",
12
25
  "build:demo": "npm run build && cd demo && npm install && npm run build -- --configuration=production",
13
26
  "lint": "prettier --check \"./**/*.{scss,ts}\" && prettier --parser angular --check \"./**/*.html\"",
14
27
  "fmt": "prettier --write \"./**/*.{scss,ts}\" && prettier --parser angular --write \"./**/*.html\"",
@@ -1,123 +0,0 @@
1
- import { config } from '../utils';
2
- // import { printIonWarning} from '@ionic/core/dist/types/utils/logging';
3
-
4
- /**
5
- * Moves focus to a specified element. Note that we do not remove the tabindex
6
- * because that can result in an unintentional blur. Non-focusables can't be
7
- * focused, so the body will get focused again.
8
- */
9
- const moveFocus = (el: HTMLElement) => {
10
- el.tabIndex = -1;
11
- el.focus();
12
- };
13
-
14
- /**
15
- * Elements that are hidden using `display: none` should not be focused even if
16
- * they are present in the DOM.
17
- */
18
- const isVisible = (el: HTMLElement) => {
19
- return el.offsetParent !== null;
20
- };
21
-
22
- /**
23
- * The focus controller allows us to manage focus within a view so assistive
24
- * technologies can inform users of changes to the navigation state. Traditional
25
- * native apps have a way of informing assistive technology about a navigation
26
- * state change. Mobile browsers have this too, but only when doing a full page
27
- * load. In a single page app we do not do that, so we need to build this
28
- * integration ourselves.
29
- */
30
- export const createFocusController = (): FocusController => {
31
- const saveViewFocus = (referenceEl?: HTMLElement) => {
32
- const focusManagerEnabled = config.get('focusManagerPriority', false);
33
-
34
- /**
35
- * When going back to a previously visited page focus should typically be moved
36
- * back to the element that was last focused when the user was on this view.
37
- */
38
- if (focusManagerEnabled) {
39
- const activeEl = document.activeElement;
40
- if (activeEl !== null && referenceEl?.contains(activeEl)) {
41
- activeEl.setAttribute(LAST_FOCUS, 'true');
42
- }
43
- }
44
- };
45
-
46
- const setViewFocus = (referenceEl: HTMLElement) => {
47
- const focusManagerPriorities = config.get('focusManagerPriority', false);
48
- /**
49
- * If the focused element is a descendant of the referenceEl then it's possible
50
- * that the app developer manually moved focus, so we do not want to override that.
51
- * This can happen with inputs the are focused when a view transitions in.
52
- */
53
- if (Array.isArray(focusManagerPriorities) && !referenceEl.contains(document.activeElement)) {
54
- /**
55
- * When going back to a previously visited view focus should always be moved back
56
- * to the element that the user was last focused on when they were on this view.
57
- */
58
- const lastFocus = referenceEl.querySelector<HTMLElement>(`[${LAST_FOCUS}]`);
59
- if (lastFocus && isVisible(lastFocus)) {
60
- moveFocus(lastFocus);
61
- return;
62
- }
63
-
64
- for (const priority of focusManagerPriorities) {
65
- /**
66
- * For each recognized case (excluding the default case) make sure to return
67
- * so that the fallback focus behavior does not run.
68
- *
69
- * We intentionally query for specific roles/semantic elements so that the
70
- * transition manager can work with both Ionic and non-Ionic UI components.
71
- *
72
- * If new selectors are added, be sure to remove the outline ring by adding
73
- * new selectors to rule in core.scss.
74
- */
75
- switch (priority) {
76
- case 'content':
77
- const content = referenceEl.querySelector<HTMLElement>('main, [role="main"]');
78
- if (content && isVisible(content)) {
79
- moveFocus(content);
80
- return;
81
- }
82
- break;
83
- case 'heading':
84
- const headingOne = referenceEl.querySelector<HTMLElement>('h1, [role="heading"][aria-level="1"]');
85
- if (headingOne && isVisible(headingOne)) {
86
- moveFocus(headingOne);
87
- return;
88
- }
89
- break;
90
- case 'banner':
91
- const header = referenceEl.querySelector<HTMLElement>('header, [role="banner"]');
92
- if (header && isVisible(header)) {
93
- moveFocus(header);
94
- return;
95
- }
96
- break;
97
- default:
98
- // printIonWarning(`Unrecognized focus manager priority value ${priority}`);
99
- break;
100
- }
101
- }
102
-
103
- /**
104
- * If there is nothing to focus then focus the page so focus at least moves to
105
- * the correct view. The browser will then determine where within the page to
106
- * move focus to.
107
- */
108
- moveFocus(referenceEl);
109
- }
110
- };
111
-
112
- return {
113
- saveViewFocus,
114
- setViewFocus,
115
- };
116
- };
117
-
118
- export type FocusController = {
119
- saveViewFocus: (referenceEl?: HTMLElement) => void;
120
- setViewFocus: (referenceEl: HTMLElement) => void;
121
- };
122
-
123
- const LAST_FOCUS = 'ion-last-focus';