Last active
October 15, 2019 00:34
-
-
Save will-wow/0e54b3bcbed02114f9e1104f3bb2de92 to your computer and use it in GitHub Desktop.
Svelte Contacts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import React, { useState } from "react" | |
const CountDown = () => { | |
const [count, setCount] = useState(0) | |
const remaining = 10 - count | |
const increment = () => { | |
if (remaining > 0) { | |
setCount(count + 1) | |
} | |
} | |
return ( | |
<div> | |
<div>Count: {count}</div> | |
<div>Remaining: {remaining}</div> | |
<button onClick={increment}>Click</button> | |
</div> | |
) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
let count = 0 | |
$: remaining = 10 - count | |
const increment = () => { | |
if (remaining > 0) { | |
count++ | |
} | |
} | |
</script> | |
<div> | |
<div>Count: {count}</div> | |
<div>Remaining: {remaining}</div> | |
<button on:click={increment}>Click</button> | |
</div> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
git clone https://github.com/will-wow/contacts.git --branch rails |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rails new contacts --database=postgresql --webpack | |
rake db:create | |
rails g scaffold Contact name:string email:string twitter:string phone:string | |
rake db:migrate |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
rake webpacker:install:svelte |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem 'webpacker', git: "https://github.com/rails/webpacker.git" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/contacts/index.html.erb --> | |
<% @contacts.each do |contact| %> | |
<tr> | |
<td><%= contact.name %></td> | |
<td><%= contact.email %></td> | |
<td><%= contact.twitter %></td> | |
<td><%= contact.phone %></td> | |
<td><%= link_to 'Show', contact, class: "btn btn-info" %></td> | |
<td> | |
<%= link_to 'Edit', edit_contact_path(contact), class: "btn btn-primary" %> | |
</td> | |
<td> | |
<%= link_to 'Destroy', contact, method: :delete, class: "btn btn-danger", | |
data: { confirm: 'Are you sure?' } %> | |
</td> | |
</tr> | |
<% end %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/javascript/src/components/ContactRow.svelte --> | |
<script> | |
export let contact | |
export let onSave | |
export let onDelete | |
const handleDelete = () => { | |
if (confirm("Are you sure?")) { | |
onDelete() | |
} | |
} | |
</script> | |
<tr> | |
<td> | |
<input | |
class="form-control" | |
type="text" | |
name="name" | |
bind:value={contact.name} | |
/> | |
</td> | |
<td> | |
<input class="form-control" name="email" bind:value={contact.email} /> | |
</td> | |
<td> | |
<input class="form-control" name="twitter" bind:value={contact.twitter} /> | |
</td> | |
<td> | |
<input class="form-control" name="phone" bind:value={contact.phone} /> | |
</td> | |
<td> | |
<a class="btn btn-info btn-xs" href="/contacts/{contact.id}>Show</a> | |
</td> | |
<td> | |
<button class="btn btn-primary btn-xs" on:click={handleSave}> | |
Save | |
</button> | |
</td> | |
<td> | |
<button class="btn btn-danger btn-xs" on:click={handleDelete}> | |
Destroy | |
</button> | |
</td> | |
</tr> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/javascript/src/components/ContactList.svelte --> | |
<script> | |
import Api from "./api" | |
import ContactRow from "./ContactRow.svelte" | |
export const saveContact = contact => | |
Api.put(`/contacts/${contact.id}.json`, { contact }) | |
const deleteContact = (contact) => { | |
Api.delete(`/contacts/${contact.id}.json`) | |
contacts = contacts.filter(({ id }) => id !== contact.id) | |
} | |
export let contacts | |
</script> | |
{#each contacts as contact} | |
<!-- bind to update the store from the ContactRow --> | |
<ContactRow | |
bind:contact | |
onSave={() => saveContact(contact)} | |
onDelete={() => deleteContact(contact)} /> | |
{/each} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
gem 'webpacker-svelte' |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
npm i webpacker-svelte --save-dev | |
# or | |
yarn add webpacker-svelte --dev |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def svelte_component(component_name, props = {}, options = {}) | |
tag = options.delete(:tag) || :div | |
data = { data: { "svelte-component" => component_name, "svelte-props" => props.to_json } } | |
content_tag(tag, nil, options.deep_merge(data)) | |
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/packs/application.js | |
import WebpackerSvelte from "webpacker-svelte" | |
import ContactList from "../src/ContactList.svelte" | |
WebpackerSvelte.setup({ ContactList }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/contacts/index.html.erb --> | |
<table class="table"> | |
<thead> | |
<tr> | |
<th>Name</th> | |
<th>Email</th> | |
<th>Twitter</th> | |
<th>Phone</th> | |
<th colspan="3"></th> | |
</tr> | |
</thead> | |
<%= svelte_component("ContactList", {contacts: @contacts}, tag: "tbody") %> | |
</table> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/src/contact-store.js | |
import { writable, derived } from "svelte/store" | |
import Api from "./api" | |
// Declare the writable store. | |
export const contactStore = writable([]) | |
export const saveContact = contact => | |
Api.put(`/contacts/${contact.id}.json`, { contact }) | |
export const deleteContact = contact => { | |
// Filter the deleted contact from the store. | |
contactStore.update(contacts => | |
contacts.filter(({ id }) => id !== contact.id) | |
) | |
return Api.delete(`/contacts/${contact.id}.json`) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/javascript/src/components/ContactList.svelte --> | |
<script> | |
import { onMount } from "svelte" | |
import { contactStore, saveContact, deleteContact } from "../contact-store" | |
import ContactRow from "./ContactRow.svelte" | |
export let contacts | |
// Initialize the store from props when the component mounts. | |
onMount(() => { | |
contactStore.set(contacts) | |
}) | |
</script> | |
<!-- Loop over the store instead of the contacts prop --> | |
{#each $contactStore as contact} | |
<ContactRow | |
bind:contact | |
onSave={() => saveContact(contact)} | |
onDelete={() => deleteContact(contact)} /> | |
{/each} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/src/contact-store.js | |
import { writable, derived } from "svelte/store" | |
import Api from './api' | |
export const contactStore = writable([]) | |
... | |
export const createContact = async contact => { | |
const { data: createdContact } = await Api.post("/contacts.json", { | |
contact | |
}) | |
// Add the new contact to the store once it's created on the server. | |
contactStore.update(contacts => [...contacts, createdContact]) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/javascript/src/components/ContactCount.svelte --> | |
<script> | |
import { contactStore } from "../contact-store" | |
export let count = null | |
// Reactive declaration that calculates the count from props or the store. | |
$: contactCount = count === null ? $contactStore.length : count | |
</script> | |
<span class="badge badge-pill badge-info">Total: {contactCount}</span> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// app/javascript/src/application.js | |
import ContactCount from "../src/ContactCount" | |
WebpackerSvelte.setup({ ContactList, NewContactButton, ContactCount }) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/contacts/index.html.erb --> | |
<%= svelte_component("ContactCount") %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- app/views/contacts/edit.html.erb --> | |
<%= svelte_component("ContactCount", count: @contact_count) %> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// contact-store.js | |
export const contactStore = writable([]) | |
export const contactCountStore = derived( | |
contactStore, | |
contacts => contacts.length | |
) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- ContactCount.svelte --> | |
<script> | |
import { contactCountStore } from "../contact-store" | |
export let count = null | |
$: contactCount = count === null ? $contactCountStore : count | |
</script> | |
<span class="badge badge-pill badge-info">Total: {contactCount}</span> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment