@rdlabo/ionic-theme-ios26 1.1.1 → 1.2.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.
Files changed (49) hide show
  1. package/README.md +62 -3
  2. package/dist/css/components/ion-button.css +1 -1
  3. package/dist/css/components/ion-fab.css +1 -1
  4. package/dist/css/components/ion-searchbar.css +1 -1
  5. package/dist/css/components/ion-toggle.css +1 -1
  6. package/dist/css/components/ion-toolbar.css +1 -1
  7. package/dist/css/ionic-theme-ios26.css +1 -1
  8. package/dist/css/utils/searchable.css +1 -0
  9. package/dist/index.d.ts +1 -0
  10. package/dist/index.d.ts.map +1 -1
  11. package/dist/index.js +1 -0
  12. package/dist/popover/animations/ios.enter.d.ts.map +1 -1
  13. package/dist/popover/animations/ios.enter.js +3 -17
  14. package/dist/popover/utils.d.ts +2 -13
  15. package/dist/popover/utils.d.ts.map +1 -1
  16. package/dist/popover/utils.js +11 -119
  17. package/dist/sheets-of-glass/index.d.ts.map +1 -1
  18. package/dist/sheets-of-glass/index.js +6 -1
  19. package/dist/tab-bar-searchable/animations/enter.d.ts +8 -0
  20. package/dist/tab-bar-searchable/animations/enter.d.ts.map +1 -0
  21. package/dist/tab-bar-searchable/animations/enter.js +73 -0
  22. package/dist/tab-bar-searchable/animations/leave.d.ts +8 -0
  23. package/dist/tab-bar-searchable/animations/leave.d.ts.map +1 -0
  24. package/dist/tab-bar-searchable/animations/leave.js +66 -0
  25. package/dist/tab-bar-searchable/index.d.ts +4 -0
  26. package/dist/tab-bar-searchable/index.d.ts.map +1 -0
  27. package/dist/tab-bar-searchable/index.js +75 -0
  28. package/dist/tab-bar-searchable/interfaces.d.ts +41 -0
  29. package/dist/tab-bar-searchable/interfaces.d.ts.map +1 -0
  30. package/dist/tab-bar-searchable/interfaces.js +5 -0
  31. package/dist/tab-bar-searchable/utils.d.ts +12 -0
  32. package/dist/tab-bar-searchable/utils.d.ts.map +1 -0
  33. package/dist/tab-bar-searchable/utils.js +60 -0
  34. package/package.json +1 -1
  35. package/src/index.ts +1 -0
  36. package/src/popover/animations/ios.enter.ts +20 -52
  37. package/src/popover/utils.ts +8 -230
  38. package/src/sheets-of-glass/index.ts +6 -1
  39. package/src/styles/components/ion-button.scss +6 -0
  40. package/src/styles/components/ion-fab.scss +31 -1
  41. package/src/styles/components/ion-searchbar.scss +10 -0
  42. package/src/styles/components/ion-toggle.scss +3 -0
  43. package/src/styles/components/ion-toolbar.scss +20 -0
  44. package/src/styles/utils/searchable.scss +0 -0
  45. package/src/tab-bar-searchable/animations/enter.ts +92 -0
  46. package/src/tab-bar-searchable/animations/leave.ts +89 -0
  47. package/src/tab-bar-searchable/index.ts +141 -0
  48. package/src/tab-bar-searchable/interfaces.ts +28 -0
  49. package/src/tab-bar-searchable/utils.ts +75 -0
@@ -1,7 +1,7 @@
1
- import { createAnimation, isPlatform } from '@ionic/core';
1
+ import { createAnimation } from '@ionic/core';
2
2
  import type { Animation } from '@ionic/core/dist/types/utils/animation/animation-interface';
3
3
  import { getElementRoot } from '../../utils';
4
- import { calculateWindowAdjustment, getArrowDimensions, getPopoverDimensions, getPopoverPosition, shouldShowArrow } from '../utils';
4
+ import { calculateWindowAdjustment, getPopoverDimensions, getPopoverPosition } from '../utils';
5
5
 
6
6
  const POPOVER_IOS_BODY_PADDING = 5;
7
7
  export const POPOVER_IOS_BODY_MARGIN = 8;
@@ -19,11 +19,9 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
19
19
 
20
20
  const root = getElementRoot(baseEl);
21
21
  const contentEl = root.querySelector('.popover-content') as HTMLElement;
22
- const arrowEl = root.querySelector('.popover-arrow') as HTMLElement | null;
23
22
 
24
23
  const referenceSizeEl = trigger || ev?.detail?.ionShadowTarget || ev?.target;
25
24
  const { contentWidth, contentHeight } = getPopoverDimensions(size, contentEl, referenceSizeEl);
26
- const { arrowWidth, arrowHeight } = getArrowDimensions(arrowEl);
27
25
 
28
26
  const isReplace = ((): boolean => {
29
27
  if (!['ion-button', 'ion-buttons'].includes(referenceSizeEl.localName)) {
@@ -42,43 +40,27 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
42
40
  originY: 'top',
43
41
  };
44
42
 
45
- const results = getPopoverPosition(
46
- isRTL,
47
- contentWidth,
48
- contentHeight,
49
- arrowWidth,
50
- arrowHeight,
51
- reference,
52
- side,
53
- align,
54
- defaultPosition,
55
- trigger,
56
- ev,
57
- );
43
+ const results = getPopoverPosition(isRTL, contentWidth, contentHeight, reference, side, align, defaultPosition, trigger, ev);
58
44
 
59
45
  const padding = size === 'cover' ? 0 : POPOVER_IOS_BODY_PADDING;
60
46
  const margin = size === 'cover' ? 0 : 25;
61
47
 
62
- const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, arrowTop, arrowLeft, addPopoverBottomClass } =
63
- calculateWindowAdjustment(
64
- side,
65
- results.top,
66
- results.left,
67
- padding,
68
- bodyWidth,
69
- bodyHeight,
70
- contentWidth,
71
- contentHeight,
72
- margin,
73
- results.originX,
74
- results.originY,
75
- results.referenceCoordinates,
76
- results.arrowTop,
77
- results.arrowLeft,
78
- arrowHeight,
79
- referenceSizeEl.getBoundingClientRect(),
80
- isReplace,
81
- );
48
+ const { originX, originY, top, left, bottom, checkSafeAreaLeft, checkSafeAreaRight, addPopoverBottomClass } = calculateWindowAdjustment(
49
+ side,
50
+ results.top,
51
+ results.left,
52
+ padding,
53
+ bodyWidth,
54
+ bodyHeight,
55
+ contentWidth,
56
+ contentHeight,
57
+ margin,
58
+ results.originX,
59
+ results.originY,
60
+ results.referenceCoordinates,
61
+ referenceSizeEl.getBoundingClientRect(),
62
+ isReplace,
63
+ );
82
64
 
83
65
  const baseAnimation = createAnimation();
84
66
  const backdropAnimation = createAnimation();
@@ -97,13 +79,12 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
97
79
 
98
80
  // In Chromium, if the wrapper animates, the backdrop filter doesn't work.
99
81
  // The Chromium team stated that this behavior is expected and not a bug. The element animating opacity creates a backdrop root for the backdrop-filter.
100
- // To get around this, instead of animating the wrapper, animate both the arrow and content.
82
+ // To get around this, instead of animating the wrapper, animate content.
101
83
  // https://bugs.chromium.org/p/chromium/issues/detail?id=1148826
102
84
  contentAnimation
103
85
  .easing('cubic-bezier(0, 1, 0.22, 1)')
104
86
  .delay(100)
105
87
  .duration(400)
106
- .addElement(root.querySelector('.popover-arrow')!)
107
88
  .addElement(root.querySelector('.popover-content')!)
108
89
  .beforeStyles({ 'transform-origin': `${originY} ${originX}` })
109
90
  .beforeAddWrite(() => {
@@ -114,7 +95,6 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
114
95
  })
115
96
  .fromTo('transform', 'scale(0)', 'scale(1)')
116
97
  .fromTo('opacity', 0.01, 1);
117
- // TODO(FW-4376) Ensure that arrow also blurs when translucent
118
98
 
119
99
  if (isReplace) {
120
100
  targetAnimation
@@ -159,18 +139,6 @@ export const iosEnterAnimation = (baseEl: HTMLElement, opts?: any): Animation =>
159
139
  contentEl.style.setProperty('top', `calc(${top}px + var(--offset-y, 0))`);
160
140
  contentEl.style.setProperty('left', `calc(${leftValue} + var(--offset-x, 0))`);
161
141
  contentEl.style.setProperty('transform-origin', `${originY} ${originX}`);
162
-
163
- if (arrowEl !== null) {
164
- const didAdjustBounds = results.top !== top || results.left !== left;
165
- const showArrow = shouldShowArrow(side, didAdjustBounds, ev, trigger);
166
-
167
- if (showArrow) {
168
- arrowEl.style.setProperty('top', `calc(${arrowTop}px + var(--offset-y, 0))`);
169
- arrowEl.style.setProperty('left', `calc(${arrowLeft}px + var(--offset-x, 0))`);
170
- } else {
171
- arrowEl.style.setProperty('display', 'none');
172
- }
173
- }
174
142
  })
175
143
  .addAnimation([backdropAnimation, contentAnimation, targetAnimation]);
176
144
  };
@@ -19,8 +19,6 @@ interface PopoverPosition {
19
19
  top: number;
20
20
  left: number;
21
21
  referenceCoordinates?: ReferenceCoordinates;
22
- arrowTop?: number;
23
- arrowLeft?: number;
24
22
  originX: string;
25
23
  originY: string;
26
24
  }
@@ -33,25 +31,9 @@ export interface PopoverStyles {
33
31
  originY: string;
34
32
  checkSafeAreaLeft: boolean;
35
33
  checkSafeAreaRight: boolean;
36
- arrowTop: number;
37
- arrowLeft: number;
38
34
  addPopoverBottomClass: boolean;
39
35
  }
40
36
 
41
- /**
42
- * Returns the dimensions of the popover
43
- * arrow on `ios` mode. If arrow is disabled
44
- * returns (0, 0).
45
- */
46
- export const getArrowDimensions = (arrowEl: HTMLElement | null) => {
47
- if (!arrowEl) {
48
- return { arrowWidth: 0, arrowHeight: 0 };
49
- }
50
- const { width, height } = arrowEl.getBoundingClientRect();
51
-
52
- return { arrowWidth: width, arrowHeight: height };
53
- };
54
-
55
37
  /**
56
38
  * Returns the recommended dimensions of the popover
57
39
  * that takes into account whether or not the width
@@ -324,119 +306,6 @@ const focusItem = (item: HTMLIonItemElement) => {
324
306
  }
325
307
  };
326
308
 
327
- /**
328
- * Returns `true` if `el` has been designated
329
- * as a trigger element for an ion-popover.
330
- */
331
- export const isTriggerElement = (el: HTMLElement) => el.hasAttribute('data-ion-popover-trigger');
332
-
333
- export const configureKeyboardInteraction = (popoverEl: HTMLIonPopoverElement) => {
334
- const callback = async (ev: KeyboardEvent) => {
335
- const activeElement = document.activeElement as HTMLElement | null;
336
- let items: HTMLIonItemElement[] = [];
337
-
338
- const targetTagName = (ev.target as HTMLElement)?.tagName;
339
- /**
340
- * Only handle custom keyboard interactions for the host popover element
341
- * and children ion-item elements.
342
- */
343
- if (targetTagName !== 'ION-POPOVER' && targetTagName !== 'ION-ITEM') {
344
- return;
345
- }
346
- /**
347
- * Complex selectors with :not() are :not supported
348
- * in older versions of Chromium so we need to do a
349
- * try/catch here so errors are not thrown.
350
- */
351
- try {
352
- /**
353
- * Select all ion-items that are not children of child popovers.
354
- * i.e. only select ion-item elements that are part of this popover
355
- */
356
- items = Array.from(
357
- popoverEl.querySelectorAll('ion-item:not(ion-popover ion-popover *):not([disabled])') as NodeListOf<HTMLIonItemElement>,
358
- );
359
- /* eslint-disable-next-line */
360
- } catch {}
361
-
362
- switch (ev.key) {
363
- /**
364
- * If we are in a child popover
365
- * then pressing the left arrow key
366
- * should close this popover and move
367
- * focus to the popover that presented
368
- * this one.
369
- */
370
- case 'ArrowLeft':
371
- const parentPopover = await popoverEl.getParentPopover();
372
- if (parentPopover) {
373
- popoverEl.dismiss(undefined, undefined, false);
374
- }
375
- break;
376
- /**
377
- * ArrowDown should move focus to the next focusable ion-item.
378
- */
379
- case 'ArrowDown':
380
- // Disable movement/scroll with keyboard
381
- ev.preventDefault();
382
- const nextItem = getNextItem(items, activeElement);
383
- if (nextItem !== undefined) {
384
- focusItem(nextItem);
385
- }
386
- break;
387
- /**
388
- * ArrowUp should move focus to the previous focusable ion-item.
389
- */
390
- case 'ArrowUp':
391
- // Disable movement/scroll with keyboard
392
- ev.preventDefault();
393
- const prevItem = getPrevItem(items, activeElement);
394
- if (prevItem !== undefined) {
395
- focusItem(prevItem);
396
- }
397
- break;
398
- /**
399
- * Home should move focus to the first focusable ion-item.
400
- */
401
- case 'Home':
402
- ev.preventDefault();
403
- const firstItem = items[0];
404
- if (firstItem !== undefined) {
405
- focusItem(firstItem);
406
- }
407
- break;
408
- /**
409
- * End should move focus to the last focusable ion-item.
410
- */
411
- case 'End':
412
- ev.preventDefault();
413
- const lastItem = items[items.length - 1];
414
- if (lastItem !== undefined) {
415
- focusItem(lastItem);
416
- }
417
- break;
418
- /**
419
- * ArrowRight, Spacebar, or Enter should activate
420
- * the currently focused trigger item to open a
421
- * popover if the element is a trigger item.
422
- */
423
- case 'ArrowRight':
424
- case ' ':
425
- case 'Enter':
426
- if (activeElement && isTriggerElement(activeElement)) {
427
- const rightEvent = new CustomEvent('ionPopoverActivateTrigger');
428
- activeElement.dispatchEvent(rightEvent);
429
- }
430
- break;
431
- default:
432
- break;
433
- }
434
- };
435
-
436
- popoverEl.addEventListener('keydown', callback);
437
- return () => popoverEl.removeEventListener('keydown', callback);
438
- };
439
-
440
309
  /**
441
310
  * Positions a popover by taking into account
442
311
  * the reference point, preferred side, alignment
@@ -446,8 +315,6 @@ export const getPopoverPosition = (
446
315
  isRTL: boolean,
447
316
  contentWidth: number,
448
317
  contentHeight: number,
449
- arrowWidth: number,
450
- arrowHeight: number,
451
318
  reference: PositionReference,
452
319
  side: PositionSide,
453
320
  align: PositionAlign,
@@ -524,7 +391,7 @@ export const getPopoverPosition = (
524
391
  * popover to be positioned on the
525
392
  * preferred side of the reference.
526
393
  */
527
- const coordinates = calculatePopoverSide(side, referenceCoordinates, contentWidth, contentHeight, arrowWidth, arrowHeight, isRTL);
394
+ const coordinates = calculatePopoverSide(side, referenceCoordinates, contentWidth, contentHeight, isRTL);
528
395
 
529
396
  /**
530
397
  * Get the top/left adjustments that
@@ -536,11 +403,9 @@ export const getPopoverPosition = (
536
403
  const top = coordinates.top + alignedCoordinates.top;
537
404
  const left = coordinates.left + alignedCoordinates.left;
538
405
 
539
- const { arrowTop, arrowLeft } = calculateArrowPosition(side, arrowWidth, arrowHeight, top, left, contentWidth, contentHeight, isRTL);
540
-
541
406
  const { originX, originY } = calculatePopoverOrigin(side, align, isRTL);
542
407
 
543
- return { top, left, referenceCoordinates, arrowTop, arrowLeft, originX, originY };
408
+ return { top, left, referenceCoordinates, originX, originY };
544
409
  };
545
410
 
546
411
  /**
@@ -589,55 +454,6 @@ const getOriginYAlignment = (align: PositionAlign) => {
589
454
  }
590
455
  };
591
456
 
592
- /**
593
- * Calculates where the arrow positioning
594
- * should be relative to the popover content.
595
- */
596
- const calculateArrowPosition = (
597
- side: PositionSide,
598
- arrowWidth: number,
599
- arrowHeight: number,
600
- top: number,
601
- left: number,
602
- contentWidth: number,
603
- contentHeight: number,
604
- isRTL: boolean,
605
- ) => {
606
- /**
607
- * Note: When side is left, right, start, or end, the arrow is
608
- * been rotated using a `transform`, so to move the arrow up or down
609
- * by its dimension, you need to use `arrowWidth`.
610
- */
611
- const leftPosition = {
612
- arrowTop: top + contentHeight / 2 - arrowWidth / 2,
613
- arrowLeft: left + contentWidth - arrowWidth / 2,
614
- };
615
-
616
- /**
617
- * Move the arrow to the left by arrowWidth and then
618
- * again by half of its width because we have rotated
619
- * the arrow using a transform.
620
- */
621
- const rightPosition = { arrowTop: top + contentHeight / 2 - arrowWidth / 2, arrowLeft: left - arrowWidth * 1.5 };
622
-
623
- switch (side) {
624
- case 'top':
625
- return { arrowTop: top + contentHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
626
- case 'bottom':
627
- return { arrowTop: top - arrowHeight, arrowLeft: left + contentWidth / 2 - arrowWidth / 2 };
628
- case 'left':
629
- return leftPosition;
630
- case 'right':
631
- return rightPosition;
632
- case 'start':
633
- return isRTL ? rightPosition : leftPosition;
634
- case 'end':
635
- return isRTL ? leftPosition : rightPosition;
636
- default:
637
- return { arrowTop: 0, arrowLeft: 0 };
638
- }
639
- };
640
-
641
457
  /**
642
458
  * Calculates the required top/left
643
459
  * values needed to position the popover
@@ -649,30 +465,28 @@ const calculatePopoverSide = (
649
465
  triggerBoundingBox: ReferenceCoordinates,
650
466
  contentWidth: number,
651
467
  contentHeight: number,
652
- arrowWidth: number,
653
- arrowHeight: number,
654
468
  isRTL: boolean,
655
469
  ) => {
656
470
  const sideLeft = {
657
471
  top: triggerBoundingBox.top,
658
- left: triggerBoundingBox.left - contentWidth - arrowWidth,
472
+ left: triggerBoundingBox.left - contentWidth,
659
473
  };
660
474
  const sideRight = {
661
475
  top: triggerBoundingBox.top,
662
- left: triggerBoundingBox.left + triggerBoundingBox.width + arrowWidth,
476
+ left: triggerBoundingBox.left + triggerBoundingBox.width,
663
477
  };
664
478
 
665
479
  switch (side) {
666
480
  case 'top':
667
481
  return {
668
- top: triggerBoundingBox.top - contentHeight - arrowHeight,
482
+ top: triggerBoundingBox.top - contentHeight,
669
483
  left: triggerBoundingBox.left,
670
484
  };
671
485
  case 'right':
672
486
  return sideRight;
673
487
  case 'bottom':
674
488
  return {
675
- top: triggerBoundingBox.top + triggerBoundingBox.height + arrowHeight,
489
+ top: triggerBoundingBox.top + triggerBoundingBox.height,
676
490
  left: triggerBoundingBox.left,
677
491
  };
678
492
  case 'left':
@@ -794,14 +608,9 @@ export const calculateWindowAdjustment = (
794
608
  contentOriginX: string,
795
609
  contentOriginY: string,
796
610
  triggerCoordinates?: ReferenceCoordinates,
797
- coordArrowTop = 0,
798
- coordArrowLeft = 0,
799
- arrowHeight = 0,
800
611
  eventElementRect?: DOMRect,
801
612
  isReplace: boolean = false,
802
613
  ): PopoverStyles => {
803
- let arrowTop = coordArrowTop;
804
- const arrowLeft = coordArrowLeft;
805
614
  const triggerTop = triggerCoordinates ? triggerCoordinates.top + triggerCoordinates.height : bodyHeight / 2 - contentHeight / 2;
806
615
  const triggerHeight = triggerCoordinates ? triggerCoordinates.height : 0;
807
616
  let left = coordLeft;
@@ -852,11 +661,10 @@ export const calculateWindowAdjustment = (
852
661
  * it is not right up against the edge of the screen.
853
662
  */
854
663
  if (!isReplace) {
855
- top = Math.max(12, triggerTop - contentHeight - triggerHeight - (arrowHeight - 1)) - POPOVER_IOS_BODY_MARGIN;
664
+ top = Math.max(12, triggerTop - contentHeight - triggerHeight) - POPOVER_IOS_BODY_MARGIN;
856
665
  } else {
857
- top = Math.max(12, triggerTop - contentHeight - (arrowHeight - 1));
666
+ top = Math.max(12, triggerTop - contentHeight);
858
667
  }
859
- arrowTop = top + contentHeight;
860
668
  originY = 'bottom';
861
669
  addPopoverBottomClass = true;
862
670
 
@@ -877,36 +685,6 @@ export const calculateWindowAdjustment = (
877
685
  originY,
878
686
  checkSafeAreaLeft,
879
687
  checkSafeAreaRight,
880
- arrowTop,
881
- arrowLeft,
882
688
  addPopoverBottomClass,
883
689
  };
884
690
  };
