8000 fix(useCssVar): new Behavior by ilyaliao · Pull Request #4500 · vueuse/vueuse · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

fix(useCssVar): new Behavior #4500

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Feb 12, 2025
Merged

fix(useCssVar): new Behavior #4500

merged 11 commits into from
Feb 12, 2025

Conversation

ilyaliao
Copy link
Member
@ilyaliao ilyaliao commented Jan 16, 2025

resolves #4493

Before submitting the PR, please make sure you do the following

  • Read the Contributing Guidelines.
  • Read the Pull Request Guidelines.
  • Check that there isn't already a PR that solves the problem the same way to avoid creating a duplicate.
  • Provide a description in this PR that addresses what the PR is solving, or reference the issue that it solves (e.g. fixes #123).
  • Ideally, include relevant tests that fail without this PR but pass with it.
⚠️ Slowing down new functions

Warning: Slowing down new functions

As the VueUse audience continues to grow, we have been inundated with an overwhelming number of feature requests and pull requests. As a result, maintaining the project has become increasingly challenging and has stretched our capacity to its limits. As such, in the near future, we may need to slow down our acceptance of new features and prioritize the stability and quality of existing functions. Please note that new features for VueUse may not be accepted at this time. If you have any new ideas, we suggest that you first incorporate them into your own codebase, iterate on them to suit your needs, and assess their generalizability. If you strongly believe that your ideas are beneficial to the community, you may submit a pull request along with your use cases, and we would be happy to review and discuss them. Thank you for your understanding.


Description

This PR enhances several behaviors:

  • Automatically adds variable to window.document.documentElement or the target on first use, and also when the target element changes.
  • Allows users to change the color again in onMounted when setting initialValue.
  • Adds some new tests to ensure that both the state and the element are indeed changed.

@dosubot dosubot bot added the size:XS This PR changes 0-9 lines, ignoring generated files. label Jan 16, 2025
@dosubot dosubot bot added size:M This PR changes 30-99 lines, ignoring generated files. and removed size:XS This PR changes 0-9 lines, ignoring generated files. labels Jan 16, 2025
@ilyaliao
Copy link
Member Author
ilyaliao commented Jan 16, 2025

Should this work? If so, then this is a new bug.

<script setup lang="ts">
import { useCssVar } from '@vueuse/core'
import { ref } from 'vue'

const el = ref(null)
const color = useCssVar('--color', window.document.documentElement, { initialValue: '#df8543' })

function switchColor() {
  if (color.value === '#df8543')
    color.value = '#7fa998'
  else
    color.value = '#df8543'
}
</script>

<template>
  <div ref="el" style="color: var(--color)">
    Sample text, {{ color }}
  </div>
  <button @click="switchColor">
    Change Color
  </button>
</template>

@OrbisK
Copy link
Collaborator
OrbisK commented Jan 16, 2025

Should this work? If so, then this is a new bug.

Do you mean the color switch?

@YiMo1
Copy link
YiMo1 commented Jan 17, 2025

但是依旧没有解决initialValue的问题。

However, the issue of initialValue has not been resolved yet.

#4493 (comment)

@ilyaliao
Copy link
Member Author

Should this work? If so, then this is a new bug.

Do you mean the color switch?

When I load the page, the color state changes to #df8543, but the actual element color doesn't change until the next update. This happens because --color: #7fa998 isn't added to window.document.documentElement tag on the initial load.

If this isn't the expected behavior, we can fix it in this PR.

2025-01-17.10.00.04.mp4

@ilyaliao
Copy link
Member Author

但是依旧没有解决initialValue的问题。

However, the issue of initialValue has not been resolved yet.

#4493 (comment)

對,這個 PR 主要是修復關於在 onMounted 中修改 color 狀態時未改變的問題,另一個問題如同上面我提到的,如果他不是預期行為,我們可以考慮在這個 PR 中一起修復。

Yes, this PR mainly fixes the issue where the color state doesn't change when modified in onMounted. As for the other issue, if it's not the expected behavior, we can fix it in this PR as well.

@OrbisK
Copy link
Collaborator
OrbisK commented Jan 17, 2025

If this isn't the expected behavior, we can fix it in this PR.

I dont think this is expected. maybe i am wrong :)

@ilyaliao ilyaliao marked this pull request as draft January 19, 2025 08:11
@ilyaliao ilyaliao marked this pull request as ready for review January 19, 2025 10:07
@ilyaliao ilyaliao changed the title fix(useCssVar): wrong variable status change perf(useCssVar): new Behavior Jan 19, 2025
{ immediate: true },
{ flush: 'post' },
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dont we need both (post and immediate)? And if not why? 😄

Copy link
Member Author
@ilyaliao ilyaliao Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we don't need immediate because lines 54-55 are used to clean up the prop from the previous element.

