elkfox / shopify-theme-framework Goto Github PK
View Code? Open in Web Editor NEWThe original framework for building native Shopify themes.
Home Page: https://concrete.elkfox.io
The original framework for building native Shopify themes.
Home Page: https://concrete.elkfox.io
Replace $colorForeground with $colorText in applicable default styles
Eg:
option {
background-color: $colorBackground;
color: $colorText;
}
and handlebars
After triggering the popup, it can be closed by clicking the wrapper. If you click on the "popup-content" div and then the wrapper, the wrapper no longer closes the popup.
Helpers should go below the grid in app.scss
so that viewport helpers always override the standard grid styling:
@import url('global/helpers.scss');
@import url('global/grid.scss');
@import url('global/grid.scss');
@import url('global/helpers.scss');
row.flex
etc
Form CSS markup is currently in two locations; forms.scss and global.scss
This should be combined into forms.scss
Wasn't sure if you guys haven't gotten to it yet but the cart line item controls don't update the cart.
I think we should consider moving to JSON-LD for the offer (and other) schema markup. It's more easy to manage updates as the standards evolve. How it is set up right now it is too easy to break the structure, and updating is overly complex.
See https://developers.google.com/search/docs/data-types/products
Thoughts and feedback very welcome ๐ค
Just noticed the bit below is missing from the en.default.json file:
It effects a couple of views (Activate Account, etc), but Order Detail in particular goes crazy.
{
"common": {
"menu": "Menu",
"tags": "Tags",
"close": "Close",
"pagination": {
"loadmore": "Load More",
"loading": "Loading...",
"previous": "<",
"next": ">"
}
},
"date_formats": {
"month_day_year": "%B %d, %Y",
"day_month_year": "%d %B, %Y",
"simple": "%d\/%m\/%y",
"simple_usa": "%m\/%d\/%y"
},
"account": {
"title": "Account",
"login": "Login",
"logout": "Logout",
"password": "Password",
"password_confirmation": "Confirm Password",
"sign_in": "Sign In",
"create_account": "Register now",
"no_account": "No account?",
"already_registered": "Already have an account?",
"forgot_password": "Forgot Password?",
"reset_password_message": "Enter a new password for {{ email }} ",
"register": "Register",
"first_name": "First Name",
"last_name": "Last Name",
"company": "Company",
"address1": "Address1",
"address2": "Address2",
"city": "City",
"country": "Country",
"province": "Province",
"zip": "Postal\/Zip Code",
"phone": "Phone",
"orders": {
"title": "Orders",
"none": "No previous orders found",
"order_number": "Order",
"date": "Date",
"status": "Status",
"payment_status": "Payment Status",
"fulfillment_status": "Fullfilment Status",
"total": "Total"
},
"address": {
"title": "Addresses",
"default": "Default Address",
"add": "Add a new address",
"update": "Update",
"edit": "Edit Address",
"set_default": "Set as default address",
"manage_addresses": "Manage Addresses",
"confirm_delete": "Are you absolutely sure you wish to delete this address?",
"count": {
"one": "Address",
"other": "Addresses"
}
},
"reset_password": {
"title": "Password Reset",
"sign_in": "Sign In",
"forgot_password": "Forgot Password?",
"create_account": "Create an Account",
"message": "Enter your email to request a password reset",
"success": "Please check your email for a link to update your password"
}
},
"form": {
"name": "Name",
"email": "Email",
"phone": "Phone",
"message": "Message",
"send": "Send",
"submit": "Submit",
"cancel": "Cancel",
"add": "Add",
"edit": "Edit",
"delete": "Delete"
},
"subscribe": {
"title": "Subscribe",
"confirmation": "Thank you for subscribing!"
},
"cart": {
"title": "Cart",
"view_cart": "View Cart",
"product": "Product",
"price": "Price",
"quantity": "Quantity",
"subtotal": "Subtotal",
"checkout": "Checkout",
"shipping_at_checkout": "Shipping calculated at checkout",
"total": "Total",
"remove_item": "Remove",
"empty": "Your cart is empty :(",
"note": "Customer Notes",
"count": {
"one": "item",
"other": "items"
}
},
"collection": {
"no_matches": "Sorry, there are no products in this collection",
"view": {
"title": "View",
"grid": "Grid",
"list": "List"
},
"items_with_count": {
"one": "{{ count }} item",
"other": "{{ count }} items"
},
"sort": {
"title": "Sort",
"featured": "Featured",
"best_selling": "Best Selling",
"az": "Alphabetically, A-Z",
"za": "Alphabetically, Z-A",
"price_ascending": "Price, low to high",
"price_descending": "Price, high to low",
"date_descending": "Date, new to old",
"date_ascending": "Date, old to new"
}
},
"product": {
"add_to_cart": "Add to Cart",
"add_to_cart_unavailable": "Unavailable",
"regular_price": "Regular Price",
"quantity": "Quantity",
"priced_from_html": "From {{ price }}",
"on_sale_html": "On sale for {{ price }}",
"on_sale_from_html": "On sale from {{ price }}",
"on_sale": "On sale",
"original_price": "Originally",
"previous_product": "Previous",
"next_product": "Next"
},
"home_page": {
"title": "Home"
},
"blog": {
"title": "Blog",
"categories": "Blog Categories",
"recent_articles": "Recent Articles",
"article": {
"title": "Home",
"published": "Published",
"author_on_date_html": "Posted by {{ author }} on {{ date }}",
"read_more": "Read More",
"previous_article": "Previous Article",
"next_article": "Next Article"
},
"comments": {
"title": "Leave a comment",
"name": "Name",
"email": "Email",
"message": "Message",
"post": "Comment",
"moderated": "Please note, comments must be approved before they are published",
"success_moderated": "Your comment was submitted. It will be published after our moderators review your post.",
"success": "Your comment was posted. Thank you!",
"meta_html": "{{ author }} on {{ date }}",
"with_count": {
"one": "{{ count }} comment",
"other": "{{ count }} comments"
}
},
"author": {
"about_with_name": "About {{ first_name }}"
}
},
"search": {
"title": "Search",
"no_results_html": "Sorry, no results for \"{{ terms }}\"",
"results_for_html": "We found these matches for \"{{ terms }}\""
},
"social": {
"facebook": "Facebook",
"fancy": "Fancy",
"google": "Google+",
"instagram": "Instagram",
"pinterest": "Pinterest",
"twitter": "Twitter",
"vimeo": "Vimeo",
"youtube": "YouTube",
"share": {
"title": "Share",
"fancy": "Fancy",
"google": "+1",
"facebook": "Share",
"pinterest": "Pin it",
"twitter": "Tweet"
}
},
"onboarding": {
"products": {
"modal_title": "This area will show your store's products",
"no_products_html": "There are no products yet, but once you begin adding them they will show up here regardless if they are in a collection.",
"add_product": "Add Product",
"product_title": "Example Product Title"
},
"collections": {
"modal_title": "This area will show your store's collections",
"no_collections_html": "You don't have any collections to show here. <a href=\"\/admin\/custom_collections\">Add some collections<\/a> to go along with the default home page.",
"add_collection": "Add a Collection",
"collection_title": "Example Collection Title",
"items_with_count": "{{ count }} Items"
}
},
"password_page": {
"opening_soon": "Opening Soon",
"password_link": "Have a password?",
"login_form_heading": "Enter with a password",
"login_form_password_label": "Password",
"login_form_password_placeholder": "Your password",
"login_form_submit": "Enter",
"signup_form_email_label": "Email",
"signup_form_success": "We will send you an email right before we open!",
"admin_link_html": "Are you the store owner? <a href=\"\/admin\" class=\"text-link\">Log in here<\/a>",
"powered_by_shopify_html": "This shop will be powered by {{ shopify }}"
},
"gift_cards": {
"title_html": "Here's your {{ value }} gift card for {{ shop }}!",
"subtext": "Your gift card",
"disabled": "Disabled",
"expired": "Expired on {{ expiry }}",
"active": "Expires on {{ expiry }}",
"redeem_html": "Use this code at checkout to redeem your {{ value }} gift card",
"shop_link": "Start shopping",
"print": "Print this gift card",
"remaining_html": "{{ balance }} of",
"add_to_apple_wallet": "Add to Apple Wallet"
},
"404": {
"title": "404 Error: Page Not Found",
"subtext_html": "Sorry, that page doesn't appear to exist! Click <a href=\"/collections/all\">here</a> to continue shopping"
},
"customer": {
"account": {
"title": "My Account",
"details": "Account Details",
"view_addresses": "View Addresses",
"return": "Return to Account Details"
},
"activate_account": {
"title": "Activate Account",
"subtext": "Create your password to activate your account.",
"password": "Password",
"password_confirm": "Confirm Password",
"submit": "Activate Account",
"cancel": "Decline Invitation"
},
"addresses": {
"title": "Your Addresses",
"default": "Default",
"add_new": "Add a New Address",
"edit_address": "Edit address",
"first_name": "First Name",
"last_name": "Last Name",
"company": "Company",
"address1": "Address1",
"address2": "Address2",
"city": "City",
"country": "Country",
"province": "Province",
"zip": "Postal/Zip Code",
"phone": "Phone",
"set_default": "Set as default address",
"add": "Add Address",
"update": "Update Address",
"cancel": "Cancel",
"edit": "Edit",
"delete": "Delete"
},
"login": {
"title": "Login",
"email": "Email",
"password": "Password",
"forgot_password": "Forgot your password?",
"sign_in": "Sign In",
"cancel": "Return to Store",
"guest_title": "Continue as a guest",
"guest_continue": "Continue"
},
"orders": {
"title": "Order History",
"order_number": "Order",
"date": "Date",
"payment_status": "Payment Status",
"fulfillment_status": "Fulfillment Status",
"total": "Total",
"none": "You haven't placed any orders yet."
},
"order": {
"title": "Order {{ name }}",
"date": "Placed on {{ date }}",
"cancelled": "Order Cancelled on {{ date }}",
"cancelled_reason": "Reason: {{ reason }}",
"billing_address": "Billing Address",
"payment_status": "Payment Status",
"shipping_address": "Shipping Address",
"fulfillment_status": "Fulfillment Status",
"discount": "Discount",
"shipping": "Shipping",
"tax": "Tax",
"product": "Product",
"sku": "SKU",
"price": "Price",
"quantity": "Quantity",
"total": "Total",
"fulfilled_at": "Fulfilled {{ date }}",
"subtotal": "Subtotal"
},
"recover_password": {
"title": "Reset your password",
"email": "Email",
"submit": "Submit",
"cancel": "Cancel",
"subtext": "We will send you an email to reset your password.",
"success": "We've sent you an email with a link to update your password."
},
"reset_password": {
"title": "Reset account password",
"subtext": "Enter a new password for {{ email }}",
"password": "Password",
"password_confirm": "Confirm Password",
"submit": "Reset Password"
},
"register": {
"title": "Create Account",
"first_name": "First Name",
"last_name": "Last Name",
"email": "Email",
"password": "Password",
"submit": "Create",
"cancel": "Return to Store"
}
}
}
Thanks for building this base framework. It's solid!
L
Concrete popups need overflow:auto
on the .popup-content
element to accomodate MS Edge's tendency to show empty scroll bars.
Update line heights on inputs to fix sketchy webkit bugs ๐
input[type="text"],
input[type="email"],
input[type="number"],
input[type="tel"],
input[type="password"],
input[type="search"],
textarea {
height: $gutter;
line-height: 100%;
&::placeholder, &::-webkit-input-placeholder, &:-moz-placeholder, &::-moz-placeholder, &:-ms-input-placeholder {
line-height: 100%;
height: $gutter;
}
}
stops the cart quantities jumping up and down
Check for featured image
check is a variant
Some stores want to show savings as a percentage.
This needs to update on variant change incase the savings percentage varies.
Using new media queries
// Hover detection
@mixin hover() {
@media (hover: hover) {
@content;
}
}
@mixin no-hover() {
@media (hover: none) {
@content;
}
}
The popup script is currently written as the one below.
So unless the form had a submission error the popup wont ever get initialized. There needs to be an else statement for the 3 popups on the page.
{% if form.errors %}
<script>
$(document).ready(function() {
var AddressPopup_{{ address.id }} = new Focus('#PopupAddress_{{ address.id }}');
AddressPopup_{{ address.id }}.show();
});
</script>
{% endif %}
{% endform %}
I'll update these myself soon ๐
The snippets blog-author
and blog-comments
do not exist in the framework and should be removed the from the article template
Struggling to find answers for some of these questions.
Currently the cart content gets overwritten by the handlebars script whenever Cartfox gets triggered. So any alteration to the cart must be done twice. Why?
What are these selectors used for?
emptyTemplate: '[data-cart-template]',
itemsContainer: '[data-item-container]'
Is there anyway to add/remove/update items in Javascript? similar to how its done in CartJS.
Ex. CartJS.addItem(1245112,1);
If I had a button like below and I use the and I change the qty value using javascript to 3. It will continue to add just 1 instead of 3. So does Cartfox only look at the attributes at the time of when the page is loaded?
<button data-quick-add="1245123" data-quick-add-qty="1">Quick Add</button>
Sorry for all the questions. I really like this framework and want to use it effectively.
For squeaky clean margins ๐
Something along the lines of:
@for $i from 1 through 10 {
$division: $gutter/5;
$spacing: $division*$i;
.margin-#{$i}x {
margin: $spacing;
}
.margin-top-#{$i}x {
margin-top: $spacing;
}
.margin-bottom-#{$i}x {
margin-bottom: $spacing;
}
.margin-left-#{$i}x {
margin-left: $spacing;
}
.margin-right-#{$i}x {
margin-right: $spacing;
}
.padding-#{$i}x {
padding: $spacing;
}
.padding-top-#{$i}x {
padding-top: $spacing;
}
.padding-bottom-#{$i}x {
padding-bottom: $spacing;
}
.padding-left-#{$i}x {
padding-left: $spacing;
}
.padding-right-#{$i}x {
padding-right: $spacing;
}
}
In snippets/collection-product.liquid, the data attribute "data-product-tags", closes itself if one of the tags contains a double quote.
I'm also really not sure what this attribute is being used for at the moment, along with data-product-id and data-product-price
With wildcard clearing
Improve the icon
snippet file to handle multiple viewboxes, dynamic sizing etc
Translations Missing for the following:
/templates/activate_account.liquid
<h1>{{ 'account.activate.title' | t }}</h1>
/snippets/popup-address.liquid
<h4>{{ 'account.address.delete' | t }}</h4>
The toggled nav needs a simple toggle function out of the box in order to hide/show secondary menus. Currently, secondary menus are permanently hidden.
theme-nav-toggled.liquid:
<a href="{{ link.url }}" data-trigger="toggle" data-target="#{{ child_list_handle }}" class="nav-link {% if link.active %} active{% endif %}">
{{ link.title }}
</a>
<ul class="dropdown_menu hidden" id="{{ child_list_handle }}">
// Linklist here
</ul>
navigation.js
concrete.Navigation = (function() {
$('[data-trigger="toggle"]').on('click', function(event) {
event.preventDefault();
var target = $(this).data('target');
$(target).toggle();
});
});
We can also remove the child_list_handle
IDs from the theme-nav-main.liquid
link elements as they are not needed and might interfere with this function's selectors.
With input fields, we have to wrestle with the user agent styling of text and number inputs.
Optimise search layout for different result types & clean up default layout
select
elements some out-of-the-box stylingThe theme settings have reverted to an old version. We'll need to manually clean them up for the new methods.
Cartfox needs to be updated to the latest in the dist, including empty cart state etc
We currently have duplicated settings for logos. This needs a cleanup, as does the way we define meta images like opengraph, favicon and itemprop sources.
It looks like "favorites_pinned_svg" isn't defined yet either.
I think this should take the form of settings for both a bitmap and svg image to be applied dynamically per use.
The product template is currently calling 'template-product' which doesn't exist in the dist files but does in the src files!
Also add missing account.activate
string group #36
snippets/form-recover-password.liquid
and templates/customers/login.recover.liquid
are missing from the rebuild.
Currently the download button on the docs site needs updating to point to the latest release.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.