885
-
886
- export const shouldShowArrow = (side: PositionSide, didAdjustBounds = false, ev?: Event, trigger?: HTMLElement) => {
887
- /**
888
- * If no event provided and
889
- * we do not have a trigger,
890
- * then this popover was likely
891
- * presented via the popoverController
892
- * or users called `present` manually.
893
- * In this case, the arrow should not be
894
- * shown as we do not have a reference.
895
- */
896
- if (!ev && !trigger) {
897
- return false;
898
- }
899
-
900
- /**
901
- * If popover is on the left or the right
902
- * of a trigger, but we needed to adjust the
903
- * popover due to screen bounds, then we should
904
- * hide the arrow as it will never be pointing
905
- * at the trigger.
906
- */
907
- if (side !== 'top' && side !== 'bottom' && didAdjustBounds) {
908
- return false;
909
- }
910
-
911
- return true;
912
- };
@@ -26,6 +26,7 @@ export const registerEffect = (
26
26
  let scaleAnimationPromise: Promise<void> | undefined;
27
27
  let startAnimationPromise: Promise<void> | undefined;
28
28
  let maxVelocity = 0;
29
+ let wasRealUserClick = false;
29
30
  const effectElement = cloneElement(effectTagName);
30
31
 
31
32
  /**
@@ -38,6 +39,7 @@ export const registerEffect = (
38
39
  createAnimationGesture();
39
40
  };
40
41
  const onPointerUp = (event: PointerEvent) => {
42
+ wasRealUserClick = true;
41
43
  clearActivatedTimer = setTimeout(async () => {
42
44
  await onEndGesture();
43
45
  gesture.destroy();
@@ -68,12 +70,15 @@ export const registerEffect = (
68
70
  if (!currentTouchedElement) {
69
71
  return;
70
72
  }
71
- currentTouchedElement!.click();
73
+ if (!wasRealUserClick) {
74
+ currentTouchedElement!.click();
75
+ }
72
76
  currentTouchedElement?.classList.remove('ion-activated');
73
77
  currentTouchedElement = undefined;
74
78
  effectElement.style.display = 'none';
75
79
  maxVelocity = 0;
76
80
  targetElement.classList.remove(ANIMATED_NAME);
81
+ wasRealUserClick = false;
77
82
  };
78
83
 
79
84
  const onStartGesture = (detail: GestureDetail): boolean | undefined => {
@@ -16,6 +16,9 @@ $scaleup-large-icon-only: 1.22;
16
16
  @include api.glass-background;
17
17
  border-radius: 25px;
18
18
  overflow: hidden;
19
+ &:hover {
20
+ opacity: 0.72;
21
+ }
19
22
 
20
23
  /**
21
24
  * compare .header-collapse-main ion-toolbar.in-toolbar ion-title, .header-collapse-main ion-toolbar.in-toolbar ion-buttons
@@ -287,6 +290,9 @@ $scaleup-large-icon-only: 1.22;
287
290
  &:not(.button-disabled) {
288
291
  opacity: 1; // for ion-back-button
289
292
  }
293
+ &:hover {
294
+ opacity: 0.72;
295
+ }
290
296
  --color: rgb(var(--ion-text-color-rgb, 0, 0, 0));
291
297
  &.ion-color {
292
298
  --color: rgba(var(--ion-color-base-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 1);
@@ -1,5 +1,9 @@
1
1
  @use '../utils/api';
2
2
 
3
+ $scaleup-small-icon-only: 1.18;
4
+ $scaleup-default-icon-only: 1.2;
5
+ $scaleup-large-icon-only: 1.12;
6
+
3
7
  ion-fab.ios:not(.ios26-disabled) {
4
8
  ion-fab-button {
5
9
  --transition:
@@ -25,6 +29,22 @@ ion-fab.ios:not(.ios26-disabled) {
25
29
 
26
30
  &.ion-activated {
27
31
  --color: rgba(var(--ion-text-color-rgb, 0, 0, 0), 0.1);
32
+ &::part(native) {
33
+ transform: scale($scaleup-default-icon-only) translateZ(0);
34
+ -webkit-transform: scale($scaleup-default-icon-only) translateZ(0);
35
+ }
36
+ &.fab-button-large {
37
+ &::part(native) {
38
+ transform: scale($scaleup-large-icon-only) translateZ(0);
39
+ -webkit-transform: scale($scaleup-large-icon-only) translateZ(0);
40
+ }
41
+ }
42
+ &.fab-button-small {
43
+ &::part(native) {
44
+ transform: scale($scaleup-small-icon-only) translateZ(0);
45
+ -webkit-transform: scale($scaleup-small-icon-only) translateZ(0);
46
+ }
47
+ }
28
48
  &.ion-color {
29
49
  --color: rgba(var(--ion-color-base-rgb, var(--ion-text-color-rgb, 0, 0, 0)), 0.1);
30
50
  }
@@ -44,10 +64,20 @@ ion-fab.ios:not(.ios26-disabled) {
44
64
  }
45
65
 
46
66
  &.fab-horizontal-start {
47
- right: calc(16px + var(--ion-safe-area-left, 0px));
67
+ left: calc(16px + var(--ion-safe-area-left, 0px));
48
68
  }
49
69
 
50
70
  &.fab-horizontal-end {
51
71
  right: calc(16px + var(--ion-safe-area-right, 0px));
52
72
  }
73
+
74
+ &:has(.fab-button-small) {
75
+ &.fab-horizontal-start {
76
+ left: calc(10px + var(--ion-safe-area-left, 0px));
77
+ }
78
+
79
+ &.fab-horizontal-end {
80
+ right: calc(10px + var(--ion-safe-area-right, 0px));
81
+ }
82
+ }
53
83
  }
@@ -34,3 +34,13 @@ ion-searchbar.ios:not(.ios26-disabled) {
34
34
  }
35
35
  }
36
36
  }
37
+
38
+ /**
39
+ * This is an override for a class where cascading is specified too heavily.
40
+ */
41
+ ion-toolbar.ios:not(.ios26-disabled).ion-color.sc-ion-searchbar-ios-h:not(.ion-color) .searchbar-input.sc-ion-searchbar-ios,
42
+ ion-toolbar:not(.ios26-disabled).ion-color
43
+ :not(.ios26-disabled).sc-ion-searchbar-ios-h:not(.ion-color)
44
+ .searchbar-input.sc-ion-searchbar-ios {
45
+ background: rgba(var(--ios26-glass-background-rgb), 0.72);
46
+ }
@@ -32,6 +32,9 @@ ion-toggle.ios:not(.ios26-disabled) {
32
32
  transform: translateX(-4px) scale(1.4, 1.6) translateZ(0);
33
33
  -webkit-transform: translateX(-4px) scale(1.4, 1.6) translateZ(0);
34
34
  }
35
+ &.toggle-activated.toggle-checked::part(handle) {
36
+ transform: scale(1.4, 1.6) translateZ(0);
37
+ }
35
38
  &.toggle-activated::part(handle) {
36
39
  transform: scale(1.4, 1.6) translateZ(0);
37
40
  -webkit-transform: scale(1.4, 1.6) translateZ(0);
@@ -30,6 +30,26 @@ ion-toolbar.ios:not(.ios26-disabled).toolbar-searchbar {
30
30
  *[slot='end'] {
31
31
  align-self: center;
32
32
  }
33
+ &:has(ion-buttons[slot='start']) {
34
+ ion-buttons[slot='start'] {
35
+ margin-right: 6px;
36
+ }
37
+ ion-searchbar.ios:not(.ios26-disabled) {
38
+ .searchbar-input-container {
39
+ margin: 0 12px 0 6px;
40
+ }
41
+ }
42
+ }
43
+ &:has(ion-buttons[slot='end']) {
44
+ ion-buttons[slot='end'] {
45
+ margin-left: 6px;
46
+ }
47
+ ion-searchbar.ios:not(.ios26-disabled) {
48
+ .searchbar-input-container {
49
+ margin: 0 6px 0 12px;
50
+ }
51
+ }
52
+ }
33
53
  }
34
54
 
35
55
  ion-header.ios:not(.ios26-disabled),
File without changes