From 11484191528a411ff6224f4a0ea70749748af031 Mon Sep 17 00:00:00 2001 From: haild173094 Date: Tue, 10 Sep 2024 17:47:01 +0700 Subject: [PATCH 1/6] Update: polaris token --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index 7288ae2a..e764c132 100644 --- a/package.json +++ b/package.json @@ -50,7 +50,7 @@ }, "devDependencies": { "@csstools/postcss-global-data": "^2.1.1", - "@shopify/polaris-tokens": "^9.1.0", + "@shopify/polaris-tokens": "9.4.0", "@shopify/postcss-plugin": "^5.0.2", "@types/node": "^20.10.4", "@vitejs/plugin-vue": "^5.0.5", diff --git a/yarn.lock b/yarn.lock index baa3912a..a7c3765e 100644 --- a/yarn.lock +++ b/yarn.lock @@ -619,10 +619,10 @@ resolved "https://registry.yarnpkg.com/@shopify/polaris-icons/-/polaris-icons-9.2.0.tgz#63d56d7aee800ab86336afc43eb883fcf52dd5a4" integrity sha512-5j+v9LHdmPQWwrtrxgIZq0GzG93a/+ixvQrQwtUP3vlXcJ8xbYvPoY2/waqrtDFij9qw6SuzkBpB4nSM632MRQ== -"@shopify/polaris-tokens@^9.1.0": - version "9.1.0" - resolved "https://registry.yarnpkg.com/@shopify/polaris-tokens/-/polaris-tokens-9.1.0.tgz#128ba661e890bf25fd55d68fec00a0bc7569d7e7" - integrity sha512-nIsOJYNENqfGC/O1Rjo+w4rytLa+9Cp841KTbq/lDwCsBKXBLf+RUOeXTvO070j8Qnc5PJ5ZvRs9EWU7XsQFDA== +"@shopify/polaris-tokens@9.4.0": + version "9.4.0" + resolved "https://registry.yarnpkg.com/@shopify/polaris-tokens/-/polaris-tokens-9.4.0.tgz#acf11a4fbc4b50cc1725c23dfff99d1de20f67e7" + integrity sha512-jnCNxq9+XfWP9ijkvSsgQH5o3PeYgfWo4/zymoO+AeJvyngL+4LvlZ/nofvYj9DXLo74taTk05xui9qt22Zy2Q== dependencies: deepmerge "^4.3.1" From 262299f6fec6578c18297bee344ca6ca082f5fa9 Mon Sep 17 00:00:00 2001 From: haild173094 Date: Tue, 10 Sep 2024 17:47:34 +0700 Subject: [PATCH 2/6] Update: Color Picker + Event Listener + DropZone --- src/components/ColorPicker/ColorPicker.vue | 15 +++++---- .../components/AlphaPicker/AlphaPicker.vue | 13 +++++++- .../components/HuePicker/HuePicker.vue | 17 +++++++++- .../components/Slidable/Slidable.vue | 32 +++++++++++++++++-- src/components/DropZone/DropZone.vue | 21 ++++++++++-- .../EventListener/EventListener.vue | 5 +++ 6 files changed, 90 insertions(+), 13 deletions(-) diff --git a/src/components/ColorPicker/ColorPicker.vue b/src/components/ColorPicker/ColorPicker.vue index da5b7086..2524242b 100644 --- a/src/components/ColorPicker/ColorPicker.vue +++ b/src/components/ColorPicker/ColorPicker.vue @@ -25,14 +25,10 @@ div( :color="colorHsb", @change="handleAlphaChange", ) - EventListener( - event="resize", - :handler="handleResize", - ) diff --git a/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue b/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue index 90f132aa..928d3dbd 100644 --- a/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue +++ b/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue @@ -17,9 +17,9 @@ PositionedOverlay( v-bind="overlay.props", :class="popoverOverlayClass", ) - EventListener(event="click", :handler="handleClick") - EventListener(event="touchstart", :handler="handleClick") - KeypressListener(:key-code="Key.Escape", :handler="handleEscape") + EventListener(event="click", :handler="handleClick", :custom-window="window") + EventListener(event="touchstart", :handler="handleClick", :custom-window="window") + KeypressListener(:key-code="Key.Escape", :handler="handleEscape", :custom-window="window") div( tabindex="0", :class="styles.FocusTracker", @@ -114,6 +114,8 @@ const state = reactive({ const contentNode = ref(null); const enteringTimer = ref(undefined); const overlayRef = ref | null>(null); +const observer = ref(null); +const window = ref(globalThis.window); const overlayDetails = computed(() => (overlayRef.value as InstanceType)?.overlayDetails); @@ -172,7 +174,7 @@ watch( changeTransitionStatus(TransitionStatus.Entering, () => { clearTransitionTimeout(); - enteringTimer.value = window.setTimeout(() => { + enteringTimer.value = window.value.setTimeout(() => { state.transitionStatus = TransitionStatus.Entered; // Important: This will not update when the active theme changes. // Update this to `useTheme` once converted to a function component. @@ -188,16 +190,38 @@ watch( } ); +watch( + () => props.activator, + (newVal, oldVal) => { + if (newVal !== oldVal) { + observer.value?.unobserve(oldVal); + observer.value?.observe(newVal); + } + } +); + onMounted(() => { if (props.active) { focusContent(); changeTransitionStatus(TransitionStatus.Entered); } + + if (!props.activator) return; + + observer.value = new ResizeObserver(() => { + window.value = props.activator.ownerDocument.defaultView!; + }); + + console.log(2, props.activator); + + observer.value.observe(props.activator); }); onBeforeUnmount(() => { clearTransitionTimeout(); + + observer.value?.disconnect(); }); const changeTransitionStatus = (transitionStatus: TransitionStatus, callback?: () => void) => { @@ -210,7 +234,7 @@ const changeTransitionStatus = (transitionStatus: TransitionStatus, callback?: ( function clearTransitionTimeout() { if (enteringTimer.value) { - window.clearTimeout(enteringTimer.value); + window.value.clearTimeout(enteringTimer.value); } } diff --git a/src/components/PositionedOverlay/PositionedOverlay.vue b/src/components/PositionedOverlay/PositionedOverlay.vue index 203b69e5..d1419aaf 100644 --- a/src/components/PositionedOverlay/PositionedOverlay.vue +++ b/src/components/PositionedOverlay/PositionedOverlay.vue @@ -7,6 +7,7 @@ div( EventListener( event="resize", :handler="handleMeasurement", + :custom-window="overlay?.ownerDocument.defaultView", ) slot @@ -234,10 +235,14 @@ function handleMeasurement() { preferInputActivator = true, } = props; + const document = activator.ownerDocument; + const preferredActivator = preferInputActivator ? activator.querySelector('input') || activator : activator; + console.log({ preferredActivator }); + const activatorRect = getRectForNode(preferredActivator); const currentOverlayRect = getRectForNode(overlay.value); @@ -273,11 +278,17 @@ function handleMeasurement() { * Note: * - With original version if overlay.value.firstElementChild is available and overlay.value.firstChild is not then there will be small padding below popover */ - const overlayMargins = overlay.value.firstElementChild - ? getMarginsForNode(overlay.value.firstElementChild as HTMLElement) - : { activator: 0, container: 0, horizontal: 0 }; + let overlayMargins = {activator: 0, container: 0, horizontal: 0}; + + if (overlay.value.firstElementChild) { + const nodeMargins = getMarginsForNode( + overlay.value.firstElementChild as HTMLElement, + ); + + overlayMargins = nodeMargins; + } - const containerRect = windowRect(); + const containerRect = windowRect(props.activator); const zIndexForLayer = getZIndexForLayerFromNode(activator); const zIndex = zIndexForLayer == null ? zIndexForLayer : zIndexForLayer + 1; const verticalPosition = calculateVerticalPosition( @@ -310,7 +321,7 @@ function handleMeasurement() { state.height = verticalPosition.height || 0; state.width = fullWidth || preferredPosition === 'cover' ? overlayRect.width : null; state.positioning = verticalPosition.positioning as Positioning; - state.outsideScrollableContainer = rectIsOutsideOfRect(activatorRect, intersectionWithViewport(scrollableContainerRect)); + state.outsideScrollableContainer = rectIsOutsideOfRect(activatorRect, intersectionWithViewport(scrollableContainerRect, containerRect)); state.zIndex = zIndex; state.chevronOffset = tmpChevronOffset; diff --git a/src/components/PositionedOverlay/utilities/math.ts b/src/components/PositionedOverlay/utilities/math.ts index 0fadf145..83be1a5d 100644 --- a/src/components/PositionedOverlay/utilities/math.ts +++ b/src/components/PositionedOverlay/utilities/math.ts @@ -21,6 +21,7 @@ export function calculateVerticalPosition( topBarOffset = 0, ) { const activatorTop = activatorRect.top; + console.log({ containerRect }); const activatorBottom = activatorTop + activatorRect.height; const spaceAbove = activatorRect.top - topBarOffset; const spaceBelow = @@ -172,7 +173,10 @@ export function intersectionWithViewport( }); } -export function windowRect() { +export function windowRect(node?: HTMLElement) { + const document = node?.ownerDocument || globalThis.document; + const window = document.defaultView || globalThis.window; + return new Rect({ top: window.scrollY, left: window.scrollX, diff --git a/src/components/PositionedOverlay/utilities/node.ts b/src/components/PositionedOverlay/utilities/node.ts index 57c4ce5f..055850d1 100644 --- a/src/components/PositionedOverlay/utilities/node.ts +++ b/src/components/PositionedOverlay/utilities/node.ts @@ -1,6 +1,7 @@ import { layer } from '@polaris/components/shared'; export const getMarginsForNode = (node: HTMLElement) => { + const window = node.ownerDocument.defaultView || globalThis.window; const nodeStyles = window.getComputedStyle(node); return { @@ -11,12 +12,12 @@ export const getMarginsForNode = (node: HTMLElement) => { } export const getZIndexForLayerFromNode = (node: HTMLElement) => { - const layerNode = node.closest(layer.selector) || document.body; - const zIndex = layerNode === document.body ? 'auto' : parseInt(window.getComputedStyle(layerNode).zIndex || '0', 10); + const layerNode = node.closest(layer.selector) || node?.ownerDocument.body; + const zIndex = layerNode === node?.ownerDocument.body ? 'auto' : parseInt(window.getComputedStyle(layerNode).zIndex || '0', 10); return zIndex === 'auto' || isNaN(zIndex) ? null : zIndex; } export const isDocument = (node: HTMLElement | Document): node is Document => { - return node === document; + return node.ownerDocument === null; } diff --git a/src/components/Tabs/components/Item/Item.vue b/src/components/Tabs/components/Item/Item.vue index 7a95ad9d..14c5932b 100644 --- a/src/components/Tabs/components/Item/Item.vue +++ b/src/components/Tabs/components/Item/Item.vue @@ -49,12 +49,12 @@ const focusedNode = ref(null); watch( () => props.focused, () => { - if ( - focusedNode.value && - focusedNode.value instanceof HTMLElement && - props.focused - ) { - focusedNode.value.focus(); + const focusTarget = focusedNode.value; + + if (focusTarget && focusTarget instanceof HTMLElement && props.focused) { + requestAnimationFrame(() => { + focusTarget.focus(); + }); } }, ); diff --git a/src/components/Tooltip/Tooltip.vue b/src/components/Tooltip/Tooltip.vue index 6d934196..6099a8f4 100644 --- a/src/components/Tooltip/Tooltip.vue +++ b/src/components/Tooltip/Tooltip.vue @@ -179,8 +179,9 @@ function setActivator(node: HTMLElement | null) { return; } - node.firstElementChild instanceof HTMLElement && (activatorNode.value = node.firstElementChild); - + if (node.firstElementChild) { + activatorNode.value = node.firstElementChild as HTMLElement; + } activatorContainerRef.current = node; } diff --git a/src/utilities/geometry.ts b/src/utilities/geometry.ts index 81ce8a57..22cfa200 100644 --- a/src/utilities/geometry.ts +++ b/src/utilities/geometry.ts @@ -39,19 +39,25 @@ export class Rect { export function getRectForNode( node: Element | Component | Window | Document, ): Rect { - if (!(node instanceof Element)) { + /** + * NOTE: We cannot do node instanceof Element because it will fail when inside of an iframe. + * Technically we can do `node instanceof node.ownerDocument.defaultView.Element`but this will + * fail when node isn't an Element. We might as well try to run `getBoundingClientRect` and then + * have a fallback for when that breaks. + */ + try { + const rect = (node as Element).getBoundingClientRect(); + + return new Rect({ + top: rect.top, + left: rect.left, + width: rect.width, + height: rect.height, + }); + } catch (_) { return new Rect({ width: window.innerWidth, height: window.innerHeight, }); } - - const rect = node.getBoundingClientRect(); - - return new Rect({ - top: rect.top, - left: rect.left, - width: rect.width, - height: rect.height, - }); } From 1c088061e837cb2492d1c72cdbdeda88bf80b408 Mon Sep 17 00:00:00 2001 From: haild173094 Date: Thu, 12 Sep 2024 16:34:05 +0700 Subject: [PATCH 5/6] Update: polaris icons version --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index e764c132..9d4482b6 100644 --- a/package.json +++ b/package.json @@ -45,7 +45,7 @@ "docs:assets": "cp -r docs/assets/** docs/dist/assets" }, "dependencies": { - "@shopify/polaris-icons": "^9.1.1", + "@shopify/polaris-icons": "9.3.0", "vite-svg-loader": "^5.1.0" }, "devDependencies": { diff --git a/yarn.lock b/yarn.lock index a7c3765e..cd3f1524 100644 --- a/yarn.lock +++ b/yarn.lock @@ -614,10 +614,10 @@ dependencies: shiki "1.9.0" -"@shopify/polaris-icons@^9.1.1": - version "9.2.0" - resolved "https://registry.yarnpkg.com/@shopify/polaris-icons/-/polaris-icons-9.2.0.tgz#63d56d7aee800ab86336afc43eb883fcf52dd5a4" - integrity sha512-5j+v9LHdmPQWwrtrxgIZq0GzG93a/+ixvQrQwtUP3vlXcJ8xbYvPoY2/waqrtDFij9qw6SuzkBpB4nSM632MRQ== +"@shopify/polaris-icons@^9.3.0": + version "9.3.0" + resolved "https://registry.yarnpkg.com/@shopify/polaris-icons/-/polaris-icons-9.3.0.tgz#560e268244904cafd4ad6e1547a8d57d7a9be5b4" + integrity sha512-fnH5Lcd3WFZNjlxGYGNtnjeq3P2xonRV8vChW4PqBfxdKlY/GQ/3/rIuxHzIgmLL0zukeZUaqERUN0lwSU+Xmg== "@shopify/polaris-tokens@9.4.0": version "9.4.0" From ac9f59ab614767969e702cde25e6dc38aca49451 Mon Sep 17 00:00:00 2001 From: haild173094 Date: Fri, 20 Sep 2024 10:11:04 +0700 Subject: [PATCH 6/6] Remove: console.log --- .../Popover/components/PopoverOverlay/PopoverOverlay.vue | 2 -- src/components/PositionedOverlay/PositionedOverlay.vue | 2 -- src/components/PositionedOverlay/utilities/math.ts | 1 - 3 files changed, 5 deletions(-) diff --git a/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue b/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue index 928d3dbd..b945c972 100644 --- a/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue +++ b/src/components/Popover/components/PopoverOverlay/PopoverOverlay.vue @@ -213,8 +213,6 @@ onMounted(() => { window.value = props.activator.ownerDocument.defaultView!; }); - console.log(2, props.activator); - observer.value.observe(props.activator); }); diff --git a/src/components/PositionedOverlay/PositionedOverlay.vue b/src/components/PositionedOverlay/PositionedOverlay.vue index d1419aaf..1008790a 100644 --- a/src/components/PositionedOverlay/PositionedOverlay.vue +++ b/src/components/PositionedOverlay/PositionedOverlay.vue @@ -241,8 +241,6 @@ function handleMeasurement() { ? activator.querySelector('input') || activator : activator; - console.log({ preferredActivator }); - const activatorRect = getRectForNode(preferredActivator); const currentOverlayRect = getRectForNode(overlay.value); diff --git a/src/components/PositionedOverlay/utilities/math.ts b/src/components/PositionedOverlay/utilities/math.ts index 83be1a5d..bf2f0988 100644 --- a/src/components/PositionedOverlay/utilities/math.ts +++ b/src/components/PositionedOverlay/utilities/math.ts @@ -21,7 +21,6 @@ export function calculateVerticalPosition( topBarOffset = 0, ) { const activatorTop = activatorRect.top; - console.log({ containerRect }); const activatorBottom = activatorTop + activatorRect.height; const spaceAbove = activatorRect.top - topBarOffset; const spaceBelow =