< 8000 div class="Box Box--condensed my-2">
if (old[0] && old[1])
old[0].style.removeProperty(old[1])

I think we probably don't need immediate because initially, both old[0] and old[1] will be undefined, so immediate: true is unnecessary.

The reason we need flush: 'post' is because at line 39 window.getComputedStyle(el).getPropertyValue(key)

const value = window.getComputedStyle(el).getPropertyValue(key)?.trim()

if you change the color value at the onMounded, since the color on the element hasn't really changed yet, we won't get the correct value here. Therefore, we need to wait for Vue to update before we get the state from the element.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

both old[0] and old[1] will be empty, so immediate: true is unnecessary.

what about updateCssVar() to get the initial value.

Copy link
Member Author
@ilyaliao ilyaliao Jan 20, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed this.

I believe it's also not needed because variable will always equal initialValue at the initial. It only needs to call updateCssVar when variable changes occur.

Perhaps I'm wrong.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed this.

I believe it's also not needed because variable will always equal initialValue at the initial. It only needs to call updateCssVar when variable changes occur.

Perhaps I'm wrong.

I think if we dont do this immediate we might miss that one, no?

if (el && window && key) {
const value = window.getComputedStyle(el).getPropertyValue(key)?.trim()
variable.value = value || initialValue
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I missed this.
I believe it's also not needed because variable will always equal initialValue at the initial. It only needs to call updateCssVar when variable changes occur.
Perhaps I'm wrong.

I think if we dont do this immediate we might miss that one, no?

if (el && window && key) {
const value = window.getComputedStyle(el).getPropertyValue(key)?.trim()
variable.value = value || initialValue
}

However, we have already set variable to initialValue at:

const variable = ref(initialValue)

In fact, in my testing, whether immediate is true or false doesn't affect the actual result. ofc, we can add immediate back first in case I missed something.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this should work:

  it('should have existing value', async () => {
    const vm = mount(defineComponent({
      setup() {
        const el = ref()

        const color = '--color'
        const variable = useCssVar(color, el)

        return {
          el,
          variable,
        }
      },
      template: `
        <div ref="el" style="--color: red"></div>
      `
    }))

    await nextTick()
    expect(vm.variable).toBe('red')
    expect(window.getComputedStyle(vm.el).getPropertyValue("--color")).toBe('red')
    expect(vm.el.style.getPropertyValue('--color')).toBe('red')
  })

But it does'nt. immediate does not change the test result here.

this one does remove the --color from the element.

watch(
variable,
(val) => {
const raw_prop = toValue(prop)
if (elRef.value?.style && raw_prop) {
if (val == null)
elRef.value.style.removeProperty(raw_prop)
else
elRef.value.style.setProperty(raw_prop, val)
}
},
)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh...It seems quite tricky, thank you for noticing.

I need some time to study it.

@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:M This PR changes 30-99 lines, ignoring generated files. labels Jan 22, 2025
@ilyaliao
Copy link
Member Author
ilyaliao commented Jan 22, 2025

I believe I have completed the task. I made some minor modifications, smaller than before but still resolved the issue. Additionally, I added more tests to ensure the original behavior remains intact.

Please lmk if I missed anything :)

@ilyaliao ilyaliao requested review from EvgenyWas and OrbisK January 22, 2025 12:04
Comment on lines 61 to 62
[variable, elRef],
([val]) => {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe not such a big difference, but I think we should add the new element here as well?

Suggested change
[variable, elRef],
([val]) => {
[variable, elRef],
([val, el]) => {

I can't suggest the full function because it's not considered a change. So the function should use el too. 😄 what do you think?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, no problem, I think it's great.

@dosubot dosubot bot added the lgtm This PR has been approved by a maintainer label Jan 22, 2025
@OrbisK
Copy link
Collaborator
OrbisK commented Feb 1, 2025

@ilyaliao isnt this a fix of the initial value instead of new behavior?

@ilyaliao
Copy link
Member Author
ilyaliao commented Feb 1, 2025

@ilyaliao isnt this a fix of the initial value instead of new behavior?

At first it was like this, but later I also added/modified some other features.

@antfu antfu changed the title perf(useCssVar): new Behavior fix(useCssVar): new Behavior Feb 12, 2025
@antfu antfu added this pull request to the merge queue Feb 12, 2025
Merged via the queue into vueuse:main with commit d5dd8fd Feb 12, 2025
9 checks passed
@ilyaliao ilyaliao deleted the fix/issue-4493 branch February 12, 2025 03:40
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
lgtm This PR has been approved by a maintainer size:L This PR changes 100-499 lines, ignoring generated files.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

BUG | useCssVar | initialValue is not working
5 participants
0