Phoebe.js Logo

Phoebe.js by example

Text input binding & templating <phoebe-text> Hello ${name.toUpperCase()} 😺
                Phoebe({
                    name: '',
                })
            
Conditions <phoebe-if> <phoebe-else>
🎂 ${age} 🎉
Please enter a valid cat age!
                Phoebe({
                    age: null
                })
            
Transitions
FLY LEFT / RIGHT
A B C D E
                Phoebe({
                    transitionIn: false
                })
            
Have a look at the phoebe.css file for all built-in transitions. You can define your own custom transitions as well.
Events
                Phoebe({
                    count: 0,
                })
            
Attributes catFullness=${catFullness}%
                Phoebe({
                    catFullness: 0,
                })
            
Basic loops <phoebe-for>
  1. ${catName}

                Phoebe({
                    catNames: Object.freeze(['Phoebe', 'Kitty', 'Ruby', 'Kali'])  // readonly list
                })
            
Interactive loops <phoebe-for> Cat Tasks:
                Phoebe({
                    catTasks: {
                        newTask: '',
                        addTask() {
                            this.list.push(this.newTask)
                            this.newTask = ''
                        },
                        removeTask(index) {
                            this.list.splice(index, 1)
                        },
                        moveTaskUp(index) {
                            [this.list[index], this.list[index - 1]] = [this.list[index - 1], this.list[index]]
                        },
                        moveTaskDown(index) {
                            [this.list[index], this.list[index + 1]] = [this.list[index + 1], this.list[index]]
                        },
                        list: ['sleep', 'scream for food', 'eat', 'sleep', 'repeat']
                    }
                })
            
Stable loops <phoebe-for>
  1. Try this: Open an expander in the list on the left and one in the list on the right. Then press shuffle a few times.
  2. Notice the difference: The stable list keeps track of which expanders are open, while the unstable list does not.
  3. Why this happens: The stable list assigns a unique key to each item.
  4. How it works: Existing list items are recycled on rerender. If you give each item a key, Phoebe.js can reorder them correctly.
  5. Recommendation: Use stable lists whenever possible, and ensure each item has a unique identifier so it can be correctly distinguished.
Unstable:
  • ${todo.text} Details for #${todo.id}: ${todo.text}
Stable:
  • ${todo.text} Details for #${todo.id}: ${todo.text}
                Phoebe({
                    todos: [
                        { id: 1, text: 'todo 1' },
                        { id: 2, text: 'todo 2' },
                        { id: 3, text: 'todo 3' },
                        { id: 4, text: 'todo 4' },
                        { id: 5, text: 'todo 5' },
                    ]
                })
            
Debounced events Search starts when you stop typing
                Phoebe({
                    search: {
                        text: "",
                        results: [],
                        async go() {
                            if (this.text.length > 0) {
                                const response = await fetch('https://en.wiktionary.org/w/api.php?' + new URLSearchParams({
                                    action: 'opensearch',
                                    search: this.text,
                                    limit: '5',
                                    format: 'json',
                                    origin: '*'
                                }).toString())
                                if (response.ok) {
                                    const responseData = await response.json()
                                    this.results = responseData[1].map((term, index) => ({ term, link: responseData[3][index] }))
                                }
                            } else {
                                this.results = []
                            }
                        }
                    }
                })
            
Radio and checkbox group inputs
${JSON.stringify({selectedCatName})}
${JSON.stringify({selectedCatNames})}
                Phoebe({
                    catNames: Object.freeze(['Phoebe', 'Kitty', 'Ruby', 'Kali']),  // readonly list
                    selectedCatName: null,  // radio button value
                    selectedCatNames: [],  // checkboxes values
                })
            
Element references
Hello from the dialog!
                Phoebe({
                    inputEl: undefined,
                    dialogEl: undefined,
                })
            
Multipage content <phoebe-component>

When working with multiple subpages, you often need to reuse the same code across HTML files, e.g. for a navigation menu.
With <phoebe-component>, you can avoid duplicating code by placing the shared part in a separate HTML file which gets mounted on each subpage.

Loading...

See view-source:${window.location.href.replace(/\/$/, '')}/nav-menu.html for the source of the component.

Countdown <phoebe-timer>
                Phoebe({
                    countdown: { running: false, value: 10 }
                })