@sparklingopinions/sparkling-ui 0.4.1 → 0.4.2

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.
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.js","names":["_sfc_main","Popover_vue_vue_type_script_setup_true_lang_default","Popover_default"],"sources":["../../../src/components/Popover/Popover.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, useAttrs, watch } from 'vue'\n\nimport { PopoverAnchor, PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\n\nexport interface PopoverProps {\n /** The gap to the anchor, in px; negative overlaps it. */\n offset?: number\n /** Shifts it along the anchor's edge, in px. */\n alignOffset?: number\n closeOnEscape?: boolean\n /** The panel's width, e.g. `20rem`. */\n width?: string\n}\n\n// Root is Reka's renderless PopoverRoot: class and attributes belong on the panel.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<PopoverProps>(), {\n offset: 4,\n alignOffset: 0,\n closeOnEscape: true,\n width: '16rem'\n})\n\nconst emit = defineEmits<{ show: []; hide: [] }>()\n\nconst attrs = useAttrs()\n\nconst open = ref(false)\nconst anchor = ref<HTMLElement>()\n// What was clicked to open it; clicks on it toggle the popover rather than counting as outside.\nconst opener = ref<HTMLElement>()\nconst label = ref<string>()\n// A press outside closes it and leaves focus to what was pressed.\nlet pressedOutside = false\n\n/** Opens below the event's element, or below `target` when given. */\nfunction show(event: Event, target?: HTMLElement) {\n opener.value = event.currentTarget as HTMLElement\n anchor.value = target ?? opener.value\n // A dialog needs a name: an aria-label given to the popover, or else the name of the element it opened from.\n label.value =\n (attrs['aria-label'] as string | undefined) ??\n opener.value?.getAttribute('aria-label') ??\n opener.value?.textContent?.trim()\n pressedOutside = false\n open.value = true\n}\n\nfunction hide() {\n open.value = false\n}\n\nfunction toggle(event: Event, target?: HTMLElement) {\n if (open.value) hide()\n else show(event, target)\n}\n\ndefineExpose({ show, hide, toggle })\n\nfunction isOnAnchor(target: EventTarget | null) {\n return target instanceof Node && [anchor.value, opener.value].some((el) => el?.contains(target))\n}\n\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n if (isOnAnchor(event.detail.originalEvent.target)) event.preventDefault()\n else pressedOutside = true\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (!props.closeOnEscape) event.preventDefault()\n}\n\n// Otherwise focus left in the panel goes back to the anchor.\nfunction onCloseAutoFocus(event: Event) {\n event.preventDefault()\n const active = document.activeElement\n const inPanel = !active || active === document.body || (event.target as HTMLElement).contains(active)\n if (inPanel && !pressedOutside) anchor.value?.focus()\n}\n\n// Focus goes to an [autofocus] element inside, or else the panel, so Tab moves through it and Escape works at once.\n// The event comes from Reka's positioning wrapper around the panel.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n const wrapper = event.target as HTMLElement | null\n const panel = wrapper?.querySelector<HTMLElement>('[role=\"dialog\"]')\n ;(panel?.querySelector<HTMLElement>('[autofocus]') ?? panel)?.focus()\n}\n\n// It closes when the page moves under it: a scrolling ancestor of the anchor, or a resized window.\nfunction onScroll(event: Event) {\n if (event.target instanceof Node && event.target.contains(anchor.value ?? null)) hide()\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n window.addEventListener('scroll', onScroll, true)\n window.addEventListener('resize', hide)\n emit('show')\n } else {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n emit('hide')\n }\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n})\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor :reference=\"anchor\" />\n <PopoverPortal>\n <PopoverContent\n v-bind=\"$attrs\"\n align=\"start\"\n :align-offset=\"alignOffset\"\n :aria-label=\"label\"\n class=\"z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in\"\n :collision-padding=\"8\"\n side=\"bottom\"\n :side-offset=\"offset\"\n :style=\"{ width }\"\n @close-auto-focus=\"onCloseAutoFocus\"\n @escape-key-down=\"onEscape\"\n @focus-outside.prevent\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <slot :hide=\"hide\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
1
+ {"version":3,"file":"Popover.js","names":["_sfc_main","Popover_vue_vue_type_script_setup_true_lang_default","Popover_default"],"sources":["../../../src/components/Popover/Popover.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, useAttrs, watch } from 'vue'\n\nimport { PopoverAnchor, PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\n\nexport interface PopoverProps {\n /** The gap to the anchor, in px; negative overlaps it. */\n offset?: number\n /** Shifts it along the anchor's edge, in px. */\n alignOffset?: number\n closeOnEscape?: boolean\n /** The panel's width, e.g. `20rem`. */\n width?: string\n}\n\n// Root is Reka's renderless PopoverRoot: class and attributes belong on the panel.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<PopoverProps>(), {\n offset: 4,\n alignOffset: 0,\n closeOnEscape: true,\n width: '16rem'\n})\n\nconst emit = defineEmits<{ show: []; hide: [] }>()\n\nconst attrs = useAttrs()\n\nconst open = ref(false)\nconst anchor = ref<HTMLElement>()\n// What was clicked to open it; clicks on it toggle the popover rather than counting as outside.\nconst opener = ref<HTMLElement>()\nconst label = ref<string>()\n// A press outside closes it and leaves focus to what was pressed.\nlet pressedOutside = false\n\n/** Opens below the event's element, or below `target` when given. */\nfunction show(event: Event, target?: HTMLElement) {\n opener.value = event.currentTarget as HTMLElement\n anchor.value = target ?? opener.value\n // A dialog needs a name: an aria-label given to the popover, or else the name of the element it opened from.\n label.value =\n (attrs['aria-label'] as string | undefined) ??\n opener.value?.getAttribute('aria-label') ??\n opener.value?.textContent?.trim()\n pressedOutside = false\n open.value = true\n}\n\nfunction hide() {\n open.value = false\n}\n\nfunction toggle(event: Event, target?: HTMLElement) {\n if (open.value) hide()\n else show(event, target)\n}\n\ndefineExpose({ show, hide, toggle })\n\nfunction isOnAnchor(target: EventTarget | null) {\n return target instanceof Node && [anchor.value, opener.value].some((el) => el?.contains(target))\n}\n\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n if (isOnAnchor(event.detail.originalEvent.target)) event.preventDefault()\n else pressedOutside = true\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (!props.closeOnEscape) event.preventDefault()\n}\n\n// Otherwise focus left in the panel goes back to the anchor.\nfunction onCloseAutoFocus(event: Event) {\n event.preventDefault()\n const active = document.activeElement\n const inPanel = !active || active === document.body || (event.target as HTMLElement).contains(active)\n if (inPanel && !pressedOutside) anchor.value?.focus()\n}\n\n// Focus goes to an [autofocus] element inside, or else the panel, so Tab moves through it and Escape works at once.\n// The event comes from Reka's positioning wrapper around the panel.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n const wrapper = event.target as HTMLElement | null\n const panel = wrapper?.querySelector<HTMLElement>('[role=\"dialog\"]')\n ;(panel?.querySelector<HTMLElement>('[autofocus]') ?? panel)?.focus()\n}\n\n// It closes when the page moves under it: a scrolling ancestor of the anchor, or a resized window.\nfunction onScroll(event: Event) {\n if (event.target instanceof Node && event.target.contains(anchor.value ?? null)) hide()\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n window.addEventListener('scroll', onScroll, true)\n window.addEventListener('resize', hide)\n emit('show')\n } else {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n emit('hide')\n }\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n})\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor :reference=\"anchor\" />\n <PopoverPortal>\n <PopoverContent\n v-bind=\"$attrs\"\n align=\"start\"\n :align-offset=\"alignOffset\"\n :aria-label=\"label\"\n class=\"z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg outline-hidden border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in\"\n :collision-padding=\"8\"\n side=\"bottom\"\n :side-offset=\"offset\"\n :style=\"{ width }\"\n @close-auto-focus=\"onCloseAutoFocus\"\n @escape-key-down=\"onEscape\"\n @focus-outside.prevent\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <slot :hide=\"hide\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":""}
@@ -65,7 +65,7 @@ var _ = /*@__PURE__*/ n({
65
65
  align: "start",
66
66
  "align-offset": n.alignOffset,
67
67
  "aria-label": T.value,
68
- class: "z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in",
68
+ class: "z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg outline-hidden border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in",
69
69
  "collision-padding": 8,
70
70
  side: "bottom",
71
71
  "side-offset": n.offset,
@@ -1 +1 @@
1
- {"version":3,"file":"Popover.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_mergeProps","_withModifiers","_renderSlot","Popover_vue_vue_type_script_setup_true_lang_default","__expose","__emit","props","__props","emit","attrs","useAttrs","open","ref","anchor","opener","label","pressedOutside","show","event","target","hide","toggle","isOnAnchor","el","onPointerDownOutside","onEscape","onCloseAutoFocus","active","onOpenAutoFocus","panel","onScroll","watch","isOpen","onBeforeUnmount","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","createVNode","PopoverAnchor","PopoverPortal","PopoverContent","mergeProps","_ctx","withModifiers","renderSlot"],"sources":["../../../src/components/Popover/Popover.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, useAttrs, watch } from 'vue'\n\nimport { PopoverAnchor, PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\n\nexport interface PopoverProps {\n /** The gap to the anchor, in px; negative overlaps it. */\n offset?: number\n /** Shifts it along the anchor's edge, in px. */\n alignOffset?: number\n closeOnEscape?: boolean\n /** The panel's width, e.g. `20rem`. */\n width?: string\n}\n\n// Root is Reka's renderless PopoverRoot: class and attributes belong on the panel.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<PopoverProps>(), {\n offset: 4,\n alignOffset: 0,\n closeOnEscape: true,\n width: '16rem'\n})\n\nconst emit = defineEmits<{ show: []; hide: [] }>()\n\nconst attrs = useAttrs()\n\nconst open = ref(false)\nconst anchor = ref<HTMLElement>()\n// What was clicked to open it; clicks on it toggle the popover rather than counting as outside.\nconst opener = ref<HTMLElement>()\nconst label = ref<string>()\n// A press outside closes it and leaves focus to what was pressed.\nlet pressedOutside = false\n\n/** Opens below the event's element, or below `target` when given. */\nfunction show(event: Event, target?: HTMLElement) {\n opener.value = event.currentTarget as HTMLElement\n anchor.value = target ?? opener.value\n // A dialog needs a name: an aria-label given to the popover, or else the name of the element it opened from.\n label.value =\n (attrs['aria-label'] as string | undefined) ??\n opener.value?.getAttribute('aria-label') ??\n opener.value?.textContent?.trim()\n pressedOutside = false\n open.value = true\n}\n\nfunction hide() {\n open.value = false\n}\n\nfunction toggle(event: Event, target?: HTMLElement) {\n if (open.value) hide()\n else show(event, target)\n}\n\ndefineExpose({ show, hide, toggle })\n\nfunction isOnAnchor(target: EventTarget | null) {\n return target instanceof Node && [anchor.value, opener.value].some((el) => el?.contains(target))\n}\n\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n if (isOnAnchor(event.detail.originalEvent.target)) event.preventDefault()\n else pressedOutside = true\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (!props.closeOnEscape) event.preventDefault()\n}\n\n// Otherwise focus left in the panel goes back to the anchor.\nfunction onCloseAutoFocus(event: Event) {\n event.preventDefault()\n const active = document.activeElement\n const inPanel = !active || active === document.body || (event.target as HTMLElement).contains(active)\n if (inPanel && !pressedOutside) anchor.value?.focus()\n}\n\n// Focus goes to an [autofocus] element inside, or else the panel, so Tab moves through it and Escape works at once.\n// The event comes from Reka's positioning wrapper around the panel.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n const wrapper = event.target as HTMLElement | null\n const panel = wrapper?.querySelector<HTMLElement>('[role=\"dialog\"]')\n ;(panel?.querySelector<HTMLElement>('[autofocus]') ?? panel)?.focus()\n}\n\n// It closes when the page moves under it: a scrolling ancestor of the anchor, or a resized window.\nfunction onScroll(event: Event) {\n if (event.target instanceof Node && event.target.contains(anchor.value ?? null)) hide()\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n window.addEventListener('scroll', onScroll, true)\n window.addEventListener('resize', hide)\n emit('show')\n } else {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n emit('hide')\n }\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n})\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor :reference=\"anchor\" />\n <PopoverPortal>\n <PopoverContent\n v-bind=\"$attrs\"\n align=\"start\"\n :align-offset=\"alignOffset\"\n :aria-label=\"label\"\n class=\"z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in\"\n :collision-padding=\"8\"\n side=\"bottom\"\n :side-offset=\"offset\"\n :style=\"{ width }\"\n @close-auto-focus=\"onCloseAutoFocus\"\n @escape-key-down=\"onEscape\"\n @focus-outside.prevent\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <slot :hide=\"hide\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
1
+ {"version":3,"file":"Popover.vue_vue_type_script_setup_true_lang.js","names":["$attrs","_openBlock","_createBlock","_unref","_withCtx","_createVNode","_mergeProps","_withModifiers","_renderSlot","Popover_vue_vue_type_script_setup_true_lang_default","__expose","__emit","props","__props","emit","attrs","useAttrs","open","ref","anchor","opener","label","pressedOutside","show","event","target","hide","toggle","isOnAnchor","el","onPointerDownOutside","onEscape","onCloseAutoFocus","active","onOpenAutoFocus","panel","onScroll","watch","isOpen","onBeforeUnmount","openBlock","createBlock","unref","PopoverRoot","_cache","$event","withCtx","createVNode","PopoverAnchor","PopoverPortal","PopoverContent","mergeProps","_ctx","withModifiers","renderSlot"],"sources":["../../../src/components/Popover/Popover.vue"],"sourcesContent":["<script setup lang=\"ts\">\nimport { onBeforeUnmount, ref, useAttrs, watch } from 'vue'\n\nimport { PopoverAnchor, PopoverContent, PopoverPortal, PopoverRoot } from 'reka-ui'\n\nexport interface PopoverProps {\n /** The gap to the anchor, in px; negative overlaps it. */\n offset?: number\n /** Shifts it along the anchor's edge, in px. */\n alignOffset?: number\n closeOnEscape?: boolean\n /** The panel's width, e.g. `20rem`. */\n width?: string\n}\n\n// Root is Reka's renderless PopoverRoot: class and attributes belong on the panel.\ndefineOptions({ inheritAttrs: false })\n\nconst props = withDefaults(defineProps<PopoverProps>(), {\n offset: 4,\n alignOffset: 0,\n closeOnEscape: true,\n width: '16rem'\n})\n\nconst emit = defineEmits<{ show: []; hide: [] }>()\n\nconst attrs = useAttrs()\n\nconst open = ref(false)\nconst anchor = ref<HTMLElement>()\n// What was clicked to open it; clicks on it toggle the popover rather than counting as outside.\nconst opener = ref<HTMLElement>()\nconst label = ref<string>()\n// A press outside closes it and leaves focus to what was pressed.\nlet pressedOutside = false\n\n/** Opens below the event's element, or below `target` when given. */\nfunction show(event: Event, target?: HTMLElement) {\n opener.value = event.currentTarget as HTMLElement\n anchor.value = target ?? opener.value\n // A dialog needs a name: an aria-label given to the popover, or else the name of the element it opened from.\n label.value =\n (attrs['aria-label'] as string | undefined) ??\n opener.value?.getAttribute('aria-label') ??\n opener.value?.textContent?.trim()\n pressedOutside = false\n open.value = true\n}\n\nfunction hide() {\n open.value = false\n}\n\nfunction toggle(event: Event, target?: HTMLElement) {\n if (open.value) hide()\n else show(event, target)\n}\n\ndefineExpose({ show, hide, toggle })\n\nfunction isOnAnchor(target: EventTarget | null) {\n return target instanceof Node && [anchor.value, opener.value].some((el) => el?.contains(target))\n}\n\nfunction onPointerDownOutside(event: CustomEvent<{ originalEvent: PointerEvent }>) {\n if (isOnAnchor(event.detail.originalEvent.target)) event.preventDefault()\n else pressedOutside = true\n}\n\nfunction onEscape(event: KeyboardEvent) {\n if (!props.closeOnEscape) event.preventDefault()\n}\n\n// Otherwise focus left in the panel goes back to the anchor.\nfunction onCloseAutoFocus(event: Event) {\n event.preventDefault()\n const active = document.activeElement\n const inPanel = !active || active === document.body || (event.target as HTMLElement).contains(active)\n if (inPanel && !pressedOutside) anchor.value?.focus()\n}\n\n// Focus goes to an [autofocus] element inside, or else the panel, so Tab moves through it and Escape works at once.\n// The event comes from Reka's positioning wrapper around the panel.\nfunction onOpenAutoFocus(event: Event) {\n event.preventDefault()\n const wrapper = event.target as HTMLElement | null\n const panel = wrapper?.querySelector<HTMLElement>('[role=\"dialog\"]')\n ;(panel?.querySelector<HTMLElement>('[autofocus]') ?? panel)?.focus()\n}\n\n// It closes when the page moves under it: a scrolling ancestor of the anchor, or a resized window.\nfunction onScroll(event: Event) {\n if (event.target instanceof Node && event.target.contains(anchor.value ?? null)) hide()\n}\n\nwatch(open, (isOpen) => {\n if (isOpen) {\n window.addEventListener('scroll', onScroll, true)\n window.addEventListener('resize', hide)\n emit('show')\n } else {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n emit('hide')\n }\n})\n\nonBeforeUnmount(() => {\n window.removeEventListener('scroll', onScroll, true)\n window.removeEventListener('resize', hide)\n})\n</script>\n\n<template>\n <PopoverRoot v-model:open=\"open\">\n <PopoverAnchor :reference=\"anchor\" />\n <PopoverPortal>\n <PopoverContent\n v-bind=\"$attrs\"\n align=\"start\"\n :align-offset=\"alignOffset\"\n :aria-label=\"label\"\n class=\"z-[1100] block max-h-(--reka-popover-content-available-height) origin-center overflow-y-auto rounded-lg outline-hidden border border-sui-line-subtle bg-sui-surface text-sui-ink shadow-xl data-[state=closed]:animate-sui-overlay-out data-[state=open]:animate-sui-overlay-in\"\n :collision-padding=\"8\"\n side=\"bottom\"\n :side-offset=\"offset\"\n :style=\"{ width }\"\n @close-auto-focus=\"onCloseAutoFocus\"\n @escape-key-down=\"onEscape\"\n @focus-outside.prevent\n @open-auto-focus=\"onOpenAutoFocus\"\n @pointer-down-outside=\"onPointerDownOutside\"\n >\n <slot :hide=\"hide\" />\n </PopoverContent>\n </PopoverPortal>\n </PopoverRoot>\n</template>\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sparklingopinions/sparkling-ui",
3
- "version": "0.4.1",
3
+ "version": "0.4.2",
4
4
  "description": "A product-agnostic Vue 3 component library, themed by semantic tokens",
5
5
  "type": "module",
6
6
  "license": "MIT",