Skip to content

Conversation

hhaensel
Copy link
Member

@hhaensel hhaensel commented May 8, 2025

With this PR all methods, watchers, computed properties and lifecyclehooks are transferred from mixins to the incorporating app. Prefixes and postfixes are applied to variables when they are prefixed by this in the functions. Method names are also prefixed when they are defined as Symbols or Strings; they are left untouched when they are defined as JSONText.

Example: HistoryTab - A tab somponent with history navigation

using Stipple, Stipple.ReactiveTools, StippleUI

Stipple.enable_model_storage(false)

@app_mixin HistoryTab begin
    @in var"" = "home"
    @in _navigate = ""

    @onchange isready begin
        isready || return
        notify(var"")
    end
    
    @onchange _navigate begin
        if _navigate != ""
            var""[!] = _navigate
            @push :var""
        end
    end

    @onchange var"" begin
        @info "$(:var"") changed to '$(var"")'"
        # empty _navigate to make sure, it is executed the next time a non-empty value is set
        _navigate = ""
        @run """
        this['_index_'] = this['_index_'] + 1 || 0;
        state = {field: '$(:var"")', value: '$(var"")', index: this['_index_']}
        console.log('push state: ', state)
        history.pushState(state, '', '#' + this['_index_']);
        """
    end
end

@mounted HistoryTab js"""
    window.addEventListener('popstate',
        (event) => {
            if (event.state && event.state.field) {
                console.log('new state: ', event.state)
                if (this[event.state.field] == event.state.value) {
                    old_index = this['_index_'];
                    this['_index_'] = event.state.index;
                    if ((old_index >= event.state.index) && (event.state.index > 0)) {
                        history.back();
                    } else {
                        history.forward();
                    }
                } else {
                    this[event.state.field + '_navigate'] = event.state.value
                    this['_index_'] = event.state.index
                }
            }
        }
    );
    """

@methods HistoryTab [
    :_hello => js"""
    function () {
        console.log('The current tab is: \'' + this. + '\'')
        console.log('The tab\'s variable name is: \'' + 'this. '.slice(5, -1) + '\'')
        console.log('Last navigation was to: \'' + this._navigate + '\'')
    }
    """,
    js"hello_everyone" => js"""
    function () {
        console.log('Tab-independent greeting!')
    }
    """
]

@app_mixin MyApp begin
    @in i = 1
    @mixin tab1::HistoryTab
    @mixin tab2::HistoryTab

    @onchange i begin
       println("i: ", i)
    end
end

@mounted MyApp [
    js"""
    console.log('isready: ', this.isready)
    """
]

function ui()
    row(class = "st-module", cell(class = "q-pa-md q-ma-md", [
        tabgroup(:tab1, [
            tab(label = "Home", name = "home"),
            tab(label = "About", name = "about"),
            tab(label = "Contact", name = "contact")
        ])

        tabgroup(:tab2, [
            tab(label = "Home", name = "home"),
            tab(label = "About", name = "about"),
            tab(label = "Contact", name = "contact")
        ])
    ]))
end

@page("/", ui, model = MyApp)

up(open_browser = true)

@hhaensel
Copy link
Member Author

hhaensel commented May 9, 2025

StippleUI needs a small correction in Tables.jl
but that's only a fix for js_watch and js_created for backward compatibility with Quasar 1.
Only event support is still missing.
I guess the way to add them is analogous to the definition of handlers.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant